Skip to main content
These open source example apps demonstrate integrating the Halliday API directly into an app to enable fiat onramping, cross-chain swaps, payment retries, and processing address withdrawals. For more rapid integrations that use the Halliday JS SDK widget with a whitelabel user interface see Payments SDK Example Apps.

Plain JavaScript API Examples

The following open source example app code demonstrates how to implement fiat onramps and cross-chain swaps using the Halliday API. There are also API examples shown to handle withdrawals and retries for payments that have failed to complete.

Fiat onramps via API using JavaScript

This example app shows how to build a fiat-to-crypto onramp, with a custom user interface, using the Halliday API.
In the example, a user would be able to onramp directly to MEGA on MegaETH with a provider like Stripe. The app allows a user to connect their MegaETH wallet and the amount of USD they wish to spend. Using JavaScript, the app fetches a collection of quotes from the API and displays the best price available with each provider, as well as the total amount of onramp fees.
Once the user selects a quote and destination address in the user interface, clicking or tapping the Continue button confirms the quote with the API.
If the payment output is >= $300 USD and the owner address has not been verified, the confirm response will include a USER_VERIFY next instruction. The user must sign the verification payloads before proceeding. A while loop handles up to two verification round-trips (owner verification followed by withdrawal simulation for large payments).
Next, the payment provider’s checkout page is shown to the user. This is where the user would input their credit or debit card information for the transaction.
Once the checkout is completed, the payment workflow begins. The app polls the payment status endpoint and shows the current status of the payment in the user interface.
This example does not show an implementation of a recovery flow if the payment fails midway onchain. In the event a payment does not complete, a user can recover it by connecting the owner wallet on this page: https://app.halliday.xyz/funding/${payment_id}.

Cross-chain swaps via API using JavaScript

This example app shows how to build a cross-chain swap app, with a custom user interface, using the Halliday API.
In the example, a user would be able to swap from USDC on Base to MEGA on MegaETH using the Halliday API and their own wallet. The app allows a user to connect their wallet and input the amount of USDC on Base that they wish to spend. Using JavaScript, the app fetches a collection of quotes from the API and displays the best price available and the total amount of fees.
Once the user approves the quote, it is confirmed using the API.
If the payment output is >= $300 USD and the owner address has not been verified, the confirm response will include a USER_VERIFY next instruction. The user must sign the verification payloads before proceeding. A while loop handles up to two verification round-trips (owner verification followed by withdrawal simulation for large payments).
Next, the user can sign transactions with their wallet to fund the workflow.
The latest status of the cross-chain swap is fetched from the API and displayed in the UI.
The next section shows how to implement payment recoveries directly via API. Alternatively, payments can be recovered on the following page by connecting the payment’s owner address wallet https://app.halliday.xyz/funding/${payment_id}.

Withdraw stuck assets with the API using JavaScript

In the event that a payment begins its onchain steps and fails to complete them, or assets are sent to a processing address in which the payment is expired, a user can sign a transaction to withdraw the tokens to any address. The owner address, which is usually the user’s wallet, is the sole controller of assets in the processing addresses. An overview and details on the withdrawal process are explained on the API Recoveries & Errors page.
The app uses the history API endpoint to fetch payments for the wallet address.
Here is example code to get the entire history of payments created using the API.
Next, after filtering out properly completed payments, the balance of failed or expired payments is queried using the API one by one. This endpoint will get the current token balances for all of the payment’s processing addresses on the relevant chains and return the data in the response.
Relevant payment information is rendered in the UI for the user. The user can tap or click buttons to initialize the withdrawal flow for each individual stuck token balance. Initializing the withdrawal flow has three steps:
  1. Get the EIP-712 data from the API (getTypedData) which is used to sign a transaction to withdraw the token from the processing address.
  2. The transaction is signed (signTypedData) with the user wallet using Ethers on the client.
  3. The signed transaction data is then sent to the API (confirmWithdrawal) to confirm the withdrawal and execute it onchain. The API returns the onchain transaction hash in the response body.
Lastly, the transaction with the final transfer of tokens to the withdrawal address is rendered as a blockchain explorer link for the user to tap or click.

Retry incomplete payments with the API using JavaScript

In the event an onramp or swap is funded but fails to complete, a retry can be attempted using assets lingering in a processing address. A retry requires a new quote which uses the lingering assets as the input token amount. Think of retries as a withdrawal of an old payment to deposit into a new payment. The owner address is the sole controller of assets in the processing addresses. The user wallet must sign a transaction to initialize the retry. Payment retries are further explained on the API Recoveries & Errors page.
The retry example uses the same history API endpoint to fetch payments for the wallet address as the above withdraw example (see getWalletPaymentHistory above). Also the same endpoint to fetch current processing address balances is used (see getProcessingAddressBalances above). Using the balances response, a quote is made for bridging and swapping with the processing address balance as the input. This is the same quotes endpoint used in onramps and swaps. See the getQuote function in the cross-chain swaps example above.
Once the user accepts a quote available to retry the payment, the following four steps orchestrate a retry:
  1. Use the API endpoint to accept the new quote (see acceptQuote). This is the same endpoint used to accept quotes in onramps and swaps.
  2. Fetch the withdrawal signature data from the API (see getTypedData). This transaction will transfer tokens from the old payment to the new payment once it is executed onchain. This is the same gas-sponsored transaction concept explained in the above withdraw example.
  3. The transaction is signed (signTypedData) with the user wallet using Ethers on the client.
  4. The signed transaction data is then sent to the API (confirmWithdrawal) to confirm the token transfer from the old payment to the new payment. The API then executes this transaction onchain covering all of the blockchain gas costs.
The new payment ID can subsequently be tracked. The new payment will reach the COMPLETE state once the output tokens have reached the destination address.

React API Examples

The following open source example app demonstrates building onramps, cross-chain swaps, payment retries, and processing address withdrawals using the Halliday API directly by connecting a user’s EIP-1193 wallet like MetaMask or Rabby.

React API Examples with Dynamic Embedded Wallets

The following open source example app demonstrates building onramps, cross-chain swaps, payment retries, and processing address withdrawals using the Halliday API directly with a Dynamic embedded wallet.

React API Examples with Privy Wallet

The following open source example app demonstrates building onramps, cross-chain swaps, payment retries, and processing address withdrawals using the Halliday API directly with a Privy connected wallet.