Skip to main content
The following open source example app code demonstrates how to implement fiat onramps and cross-chain swaps using the Halliday API.

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 Payments API.
In the example, a user would be able to onramp directly to IP on Story mainnet with a provider like Stripe, Transak, or Moonpay. The app allows a user to input their Story mainnet address 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.
// From getQuote function

const res = await fetch('https://v2.prod.halliday.xyz/payments/quotes', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer ' + HALLIDAY_API_KEY,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    request: {
      kind: 'FIXED_INPUT',
      fixed_input_amount: {
        asset: inputAsset,
        amount: inputAmount,
      },
      output_asset: outputAsset,
    },
    price_currency: 'usd',
    onramps,
    onramp_methods: fiatOnrampPayInMethods,
    customer_geolocation: { alpha3_country_code: 'USA' }
  }),
});
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.
// From acceptQuote function

const res = await fetch('https://v2.prod.halliday.xyz/payments/confirm', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer ' + HALLIDAY_API_KEY,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    payment_id: selectedQuote.paymentId,
    state_token: selectedQuote.stateToken,
    owner_address: destinationAddress,
    destination_address: destinationAddress
  })
});
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.
// From onContinueButtonClick function

const acceptedQuote = await acceptQuote();
const paymentId = acceptedQuote.payment_id;
const onrampUrl = acceptedQuote.next_instruction.funding_page_url;

paymentStatusInterval = setInterval(async () => {
  console.log('payment status:', paymentId, await getPaymentStatus(paymentId));
}, 5000);

continueButton.classList.remove('loading');

onrampIframe.src = onrampUrl;
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.
// From getPaymentStatus function

const res = await fetch(`https://v2.prod.halliday.xyz/payments?payment_id=${paymentId}`, {
  method: 'GET',
  headers: {
    'Authorization': 'Bearer ' + HALLIDAY_API_KEY,
    'Content-Type': 'application/json'
  },
});
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 Payments API.
In the example, a user would be able to swap from USDC on Base to IP on Story mainnet using the Halliday Payments 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.
// From getQuote function

const res = await fetch('https://v2.prod.halliday.xyz/payments/quotes', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer ' + HALLIDAY_API_KEY,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    request: {
      kind: 'FIXED_INPUT',
      fixed_input_amount: {
        asset: inputAsset,
        amount: inputAmount
      },
      output_asset: outputAsset
    },
    price_currency: 'USD'
  })
});
Once the user approves the quote, it is confirmed using the API.
const requestBody = {
  payment_id: quote.paymentId,
  state_token: quote.stateToken,
  owner_address: userAddress,
  destination_address: userAddress
};

const res = await fetch('https://v2.prod.halliday.xyz/payments/confirm', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer ' + HALLIDAY_API_KEY,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(requestBody)
});
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.
const res = await fetch('https://v2.prod.halliday.xyz/payments' +
  `?payment_id=${paymentId}`, {
  method: 'GET',
  headers: {
    'Authorization': 'Bearer ' + HALLIDAY_API_KEY,
    'Content-Type': 'application/json'
  }
});
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}.