+
+
+```typescript
+// src/db/index.ts
+import Database from 'better-sqlite3';
+import { drizzle } from 'drizzle-orm/better-sqlite3';
+import * as schema from './schema';
+
+const sqlite = new Database('database.sqlite');
+export const db = drizzle(sqlite, { schema });
+```
+
+```typescript
+// src/db/schema.ts
+import { sqliteTable, text, integer } from 'drizzle-orm/sqlite-core';
+
+export const payments = sqliteTable('payments', {
+ id: integer('id').primaryKey({ autoIncrement: true }),
+ requestId: text('request_id').notNull(),
+ status: text('status').notNull(),
+});
+
+export type Payment = typeof payments.$inferSelect;
+```
+
+```typescript
+// src/index.ts
+import 'dotenv/config';
+import Fastify, { FastifyRequest, FastifyReply } from 'fastify';
+
+const fastify = Fastify({
+ logger: true
+});
+
+fastify.get('/', async (request: FastifyRequest, reply: FastifyReply) => {
+ return { message: 'Hello World!' };
+});
+
+const start = async () => {
+ try {
+ const port = 3000;
+ const host = 'localhost';
+
+ await fastify.register(require('@fastify/cors'), {
+ origin: true, // change to your frontend URL in production
+ methods: ['GET', 'POST', 'PATCH'],
+ });
+ await fastify.listen({ port, host });
+ console.log(`Server listening on http://${host}:${port}`);
+ } catch (err) {
+ fastify.log.error(err);
+ process.exit(1);
+ }
+};
+
+start();
+
+```
+
+```typescript
+// drizzle-config.ts
+import { defineConfig } from 'drizzle-kit';
+
+export default defineConfig({
+ schema: './src/db/schema.ts',
+ out: './drizzle',
+ dialect: 'sqlite',
+ dbCredentials: {
+ url: './database.sqlite',
+ },
+});
+```
+
+```json
+// tsconfig.json
+{
+ "compilerOptions": {
+ "target": "ES2020",
+ "module": "commonjs",
+ "lib": ["ES2020"],
+ "outDir": "./dist",
+ "rootDir": "./src",
+ "strict": true,
+ "esModuleInterop": true,
+ "skipLibCheck": true,
+ "forceConsistentCasingInFileNames": true,
+ "resolveJsonModule": true,
+ "declaration": true,
+ "declarationMap": true,
+ "sourceMap": true
+ },
+ "include": ["src/**/*"],
+ "exclude": ["node_modules", "dist"]
+}
+
+```
+
+Then run `npm install` and when that's done, run `npm run db:push`.
+
+### Get your API key
+
+Before starting your integration, you need to sign up on our API portal, which you can access via this [link](https://portal.request.network/).
+
+On our API portal dashboard, you can easily create an API key.
+
+
+
+
+
+
+
+
+
+
+
+
+
+Now copy over its value to your `.env` file
+
+```
+// .env
+RN_API_KEY=
+
+
+### Setting up webhooks
+
+In order for your app to make use of our payment tracking easily and in real-time, we provide webhook support. You just provide the endpoint and the Request Network API does the rest.
+
+Let's create a new route for handling webhook calls.
+
+```typescript
+// Add this to src/index.ts
+import crypto from "node:crypto";
+
+fastify.post('/webhooks', async (request: FastifyRequest, reply: FastifyReply) => {
+ let webhookData: Record
+
+
+Next up, go back to the [API portal](https://portal.request.network) and add a new webhook. In the case above it's the URL from ngrok with the `/webhooks` appendix (https://34c701d1d7f9.ngrok-free.app/webhooks).
+
+
+
+
+
+
+
+
+
+Next thing, copy over the signing secret and add it to your `.env` file, then restart the app.
+
+```
+// .env
+RN_API_KEY=
+
+
+Next up, let's scaffold our app. Create a folder called `components`, and then create two files `CreatePayment.tsx` and `ViewPayments.tsx`.
+
+```tsx
+// src/components/create-payment/index.tsx
+import React from 'react';
+
+const CreatePayment: React.FC = () => {
+ return (
+ This will be a form to create new payments
+This will show all payments from the database
+
+
+
+### Connecting the user's wallet
+
+We'll be using [wagmi](https://wagmi.sh/) to enable wallet connection. To do that we need to do a few things:
+
+1. Install `wagmi` and its dependencies `npm install wagmi viem @tanstack/react-query --save`
+2. Create a wagmi config at `src/config/wagmi.ts`
+
+```typescript
+// src/config/wagmi.ts
+import { createConfig, http } from 'wagmi'
+import { sepolia } from 'wagmi/chains'
+import { injected } from 'wagmi/connectors'
+
+export const config = createConfig({
+ chains: [sepolia],
+ connectors: [
+ injected(),
+ ],
+ transports: {
+ [sepolia.id]: http(),
+ },
+})
+```
+
+3. Update `main.tsx` to include the new providers
+
+```tsx
+// src/main.tsx
+import React from 'react'
+import ReactDOM from 'react-dom/client'
+import { WagmiProvider } from 'wagmi'
+import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
+import { config } from './config/wagmi'
+import App from './App.tsx'
+import './index.css'
+
+const queryClient = new QueryClient()
+
+ReactDOM.createRoot(document.getElementById('root')!).render(
+
+
+
+
+
+
+
+### Viewing payments
+
+Since we have created a few payments via `cURL` before, we can implement viewing of payments first. Let's create a `.env` file and add the following to it:
+
+```
+// .env
+VITE_API_URL=http://localhost:3000
+```
+
+Next up, let's modify the `ViewPayments` component.
+
+```tsx
+// src/components/view-payments/index.tsx
+import React, { useState, useEffect } from 'react';
+import './styles.css';
+
+interface Payment {
+ id: number;
+ requestId: string;
+ status: string;
+}
+
+const ViewPayments: React.FC = () => {
+ const [payments, setPayments] = useState
+
+
+### Creating payments
+
+Let's update our `CreatePayment` component. It's going to do the following:
+
+1. The user inputs payment information - the payee address, amount, invoice currency and payment currency
+2. After submitting the form, we create a payment on the API, receive the response and use the `transactions` property to execute the payment with our connected wallet.
+3. Immediately after that succeeds, we update the payment status on the backend to `in-progress`
+
+```tsx
+// src/components/create-payment/index.tsx
+import React, { useState } from 'react';
+import { useSendTransaction, useAccount } from 'wagmi';
+import './styles.css';
+
+interface PaymentForm {
+ payee: string;
+ amount: string;
+ invoiceCurrency: string;
+ paymentCurrency: string;
+}
+
+const CreatePayment: React.FC = () => {
+ const [formData, setFormData] = useState
+
+
+### Trying everything out
+
+We recommend using two different Metamask accounts you own. That way you will be able to confirm that the funds were moved on your very own.
+
+*NOTE*: For this demo, we recommend inputting your second account for the `Payee address` value and use the same invoice and payment currencies.
+
+1. Let's create a payment from the client, moving 0.02 Sepolia ETH to our second account
+
+
+
+
+
+2. Create the payment and sign the transaction
+
+
+
+
+
+
+
+
+
+3. Navigate to the `View payments tab` , verify that the last payment is `In progress` and let's wait for the transaction to go through. You can patiently watch your server's logs to check when the webhook is called.
+
+
+
+
+
+4. In a few moments the payment's status should be set to `Confirmed` .
+
+
+
+
+
+This is it, you have succesfully built a basic application integrating our API to move actual test funds between two wallets.
+
+**Happy building** 🎉
diff --git a/docs.json b/docs.json
index b8caa16..cbf0380 100644
--- a/docs.json
+++ b/docs.json
@@ -63,6 +63,7 @@
"group": "🔑 API Setup",
"pages": [
"api-setup/getting-started",
+ "api-setup/integration-tutorial",
"request-network-api/api-portal-manage-api-keys-and-webhooks",
"api-setup/migrate-to-v2"
]
diff --git a/images/api-setup/integration-tutorial/api-portal-step-1.webp b/images/api-setup/integration-tutorial/api-portal-step-1.webp
new file mode 100644
index 0000000..12ec3d3
Binary files /dev/null and b/images/api-setup/integration-tutorial/api-portal-step-1.webp differ
diff --git a/images/api-setup/integration-tutorial/api-portal-step-2.webp b/images/api-setup/integration-tutorial/api-portal-step-2.webp
new file mode 100644
index 0000000..1687573
Binary files /dev/null and b/images/api-setup/integration-tutorial/api-portal-step-2.webp differ
diff --git a/images/api-setup/integration-tutorial/api-portal-step-3.webp b/images/api-setup/integration-tutorial/api-portal-step-3.webp
new file mode 100644
index 0000000..d5d712b
Binary files /dev/null and b/images/api-setup/integration-tutorial/api-portal-step-3.webp differ
diff --git a/images/api-setup/integration-tutorial/create-payment-form.webp b/images/api-setup/integration-tutorial/create-payment-form.webp
new file mode 100644
index 0000000..bdf224f
Binary files /dev/null and b/images/api-setup/integration-tutorial/create-payment-form.webp differ
diff --git a/images/api-setup/integration-tutorial/create-payment-step-1.webp b/images/api-setup/integration-tutorial/create-payment-step-1.webp
new file mode 100644
index 0000000..6492da0
Binary files /dev/null and b/images/api-setup/integration-tutorial/create-payment-step-1.webp differ
diff --git a/images/api-setup/integration-tutorial/database-studio.webp b/images/api-setup/integration-tutorial/database-studio.webp
new file mode 100644
index 0000000..32cfead
Binary files /dev/null and b/images/api-setup/integration-tutorial/database-studio.webp differ
diff --git a/images/api-setup/integration-tutorial/folder-structure.webp b/images/api-setup/integration-tutorial/folder-structure.webp
new file mode 100644
index 0000000..dd7713d
Binary files /dev/null and b/images/api-setup/integration-tutorial/folder-structure.webp differ
diff --git a/images/api-setup/integration-tutorial/initial-ui.webp b/images/api-setup/integration-tutorial/initial-ui.webp
new file mode 100644
index 0000000..7d21192
Binary files /dev/null and b/images/api-setup/integration-tutorial/initial-ui.webp differ
diff --git a/images/api-setup/integration-tutorial/ngrok-terminal.webp b/images/api-setup/integration-tutorial/ngrok-terminal.webp
new file mode 100644
index 0000000..cb1a401
Binary files /dev/null and b/images/api-setup/integration-tutorial/ngrok-terminal.webp differ
diff --git a/images/api-setup/integration-tutorial/payment-confirmed.webp b/images/api-setup/integration-tutorial/payment-confirmed.webp
new file mode 100644
index 0000000..13185c8
Binary files /dev/null and b/images/api-setup/integration-tutorial/payment-confirmed.webp differ
diff --git a/images/api-setup/integration-tutorial/payment-in-progress.webp b/images/api-setup/integration-tutorial/payment-in-progress.webp
new file mode 100644
index 0000000..b7872de
Binary files /dev/null and b/images/api-setup/integration-tutorial/payment-in-progress.webp differ
diff --git a/images/api-setup/integration-tutorial/sign-transaction-1.webp b/images/api-setup/integration-tutorial/sign-transaction-1.webp
new file mode 100644
index 0000000..d3909de
Binary files /dev/null and b/images/api-setup/integration-tutorial/sign-transaction-1.webp differ
diff --git a/images/api-setup/integration-tutorial/sign-transaction-2.webp b/images/api-setup/integration-tutorial/sign-transaction-2.webp
new file mode 100644
index 0000000..1df390f
Binary files /dev/null and b/images/api-setup/integration-tutorial/sign-transaction-2.webp differ
diff --git a/images/api-setup/integration-tutorial/view-payments.webp b/images/api-setup/integration-tutorial/view-payments.webp
new file mode 100644
index 0000000..276a4da
Binary files /dev/null and b/images/api-setup/integration-tutorial/view-payments.webp differ
diff --git a/images/api-setup/integration-tutorial/vite-setup.webp b/images/api-setup/integration-tutorial/vite-setup.webp
new file mode 100644
index 0000000..b90a750
Binary files /dev/null and b/images/api-setup/integration-tutorial/vite-setup.webp differ
diff --git a/images/api-setup/integration-tutorial/wallet-conencted.webp b/images/api-setup/integration-tutorial/wallet-conencted.webp
new file mode 100644
index 0000000..0e52b6b
Binary files /dev/null and b/images/api-setup/integration-tutorial/wallet-conencted.webp differ
diff --git a/images/api-setup/integration-tutorial/wallet-disconnected.webp b/images/api-setup/integration-tutorial/wallet-disconnected.webp
new file mode 100644
index 0000000..1e02975
Binary files /dev/null and b/images/api-setup/integration-tutorial/wallet-disconnected.webp differ
diff --git a/images/api-setup/integration-tutorial/webhook-step-1.webp b/images/api-setup/integration-tutorial/webhook-step-1.webp
new file mode 100644
index 0000000..fa43ac1
Binary files /dev/null and b/images/api-setup/integration-tutorial/webhook-step-1.webp differ
diff --git a/images/api-setup/integration-tutorial/webhook-step-2.webp b/images/api-setup/integration-tutorial/webhook-step-2.webp
new file mode 100644
index 0000000..b59c95b
Binary files /dev/null and b/images/api-setup/integration-tutorial/webhook-step-2.webp differ