Request Network Docs
WebsiteGithubStatusDiscord
  • Request Network Docs
  • Request Network API
    • Create and Pay Requests
    • Crosschain Payments
    • EasyInvoice: API Demo App
    • API Portal: Manage API Keys and Webhooks
      • Manage API Keys and Webhooks programmatically
    • Full API Reference
  • General
    • Lifecycle of a Request
    • Request Scan
    • Supported Chains
      • Smart Contract Addresses
    • Request Network Token List
  • Advanced
    • Request Network SDK
      • Get Started
        • Quickstart - Browser
        • Quickstart - Node.js
        • Installation
        • SDK Injector
        • Request Node Gateways
      • SDK Demo Apps
        • Request Invoicing
          • Pay from Safe Multisig
        • Request Checkout
        • Components
          • Create Invoice Form
          • Invoice Dashboard
          • Payment Widget
          • Add Stakeholder
      • SDK Guides
        • Request Client
          • Configure the Request Client
          • Updating a Request
          • Payment Reference
          • Compute a Request ID without creating the request
          • Use your own signature mechanism
          • Support a new currency
          • In-Memory Requests
        • Encryption and Decryption
          • Encrypt with a wallet signature using Lit Protocol
          • Encrypt with an Ethereum private key
          • Share an encrypted request
        • Payment
          • Detect a payment
          • Native Payment
          • Conversion Payment
          • Declarative Payment
          • Configuring Payment Fees
          • Single Request Forwarder
          • Batch Payment
          • Swap-to-Pay Payment
          • Swap-to-Conversion Payment
          • Transferable Receivable Payment
          • Meta Payments
          • Escrow Payment
          • Streaming Payment
          • Pay through a proxy-contract with a multisig
          • Hinkal Private Payments
        • Mobile using Expo
      • SDK Reference
        • request-client.js
          • RequestNetwork
            • createRequest()
            • computeRequestId()
            • fromRequestId()
            • fromIdentity()
            • fromTopic()
          • Request
            • waitForConfirmation()
            • getData()
            • refresh()
            • cancel()
            • accept()
            • increaseExpectedAmountRequest()
            • reduceExpectedAmountRequest()
          • IIdentity
          • IRequestDataWithEvents
          • PaymentReferenceCalculator
        • payment-processor
          • payRequest()
        • web3-signature
          • Web3SignatureProvider
        • epk-signature
          • EthereumPrivateKeySignatureProvider
        • epk-decryption
          • EthereumPrivateKeyDecryptionProvider
    • Protocol Overview
      • SDK and Request Node Overview
      • Payment Networks
      • Private Requests using Encryption
      • Smart Contracts Overview
    • Internal SDK Architecture
      • Request Logic
      • Advanced Logic
      • Transaction
      • Data-access
      • Storage
      • Data flow
      • Request IPFS network
  • FAQ
  • Glossary
  • Contributing
Powered by GitBook
On this page
  • Installation
  • Usage
  • Usage in React and Next.js
  • Props
  • Next Steps

Was this helpful?

Edit on GitHub
Export as PDF
  1. Advanced
  2. Request Network SDK
  3. SDK Demo Apps
  4. Components

Create Invoice Form

A form for creating invoices in Request Network

PreviousComponentsNextInvoice Dashboard

Last updated 6 months ago

Was this helpful?

Installation

To install the component, use npm:

npm install @requestnetwork/create-invoice-form

Usage

Usage in React and Next.js

Configure the Create Invoice Form web component by creating a reference to it, setting its properties, and passing the reference as a prop.

Initialize the RequestNetwork object using an Ethers Signer or Viem WalletClient.

Use the config object to pass additional configuration options. Please replace the builderId with your own, arbitrarily chosen ID. This is used to track how many invoices your application creates.

Use a context provider to reinitialize the Request Network instance when the wallet changes.

A list of custom currencies to extend the default currency list.

Specify types to avoid TypeScript errors.

Props

Prop
Type
Description

config

IConfig

Additional configuration parameters

config.builderId

string

Unique builder ID, arbitrarily chosen, used for metrics

config.dashboardLink

string

Path to dashboard page

config.logo

string

Path to logo file

config.colors.main

string

Hex color code for primary buttons and labels

config.colors.secondary

string

Hex color code for for borders and accents

requestNetwork

The RequestNetwork instance

wagmiConfig

WagmiConfig

Wallet connector config

currencies

Currency[]

A list of custom currencies

Next Steps

The Create Invoice Form allows end-users to create an invoice using the Request Network. It is built using but compiled to a , making it usable in any web environment, regardless of the framework.

Follow the instructions below to add the Create Invoice Form to a React or Next.js app. For a video explaining how to integrate, see the

The web component supports any wallet connector module built on top of . This provides the flexibility to use any wagmi-compatible wallet connector, such as .

Svelte
Web Component
create-invoice.tsx
wagmiConfig.ts
wagmi
RainbowKit
initializeRN.ts
config.ts
context.tsx
currencies.ts
types.d.ts
Quickstart - Browser
RequestNetwork

Try it out

Demo Video

Integration Video

View on NPM

View Source

🕹️
▶️
🏗️
📦
ℹ️
#request-invoicing-integration-video
Screenshot of @requestnetwork/create-invoice-form 0.2.0
https://github.com/RequestNetwork/invoicing-template/blob/01e44755b274d17c0718ca03f077d68a9fe8baec/utils/context.tsx
import React, {
  createContext,
  useContext,
  useState,
  ReactNode,
  useEffect,
} from "react";
import { initializeRequestNetwork } from "./initializeRN";
import type { RequestNetwork } from "@requestnetwork/request-client.js";
import { useAccount, useWalletClient } from "wagmi";

interface ContextType {
  requestNetwork: RequestNetwork | null;
}

const Context = createContext<ContextType | undefined>(undefined);

export const Provider = ({ children }: { children: ReactNode }) => {
  const { data: walletClient } = useWalletClient();
  const { address, isConnected, chainId } = useAccount();
  const [requestNetwork, setRequestNetwork] = useState<RequestNetwork | null>(
    null
  );

  useEffect(() => {
    if (walletClient && isConnected && address && chainId) {
      initializeRequestNetwork(setRequestNetwork, walletClient);
    }
  }, [walletClient, chainId, address, isConnected]);

  return (
    <Context.Provider
      value={{
        requestNetwork,
      }}
    >
      {children}
    </Context.Provider>
  );
};

export const useAppContext = () => {
  const context = useContext(Context);
  if (!context) {
    throw new Error("useAppContext must be used within a Context Provider");
  }
  return context;
};
https://github.com/RequestNetwork/invoicing-template/blob/01e44755b274d17c0718ca03f077d68a9fe8baec/pages/create-invoice.tsx
import Head from "next/head";
import dynamic from "next/dynamic";
import { config } from "@/utils/config";
import { useAppContext } from "@/utils/context";
import { currencies } from "@/utils/currencies";
import { rainbowKitConfig as wagmiConfig } from "@/utils/wagmiConfig";
import { Spinner } from "@/components/ui";

const CreateInvoiceForm = dynamic(
  () => import("@requestnetwork/create-invoice-form/react"),
  { ssr: false, loading: () => <Spinner /> }
);

export default function CreateInvoice() {
  const { requestNetwork } = useAppContext();

  return (
    <>
      <Head>
        <title>Request Invoicing - Create an Invoice</title>
      </Head>
      <div className="container m-auto  w-[100%]">
        <CreateInvoiceForm
          config={config}
          currencies={currencies}
          wagmiConfig={wagmiConfig}
          requestNetwork={requestNetwork}
        />
      </div>
    </>
  );
}
https://github.com/RequestNetwork/invoicing-template/blob/01e44755b274d17c0718ca03f077d68a9fe8baec/utils/config.ts
import { IConfig } from "./types";

export const config: IConfig = {
  builderId: "request-network", // Replace with your builder ID, arbitrarily chosen, used to identify your app
  dashboardLink: "/",
  logo: "/assets/logo-sm.svg",
  colors: {
    main: "#0BB489",
    secondary: "#58E1A5",
  },
};
https://github.com/RequestNetwork/invoicing-template/blob/01e44755b274d17c0718ca03f077d68a9fe8baec/utils/wagmiConfig.ts
import {
  bsc,
  celo,
  base,
  fuse,
  zksync,
  fantom,
  coreDao,
  polygon,
  mainnet,
  sepolia,
  arbitrum,
  moonbeam,
  optimism,
  avalanche,
  gnosis,
} from "wagmi/chains";
import { http } from "wagmi";
import {
  coinbaseWallet,
  injectedWallet,
  ledgerWallet,
  metaMaskWallet,
  safeWallet,
  trustWallet,
  walletConnectWallet,
} from "@rainbow-me/rainbowkit/wallets";
import { getDefaultConfig } from "@rainbow-me/rainbowkit";

export const rainbowKitConfig = getDefaultConfig({
  appName: "Request Invoicing",
  projectId: process.env.NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID as string,
  chains: [
    bsc,
    celo,
    base,
    fuse,
    zksync,
    gnosis,
    fantom,
    coreDao,
    polygon,
    mainnet,
    sepolia,
    arbitrum,
    moonbeam,
    optimism,
    avalanche,
  ],
  transports: {
    [arbitrum.id]: http(
      process.env.NEXT_PUBLIC_RPC_URL_ARBITRUM_ONE ||
        "https://arbitrum.llamarpc.com"
    ),
    [avalanche.id]: http(
      process.env.NEXT_PUBLIC_RPC_URL_AVALANCHE || "https://avalanche.drpc.org"
    ),
    [base.id]: http(
      process.env.NEXT_PUBLIC_RPC_URL_BASE || "https://base.llamarpc.com"
    ),
    [bsc.id]: http(
      process.env.NEXT_PUBLIC_RPC_URL_BSC || "https://bsc.llamarpc.com"
    ),
    [celo.id]: http(
      process.env.NEXT_PUBLIC_RPC_URL_CELO || "https://forno.celo.org"
    ),
    [coreDao.id]: http(
      process.env.NEXT_PUBLIC_RPC_URL_CORE || "https://rpc.coredao.org"
    ),
    [fantom.id]: http(
      process.env.NEXT_PUBLIC_RPC_URL_FANTOM ||
        "https://endpoints.omniatech.io/v1/fantom/mainnet/public"
    ),
    [fuse.id]: http(
      process.env.NEXT_PUBLIC_RPC_URL_FUSE || "https://fuse.drpc.org"
    ),
    [mainnet.id]: http(
      process.env.NEXT_PUBLIC_RPC_URL_ETHEREUM || "https://eth.llamarpc.com"
    ),
    [polygon.id]: http(
      process.env.NEXT_PUBLIC_RPC_URL_POLYGON || "https://1rpc.io/matic"
    ),
    [moonbeam.id]: http(
      process.env.NEXT_PUBLIC_RPC_URL_MOONBEAM ||
        "https://moonbeam-rpc.publicnode.com"
    ),
    [optimism.id]: http(
      process.env.NEXT_PUBLIC_RPC_URL_OPTIMISM ||
        "https://optimism.llamarpc.com"
    ),
    [sepolia.id]: http(
      process.env.NEXT_PUBLIC_RPC_URL_SEPOLIA || "https://sepolia.drpc.org"
    ),
    [gnosis.id]: http(
      process.env.NEXT_PUBLIC_RPC_URL_XDAI || "https://gnosis.drpc.org"
    ),
    [zksync.id]: http(
      process.env.NEXT_PUBLIC_RPC_URL_ZKSYNCERA ||
        "https://mainnet.era.zksync.io"
    ),
  },
  wallets: [
    {
      groupName: "Recommended",
      wallets: [injectedWallet, metaMaskWallet, walletConnectWallet],
    },
    {
      groupName: "Others",
      wallets: [safeWallet, coinbaseWallet, ledgerWallet, trustWallet],
    },
  ],
  ssr: true,
});
https://github.com/RequestNetwork/invoicing-template/blob/01e44755b274d17c0718ca03f077d68a9fe8baec/utils/currencies.ts
import { Types } from "@requestnetwork/request-client.js";

export const currencies = [
  {
    symbol: "FAU",
    address: "0x370DE27fdb7D1Ff1e1BaA7D11c5820a324Cf623C",
    network: "sepolia",
    decimals: 18,
    type: Types.RequestLogic.CURRENCY.ERC20,
  },
  {
    symbol: "ETH",
    address: "eth",
    network: "sepolia",
    decimals: 18,
    type: Types.RequestLogic.CURRENCY.ETH,
  },
];
https://github.com/RequestNetwork/invoicing-template/blob/01e44755b274d17c0718ca03f077d68a9fe8baec/utils/initializeRN.ts
import { RequestNetwork } from "@requestnetwork/request-client.js";
import { Web3SignatureProvider } from "@requestnetwork/web3-signature";
import { getTheGraphClient } from "@requestnetwork/payment-detection";

export const initializeRequestNetwork = (setter: any, walletClient: any) => {
  try {
    const web3SignatureProvider = new Web3SignatureProvider(walletClient);

    const requestNetwork = new RequestNetwork({
      nodeConnectionConfig: {
        baseURL: "https://gnosis.gateway.request.network/",
      },
      signatureProvider: web3SignatureProvider,
      httpConfig: {
        getConfirmationMaxRetry: 120,
      },
      paymentOptions: {
        getSubgraphClient: (chain: string) => {
          // Ternary because cannot dynamically access environment variables in the browser
          const paymentsSubgraphUrl =
          chain === "arbitrum-one"
            ? process.env.NEXT_PUBLIC_PAYMENTS_SUBGRAPH_URL_ARBITRUM_ONE || "https://subgraph.satsuma-prod.com/e2e4905ab7c8/request-network--434873/request-payments-arbitrum-one/api"
            : chain === "avalanche"
            ? process.env.NEXT_PUBLIC_PAYMENTS_SUBGRAPH_URL_AVALANCHE || "https://subgraph.satsuma-prod.com/e2e4905ab7c8/request-network--434873/request-payments-avalanche/api"
            : chain === "base"
            ? process.env.NEXT_PUBLIC_PAYMENTS_SUBGRAPH_URL_BASE || "https://subgraph.satsuma-prod.com/e2e4905ab7c8/request-network--434873/request-payments-base/api"
            : chain === "bsc"
            ? process.env.NEXT_PUBLIC_PAYMENTS_SUBGRAPH_URL_BSC || "https://subgraph.satsuma-prod.com/e2e4905ab7c8/request-network--434873/request-payments-bsc/api"
            : chain === "celo"
            ? process.env.NEXT_PUBLIC_PAYMENTS_SUBGRAPH_URL_CELO || "https://api.studio.thegraph.com/query/67444/request-payments-celo/version/latest"
            : chain === "core"
            ? process.env.NEXT_PUBLIC_PAYMENTS_SUBGRAPH_URL_CORE || "https://thegraph.coredao.org/subgraphs/name/requestnetwork/request-payments-core"
            : chain === "fantom"
            ? process.env.NEXT_PUBLIC_PAYMENTS_SUBGRAPH_URL_FANTOM || "https://subgraph.satsuma-prod.com/e2e4905ab7c8/request-network--434873/request-payments-fantom/api"
            : chain === "fuse"
            ? process.env.NEXT_PUBLIC_PAYMENTS_SUBGRAPH_URL_FUSE || "https://api.studio.thegraph.com/query/67444/request-payments-fuse/version/latest"
            : chain === "mainnet"
            ? process.env.NEXT_PUBLIC_PAYMENTS_SUBGRAPH_URL_MAINNET || "https://subgraph.satsuma-prod.com/e2e4905ab7c8/request-network--434873/request-payments-mainnet/api"
            : chain === "matic"
            ? process.env.NEXT_PUBLIC_PAYMENTS_SUBGRAPH_URL_MATIC || "https://subgraph.satsuma-prod.com/e2e4905ab7c8/request-network--434873/request-payments-matic/api"
            : chain === "moonbeam"
            ? process.env.NEXT_PUBLIC_PAYMENTS_SUBGRAPH_URL_MOONBEAM || "https://api.studio.thegraph.com/query/67444/request-payments-moonbeam/version/latest"
            : chain === "optimism"
            ? process.env.NEXT_PUBLIC_PAYMENTS_SUBGRAPH_URL_OPTIMISM || "https://subgraph.satsuma-prod.com/e2e4905ab7c8/request-network--434873/request-payments-optimism/api"
            : chain === "sepolia"
            ? process.env.NEXT_PUBLIC_PAYMENTS_SUBGRAPH_URL_SEPOLIA || "https://subgraph.satsuma-prod.com/e2e4905ab7c8/request-network--434873/request-payments-sepolia/api"
            : chain === "xdai"
            ? process.env.NEXT_PUBLIC_PAYMENTS_SUBGRAPH_URL_XDAI || "https://api.studio.thegraph.com/query/67444/request-payments-xdai/version/latest"
            : chain === "zksyncera"
            ? process.env.NEXT_PUBLIC_PAYMENTS_SUBGRAPH_URL_ZKSYNCERA || "https://subgraph.satsuma-prod.com/e2e4905ab7c8/request-network--434873/request-payments-zksyncera/api"
            : undefined;
          if (!paymentsSubgraphUrl) {
            throw new Error(
              `Cannot get subgraph client for unknown chain: ${chain}`
            );
          }
          return getTheGraphClient(chain, paymentsSubgraphUrl);
        },
      },
    });

    setter(requestNetwork);
  } catch (error) {
    console.error("Failed to initialize the Request Network:", error);
    setter(null);
  }
};
https://github.com/RequestNetwork/invoicing-template/blob/01e44755b274d17c0718ca03f077d68a9fe8baec/types.d.ts
import { IConfig } from "@/utils/types";
import { Config as WagmiConfig } from "wagmi";
import type { RequestNetwork } from "@requestnetwork/request-client.js";

declare global {
  namespace JSX {
    interface IntrinsicElements {
      "invoice-dashboard": InvoiceDashboardElement;
      "create-invoice-form": CreateInvoiceFormElement;
    }
  }
}

interface InvoiceDashboardElement {
  ref?: React.Ref<InvoiceDashboardProps>;
}

interface CreateInvoiceFormElement {
  ref?: React.Ref<CreateInvoiceFormProps>;
}

interface InvoiceDashboardProps extends HTMLElement {
  config: IConfig;
  wagmiConfig: WagmiConfig;
  requestNetwork: RequestNetwork;
  currencies: any;
}

interface CreateInvoiceFormProps extends HTMLElement {
  config: IConfig;
  wagmiConfig: WagmiConfig;
  requestNetwork: RequestNetwork;
  currencies: any;
}