# Overview

### What is LlamaPay?

LlamaPay is a multi-chain payments protocol for automating outgoing payments and receiving payments. LlamaPay provides the following services:

* Payment streaming for salaries: Automate transactions and stream them by the second. The recipients can withdraw these funds at any time. This eliminates the need for manual transactions.
* Payments gateway: Receive crypto payments and charge recurring subscriptions, with optional cost reductions for users thanks to aave yield.
* Scheduled payments: Set a payment to be sent at a specific date and llamapay will automate it. Payment can be cancelled at any time until it's sent.
* Vesting contracts: Token vesting contracts with cliffs forked from Yearn Finance.
* Automated token payments denominated in USD: Pay recurring USD-denominated payments in another currency, such ETH, UNI or your own token.


# Why use LlamaPay?

### Reasons

* Cheapest payments gas-wise across all payment gateways
* Fully non-custodial
* Built-in swapping so you can accept payments in any token on all major chains, and everything will automatically get swapped for stablecoins
* Recurring subscriptions that earn yield

### Comparison with Coinbase Commerce

| Feature                                      | LlamaPay                                      | Coinbase                               |
| -------------------------------------------- | --------------------------------------------- | -------------------------------------- |
| Fees on direct payments                      | 0-0.5%                                        | 1%                                     |
| Chains supported                             | 8                                             | 3                                      |
| Subscriptions                                | [✅](https://emojipedia.org/check-mark-button) | [❌](https://emojipedia.org/cross-mark) |
| Gas cost of first USDT payment               | 57,294                                        | 343,594                                |
| Signatures/txs needed for first USDT payment | 1                                             | 3                                      |
| Gnosis Safe support                          | [✅](https://emojipedia.org/check-mark-button) | [❌](https://emojipedia.org/cross-mark) |
| Permissions system for team delegation       | [✅](https://emojipedia.org/check-mark-button) | [❌](https://emojipedia.org/cross-mark) |


# How are gas fees so cheap?

The main issue a payments gateway has to solve is how to connect a transfer with a payment request, so if an app requests a 100$ payment from multiple users and later there's a 100$ transfer, how do you know which user did the payment?

### Previous solutions

The most common solution that payment gateways use is they create a new address for each payment, so if money ends up at that address then you know for sure which user sent it. However this means that the payment gateway needs to later send that money again to aggregate all payments, which costs extra transaction fees, and it also needs to take custody of funds, which exposes it to hacks.

Another solution is to do the transfer through a contract where a unique id is attached to the transaction, allowing identification of which payment this transaction is paying. The issue with this is that adding a contract to the transaction increases gas costs and number of transactions needed, as first you need to approve the token against the contract.

### Our solution

Before making a payment, users send a request to our server claiming the payment, such as "I will pay payment ABCDE from address 0x123", then when a transaction comes from address 0x123 we know that it must be paying ABCDE.

But what happens if two different users claim the same address for different payments? In that case we add 0.000001$ to the second payment such that it's possible to perfectly differentiate between the two potential transactions. However this should almost never happen, as it should only happen in the case where an attacker predicts a future transfer perfectly and tries to grief the user.

Because the transaction is just a simple transfer, it achieves the minimum gas cost possible and, because all wallets have logic for parsing transfers, it's very easy for all users to verify exactly what the transaction is doing and check it's not malicious, which improves UX compared to systems where you have to approve other contracts, interact with them and sign messages.

In the worse case scenario where there's a huge DDoS attack which could increase transaction amount significantly, then we fall back to transacting through a contract, so it's impossible for users to pay more than 0.005$ extra.

## Subscriptions

#### Constant costs

Gas costs for retrieving subscription payments in our contracts are independent of the number of payers. This is important because other systems rely on pulling tokens from payers' wallets directly or on a contract that needs to perform actions for each payer, thus the gas costs grow linearly with the number of payers.

Because of that, gas costs can end ballooning significantly when you reach hundreds or thousands of players, while adding unpredictable liabilities because you don't know how much those gas fees will cost you in the future. Our system keeps costs constant so as you grow costs will always remain cheap.

#### Yield buffer

On top of that, our contracts have a yield buffer that significantly reduces costs when users deposit money, making costs costs equivalent to those you'd get if there was no yield farming involved at all.

LlamaPay subscriptions generate yield by depositing funds on AAVE, but doing so can increase 2-3x the gas costs of deposit transactions. To avoid that, users deposit only to our contract, and once enough deposits have accumulated, we have a bot that triggers a deposit to AAVE, amortizing costs.

To illustrate, imagine the contract has 1m deposited on aave and there are users depositing money for 5$/mo subscriptions for a year (so 60$ per user). Instead of depositing into aave on each transaction, we would wait till there are 2.1k$ on the contract and then trigger a deposit for everyone, thus lowering the total gas costs by 35x (there's only 1 aave deposit instead of 35, one for each transaction).

This introduces economies of scale since it's shared among all the companies that use llamapay, and it also improves security because if there was some bug around aave deposits an attacker wouldn't be able to trigger it at will within their attack transaction.


# Why use LlamaPay instead of paying and sending an etherscan link?

Subscriptions require our contracts, but for simple one-off stablecoin payments you might wonder why use LlamaPay instead of posting an address and having your clients send money there and send you the etherscan link aftewards, since that's free and easy to implement.

LlamaPay improves upon these simple payments significantly in attribution, automation and convenience, with no downsides since costs stay exactly the same!

### Attribution

Imagine you run a telegram bot that requires payment for access, and a user pays and sends you the etherscan link of the transaction.

How do you know if the user who sent you that link is the one who actually sent the transaction? Someone else could have seen that transaction and sent it to you. And how do you link that payment with a telegram username to give access to?

If the payment is done through LlamaPay you'll be able to tell exactly who sent that payment and get their telegram handle directly (or any other internal user representation you use), because you'll know which payment link that payment came from, removing any possible attribution conflict. User info is either provided directly through our API before payment or by users before the payment if you're using static payment links, making it impossible to tamper with and falsely claim a payment.

### Automation

Having to manually process payments:

* takes away your time and focus from what really matters, running your business
* leads to a very slow experience for your users, who have to wait for hours/days for the payment to complete
* easily leads to mistakes such as forgetting to cancel a service when payment is over

LlamaPay completely automates handling of payments so you don't have to bother with it and provisioning for your users is instant.

### Convenience

Our payment links streamline the process of paying, guiding the user to the chains where you wish to accept payment and automatically showing them their options based on their wallet, preventing duplicated payments and user errors from pasting addresses around. All while providing a more professional experience for them.

For you, we provide analytics on all your payments and make them easy to consume through our API.

### Downsides

Stablecoin transfers have 0% fees on LlamaPay, and they're implemented using transfer() calls, which is the same that users would use when sending payments directly to your wallet, so the gas cost for users is exactly the same.

### Conclusion

By using LlamaPay you get to automate work away, completely remove attribution conflicts, reduce user errors and massively improve customer UX by reducing payment settling from hours/days to minutes, all this at the exact same cost as crudely sending payments directly, both for you and your users.


# Integration

## No code

1. Create a company by clicking **Get Started** on <https://checkout.llamapay.io/>
2. Create a payment link
3. Add the payment link to your site or send it to customers directly

## Code

{% hint style="info" %}
Have you integrated Coinbase Commerce already? Our API is fully backwards compatible with it, so you can switch to LlamaPay by simply replacing endpoint urls, api key, and webhook secret. It's a drop-in replacement!
{% endhint %}

1. Create a company by clicking **Get Started** on <https://checkout.llamapay.io/>
2. [Set up a server with a webhook endpoint](/payments-gateway/integration/set-up-webhooks) to get notified when the payment is paid.
3. Go to the Developer tab in LlamaPay UI, set your webhook URL and copy your API Key and webhook secret.
4. To [create a new payment](/payments-gateway/integration/create-a-new-payment), make a <mark style="color:green;">`POST`</mark> request to`https://api.llamapay.io/charges`, then take `hosted_url` from the response and send it to your users to pay.

Here's a basic express server that implements the system above:

```javascript
const { createHmac } = require("crypto");
const express = require('express')
const app = express()
app.use(express.raw({ type: '*/*', limit: '10mb' }));

const PORT = 3000
const LLAMAPAY_API_KEY = "llamapay_sk_YOUR_API_KEY"
const LLAMAPAY_WEBHOOK_SECRET = "llamapay_webhook_secret_XXXX"

app.post('/webhook', (req, res) => {
  const hmac = createHmac('sha256', LLAMAPAY_WEBHOOK_SECRET)
    .update(req.body).digest('hex');
  if(req.headers['x-cc-webhook-signature'] !== hmac){
    return res.sendStatus(401)
  }
  const body = JSON.parse(req.body);
  if(body.type === "charge:pending"){
    console.log("User paid:", body.data.metadata)
  }
  res.sendStatus(200)
})

app.post('/new-payment/:userHandle', async (req, res) => {
  const payment = await fetch("https://api.llamapay.io/charges", {
    method: "POST",
    headers:{
        Authorization: LLAMAPAY_API_KEY
    },
    body: JSON.stringify({
        "pricing_type": "fixed_price",
        "local_price": {
            "amount": "1.00",
            "currency": "USD"
        },
        "metadata": {
            "userHandle": req.params.userHandle
        }
    })
  }).then(r=>r.json())
  res.send(payment.data.hosted_url)
})

app.listen(PORT, () => {
  console.log(`Listening on port ${PORT}`)
})
```


# Create a new payment

<mark style="color:green;">`POST`</mark> `https://api.llamapay.io/charges`

#### **Headers**

| Name          | Value                      |
| ------------- | -------------------------- |
| Authorization | `llamapay_sk_YOUR_API_KEY` |

#### **Body parameters**

<table><thead><tr><th width="154">Key</th><th>Value</th><th>Example</th></tr></thead><tbody><tr><td>pricing_type</td><td>Can be either:<br>- <code>fixed_price</code> for simple one-time payments<br>- <code>no_price</code> for payments where user picks amount, eg donations<br>- <code>subscription</code> for recurring subscriptions</td><td>"fixed_price"</td></tr><tr><td>local_price</td><td>Amount to charge user.<br>If <code>pricing_type</code> is <code>subscription</code>, this is the monthly cost</td><td>{<br>  "amount": "10.00",<br>  "currency": "USD"<br>}</td></tr><tr><td>metadata</td><td><strong>[Optional]</strong> Arbitrary JSON object, it will be returned on webhooks for the payment.<br>Object must be smaller than 20kB</td><td>{ "userId": "0xngmi" }</td></tr><tr><td>redirect_url</td><td><strong>[Optional]</strong> URL to redirect user to after successful payment.</td><td>"https://mypage.com/success"</td></tr><tr><td>cancel_url</td><td><strong>[Optional]</strong> URL to redirect user to if they cancel the payment</td><td>"https://mypage.com/failure"</td></tr></tbody></table>

#### **Example body**

Charge the user a one-time payment of 10$:

```json
{
	"pricing_type": "fixed_price",
	"local_price": {
		"amount": "10.00",
		"currency": "USD"
	},
	"metadata": {
		"userId": "0xngmi"
	}
}
```

#### **Response**

```json
{
  "data": {
    ...
    "hosted_url": "https://checkout.llamapay.io/pay/fd533947-6889-4970-8fb9-6441342dc07d",
    ...
  }
}
```


# Set up webhooks

Whenever there's a new event about one of the payments you've generated, we'll send an HTTP POST request to a URL you provide, you can use this to take actions such as delivering a service when a payment has been made or cut access to a user when a subscription expires.

To receive these webhook notifications, you need to set up a webserver with https and a POST endpoint, then submit the URL of that endpoint in the Developer tab of LlamaPay dashboard.

The event received from the webhook will look like this:

```javascript
{
  event: {
    api_version: '2018-03-22', // Constant, identifies the format
    created_at: '2024-06-23T06:47:30.020Z', // Time when event was created
    data: {
      id: 'fd533947-6889-4970-8fb9-6441342dc07d', // Payment id
      pricing: { // Pricing provided when payment was created
        "local":{
          "amount":"10.0",
          "currency":"USD"
        }
      },
      metadata: { // Metadata provided when payment was created
        "userId": "0xngmi"
      },
      created_at: '2024-06-22T14:48:34.076Z', // Time when payment was created
      hosted_url: 'https://checkout.llamapay.io/pay/fd533947-6889-4970-8fb9-6441342dc07d', // URL where users can pay
      pricing_type: 'fixed_price', // Type of payment, provided at payment creation
    },
    id: 'e1e4ff60-9fcb-4a9f-b0df-fb5b0139cf2d', // id of event, will be the same on all retries so you can use it to avoid processing same event twice
    type: 'charge:pending' // Type of event
  },
}
```

The possible event types are:

<table><thead><tr><th width="203">Type</th><th>Explanation</th></tr></thead><tbody><tr><td>charge:pending</td><td>Payment transaction has been included on chain</td></tr><tr><td>charge:confirmed</td><td>Payment transaction has been finalized on chain, this happens some time after the transaction has been included on chain and we sent the charge:pending event</td></tr><tr><td>subscription:expired</td><td>A subscription has expired because it reached it's end and there was not enough money to keep it going</td></tr></tbody></table>

### Pending vs Confirmed

As soon as a transaction has landed on-chain we send a `charge:pending` event. However, if there is a chain reorg it's possible for that transaction to be excluded from the chain, so after enough time has passed that a reorg is impossible or very unlikely we send a `charge:confirmed` event confirming that the payment has been finalized.

This is the same that you would typically see when depositing into a CEX, as soon as the transaction is onchain you can see it, but it takes some confirmations till the money is available.

We recommend applying the effects of the payment as soon as you receive a charge:pending event. This will improve UX for your users and once a charge:pending event has been sent the user can't revert the payment anymore since it's on chain. The only way for such a payment to revert would be a chain reorg along with the user sending a replacement transaction.

### Security

Attackers could figure out your endpoint and send fake requests, so you should authenticate all webhook requests by crafting a HMAC from the body of the request and the shared secret you can obtain from the Developer tab on the dashboard and comparing that against the value we send in the `X-CC-WEBHOOK-SIGNATURE` header.

Here's how to do it in javascript:

```javascript
const { createHmac } = require("crypto");

function verifyWebhook(request){
  const hmac = createHmac('sha256', "LLAMAPAY_WEBHOOK_SECRET")
    .update(request.body).digest('hex');
  if(request.headers['X-CC-WEBHOOK-SIGNATURE'] !== hmac){
    throw new Error("Invalid webhook signature")
  }
}
```

### Retries

In case the request can't reach your server or your server returns an HTTP code other than 200, we'll keep retrying the same request for 3 days with an exponential backoff delay that maxes out at 1 hour.

In other words, if your server is off or for some reason it returns an error, we'll retry the same request after 10 seconds, then if that fails again, we'll retry after 20 seconds, 40 seconds, 80 seconds... for 3 days or until we get an HTTP 200 response to this request.


# API Reference

### Authentication

All calls must be authenticated with the header `Authorization: llamapay_sk_YOUR_API_KEY`.\
You can obtain the required API Key in the Developer tab on [LlamaPay's interface](https://checkout.llamapay.io/).

{% openapi src="/files/gKndNCnizEZc61uXFYJO" path="/charges" method="post" %}
[api-reference.yaml](https://1064095018-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2CMHHZLnhZkCj1dVKJLj%2Fuploads%2F3GaohI5v4gaB9TyGT3rV%2Fapi-reference.yaml?alt=media\&token=dc36d22b-bddd-491b-a5d0-9d3b9f5de784)
{% endopenapi %}

{% openapi src="/files/gKndNCnizEZc61uXFYJO" path="/charges" method="get" %}
[api-reference.yaml](https://1064095018-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2CMHHZLnhZkCj1dVKJLj%2Fuploads%2F3GaohI5v4gaB9TyGT3rV%2Fapi-reference.yaml?alt=media\&token=dc36d22b-bddd-491b-a5d0-9d3b9f5de784)
{% endopenapi %}

{% openapi src="/files/gKndNCnizEZc61uXFYJO" path="/charges/{payment\_id}" method="get" %}
[api-reference.yaml](https://1064095018-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F2CMHHZLnhZkCj1dVKJLj%2Fuploads%2F3GaohI5v4gaB9TyGT3rV%2Fapi-reference.yaml?alt=media\&token=dc36d22b-bddd-491b-a5d0-9d3b9f5de784)
{% endopenapi %}


# Subscriptions Yield

Money that's sitting in our contracts waiting to pay a subscription is deposited into AAVE, where it earns interest, this interest then effectively reduces the cost of the subscription, potentially making it free if deposit is big enough.

Let's say a user wants to pay a 5$/mo subscription and deposits 600$ into llamapay, this money will earn 5% currently on AAVE, so a total of 30$ yearly. After a year, user will have paid a total of 5\*12 = 60$ for the subscription, but because he has earned 30$, the total cost is only 30$, thus effectively his subscription is only 2.5$/mo.

If that same user had deposited 1.2k$ instead, then yearly yield would be 60$ and thus after a year he would have lost 60$ and earned 60$, thus staying flat. In this case the subscription will be completely free, because at any moment he can withdraw and get back all the money he put in,

All this while the receiver always receives the full subscription amount, so receiver can be getting paid 5$/mo while payer only loses 2.5$/mo or even nothing.

This is how LlamaPay enables free subscriptions, and even if users doesn't deposit enough money to fully offset costs they still benefit from this feature because their subscription costs will still be partially reduced.


# Pricing

LlamaPay for outgoing payments, which includes salaries, vesting and scheduled transfers, is completely free with no fees at all, and will remain free forever. These contracts are not upgradeable and don't even have an owner/admin, so they will always remain free and that can't be changed.

For LlamaPay's payment gateway, the fees are the following:

* For subscriptions: 1% of total amount paid by users. This fee is only charged when a payment is made, if a user just deposits no fee is paid.
* For direct payments: 0 fees on stablecoin payments and a 0.5% fee on payments from other tokens where a swap is needed.


# Features

* [x] Fast UI
* [x] Gas efficient
* [x] Multi-chain
* [x] Works with all tokens
* [x] Top up all streams in one operation
* [x] Deposit and withdraw in one operation
* [x] No need to deposit all the money at the start of the stream
* [x] Works with debt
* [x] Trigger withdrawals for someone else
* [x] Open source and verified contracts
* [x] No big precision errors


# Multi-chain

After our public release, LlamaPay will be available on all EVM chains and all the contracts will share the same address across chains.


# Deposits

### Problem

Sablier requires you to pick a duration for each stream and deposit all the money needed for the stream at the start. This doesn't work for salaries as the length is indeterminate.

This system requires you to keep making new streams as the old ones die and you have to provide and lock up a large amount of capital if you choose a long duration.

### Solution

We create streams of indefinite duration and tokens can just be siphoned out of a pool. This makes it possible for streams to be topped up in a single transaction and you just need to provide money that's needed to maintain these streams.


# Withdrawals

### Withdrawals that anyone can trigger

LlamaPay allows anyone to trigger withdrawals if a payee decides to use an address that belongs to a centralized exchange (CEX) or uses a wallet that cannot make Ethereum calls.&#x20;

They can just set a CEX address and have someone else trigger withdrawals or trigger themselves using another wallet.

Payers can also trigger withdrawals for their payees by using the withdraw all button.


# Debt

### Problem

One of the issues encountered with current stream payment platforms happens when you forget to top up your balance and run out.&#x20;

With SuperFluid, their bot sends a transaction that will cancel your streams and takes a part of your money (no refunds).&#x20;

To get your stream working again you would have to:

* Create all streams from scratch again
* Calculated the money recipients lost while the streams are down and send them manually
* Accept your losses

This defeats the point of automatic payments and increases your workload instead of reducing it.

### Solution

LlamaPay solves this issue by introducing the debt feature.&#x20;

When your balance gets depleted, instead of losing money and having to go through the work of restarting the streams, you incur debt. The next time you deposit, the debt is paid and streams keep working as usual. If the payer really meant to stop the streams, they can just not deposit and the payee will be able to withdraw the money they received up to when the payer's balance was depleted. They can also cancel individual streams which will remove their debt.

Once the payer deposits, the money cannot be removed and can only be withdrawn to the payee's wallet.

LlamaPay gives the option to the payer to just resume streams and repay debt easily, greatly simplifying the process in case they forgot or couldn't top up in time.


# Gas

#### Deploying a LlamaPay stream is 3.2-3.7x cheaper than the competition

<table><thead><tr><th width="150">Protocol</th><th width="225">Cost in Gwei</th><th data-hidden></th><th data-hidden></th><th data-hidden></th></tr></thead><tbody><tr><td>LlamaPay</td><td>69,963</td><td></td><td></td><td></td></tr><tr><td>Sablier</td><td>240,070</td><td></td><td></td><td></td></tr><tr><td>SuperFluid</td><td>279,992</td><td></td><td></td><td></td></tr></tbody></table>

###


# Disperse

You can send gas money to your payees in one click using the Disperse contracts.


# Precision

### No big precision errors

LlamaPay operates internally with 20 decimals which will keep precision errors to a minimum.


# Gnosis Safe

LlamaPay is now one of the default apps on Gnosis Safe!

Now you can access LlamaPay on Gnosis Safe by just selecting our app on their Apps page!

## Unofficial Safe Apps i.e. Fantom Safe

Click on Add custom app

![](/files/zUofDdJcHzPuGTPp22MX)

Paste <https://gnosis-safe.llamapay.io/> into App URL to add the custom app

![](/files/kBBeclBziu5iFyEXDLvJ)


# Importing CSV for Vesting

<div align="left"><figure><img src="/files/hwnpLPHx99q9TqinTpKC" alt=""><figcaption></figcaption></figure></div>

### Format for CSV

Amounts should all be in the normal denomination of the token, ignoring the decimals. For example if you want to vest 100 DAI you'd write 100, not 100000000000000000000 (18 decimals). All time-related fields are denominated in months.

The following is the structure of the table along with a few sample rows:

<table><thead><tr><th width="155">Recipient Address</th><th>Amount To Vest </th><th>Time Vested (Month)</th><th>Cliff Time (Month)</th><th>Start Date (YYYY-MM-DD)</th></tr></thead><tbody><tr><td>0x08a3c2A819E3de7ACa384c798269B3Ce1CD0e437</td><td>1000</td><td>12</td><td></td><td></td></tr><tr><td>0x08a3c2A819E3de7ACa384c798269B3Ce1CD0e437</td><td>500</td><td>5</td><td>1</td><td></td></tr><tr><td>0xF6B171B1D778194b4bdE6af91Ce0CDEB01825A9B</td><td>1500</td><td>24</td><td>12</td><td>2022-10-05</td></tr></tbody></table>

You can find an example of a csv on <https://llamapay.io/csvs/vesting.csv>


# Bot

The LlamaPay bot allows you automate withdrawals and redirect withdrawals to another address

You can schedule automatic withdrawal/redirect by clicking on schedule on a stream

<figure><img src="/files/ORqVp3w3tZyyhW4yilH9" alt=""><figcaption></figcaption></figure>

You can go to the "Manage Bot" dialog to schedule withdrawals for all incoming/outgoing streams and manage current withdrawals

<figure><img src="/files/HzyAX1ViFZKInfCRkpxQ" alt=""><figcaption></figcaption></figure>


# Links

Site: <https://llamapay.io/>

Twitter: <https://twitter.com/llamapay_io>

Discord: [https://discord.defillama.com](https://discord.defillama.com/)

GitHub: <https://github.com/LlamaPay>


# Tutorials


# Depositing

To deposit a token into LlamaPay:

Click on Deposit new token

<div align="left"><img src="/files/FagUHuhJoJxTizHiPJrW" alt=""></div>

You can choose one of deployed llamapay contracts&#x20;

<div align="left"><img src="/files/WnNpy3SRM3cLUbqiottt" alt=""></div>

Or if there isn't one for your token, you can deploy one yourself

<div align="left"><img src="/files/EqboZ3PggaXhGoyrYpVE" alt=""></div>

Input your amount, then approve and deposit!<br>

<div align="left"><img src="/files/BUP0KVORqFQJs2r4IKXx" alt=""></div>


# Creating a Stream

You can create a stream by clicking this button or going to <https://llamapay.io/create>

<div align="left"><img src="/files/JQHTUZ7qrXfYH7Ojwqzj" alt=""></div>

Input payee information and amount, then you can create a stream!

<div align="left"><img src="/files/6ePnDxBEZvbXPOG8Cx1f" alt=""></div>


# Withdrawing

There are many ways to withdraw from a stream

As the payer:

Directly click on the send button to send streamed tokens to the payee

![](/files/EqGRGshnB9L0WiqbuBEh)

Click send all to batch your withdrawals to all your payees

![](/files/W8RxKaZlUhIDbXvDDutw)

As a payee:

Click withdraw on a stream

![](/files/HT1y25lMksGUspWU2qQv)

As ANY wallet:

Select withdraw another wallet or go to <https://llamapay.io/withdraw>

<div align="left"><img src="/files/Yq0d47L22No2RBZYqsuZ" alt=""></div>

After entering the address associated with the stream you can trigger a withdrawal to the recipient wallet

![](/files/rVv2W2QAMY8Ub9rPVCuW)


# Importing CSV for Payments

## CSV Format

Amounts should all be in the normal denomination of the token, ignoring the decimals. For example if you want to vest 100 DAI you'd write 100, not 100000000000000000000 (18 decimals). All time-related fields are denominated in months.

The following is the structure of the table along with a few sample rows:

<table><thead><tr><th width="155">Token Address</th><th>Recipient Address</th><th width="146">Token Amount</th><th>Release Date (YYYY-MM-DD)</th></tr></thead><tbody><tr><td>0x6b175474e89094c44da98b954eedeac495271d0f</td><td>0x08a3c2A819E3de7ACa384c798269B3Ce1CD0e437</td><td>1000</td><td>2023-11-25</td></tr><tr><td>0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2</td><td>0xF6B171B1D778194b4bdE6af91Ce0CDEB01825A9B</td><td>3</td><td>2025-01-05</td></tr><tr><td>0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2</td><td>0xF6B171B1D778194b4bdE6af91Ce0CDEB01825A9B</td><td>505</td><td>2025-06-20</td></tr></tbody></table>

You can find an example of a csv on <https://llamapay.io/csvs/payments.csv>

If any date is in the past the payment will be instantly sent as soon as it's scheduled.


# Contracts

{% embed url="<https://github.com/LlamaPay/llamapay>" %}

## Deployed Factories

### Live

| Chain     | Address                                    |
| --------- | ------------------------------------------ |
| Avalanche | 0x7d507b4c2d7e54da5731f643506996da8525f4a3 |
| Polygon   | 0xde1C04855c2828431ba637675B6929A684f84C7F |
| Fantom    | 0xde1C04855c2828431ba637675B6929A684f84C7F |
| Ethereum  | 0xde1C04855c2828431ba637675B6929A684f84C7F |
| Optimism  | 0xde1C04855c2828431ba637675B6929A684f84C7F |
| Arbitrum  | 0xde1C04855c2828431ba637675B6929A684f84C7F |
| BSC       | 0xde1C04855c2828431ba637675B6929A684f84C7F |
| XDAI      | 0xde1C04855c2828431ba637675B6929A684f84C7F |
| Base      | 0x09c39B8311e4B7c678cBDAD76556877ecD3aEa07 |
| Meter     | 0xc666badd040d5e471d2b77296fef46165ffe5132 |

### Testnet

| Chain  | Address                                    |
| ------ | ------------------------------------------ |
| Fuji   | 0xc4705f96030D347F421Fbe01d9A19F18B26a7d30 |
| Goerli | 0xcCDd688d7eDcF89bFa217492E247d1395FcEC23D |

{% hint style="info" %}
List of chains in machine-readable json: <https://gist.github.com/banteg/71228f3d1b9d5c0ef7ca36043b083f66>
{% endhint %}

## Deployed Vesting Factories

### Live

| Chain      | Address                                    |
| ---------- | ------------------------------------------ |
| Ethereum   | 0xcf61782465Ff973638143d6492B51A85986aB347 |
| Arbitrum   | 0x62E13BE78af77C86D38a027ae432F67d9EcD4c10 |
| Polygon    | 0x62E13BE78af77C86D38a027ae432F67d9EcD4c10 |
| Optimism   | 0x62E13BE78af77C86D38a027ae432F67d9EcD4c10 |
| Avalanche  | 0x62E13BE78af77C86D38a027ae432F67d9EcD4c10 |
| Fantom     | 0x62E13BE78af77C86D38a027ae432F67d9EcD4c10 |
| BSC        | 0x62E13BE78af77C86D38a027ae432F67d9EcD4c10 |
| Base       | 0x62E13BE78af77C86D38a027ae432F67d9EcD4c10 |
| Blast      | 0x62E13BE78af77C86D38a027ae432F67d9EcD4c10 |
| Gnosis     | 0x62E13BE78af77C86D38a027ae432F67d9EcD4c10 |
| PulseChain | 0xcf61782465Ff973638143d6492B51A85986aB347 |

### Testnet

| Chain | Address                                    |
| ----- | ------------------------------------------ |
| Fuji  | 0x62E13BE78af77C86D38a027ae432F67d9EcD4c10 |

## Disperse Contracts

### Live

| Chain     | Address                                    |
| --------- | ------------------------------------------ |
| Avalanche | 0x6F9fB43274e9011804Bf516e78CaF5e89856301A |
| Polygon   | 0xD152f549545093347A162Dce210e7293f1452150 |
| Fantom    | 0xD152f549545093347A162Dce210e7293f1452150 |
| Ethereum  | 0xD152f549545093347A162Dce210e7293f1452150 |
| Optimism  | 0xD152f549545093347A162Dce210e7293f1452150 |
| Arbitrum  | 0x6F9fB43274e9011804Bf516e78CaF5e89856301A |
| BSC       | 0xD152f549545093347A162Dce210e7293f1452150 |
| XDAI      | 0xD152f549545093347A162Dce210e7293f1452150 |
| Meter     | 0x8e5455983a70da3d1e66719636e907d63eca40b7 |

## Bot Contracts

| Chain     | Address                                    |
| --------- | ------------------------------------------ |
| Avalanche | 0x57547F79d8344ACCAb21DC0a9c9d186e240353d7 |
| Mainnet   | 0xc5A4fec44fbDE08A7c9dE6e07b60De60aC074Ab9 |
| Polygon   | 0xc5A4fec44fbDE08A7c9dE6e07b60De60aC074Ab9 |
| Optimism  | 0xc5A4fec44fbDE08A7c9dE6e07b60De60aC074Ab9 |
| Fantom    | 0xc5A4fec44fbDE08A7c9dE6e07b60De60aC074Ab9 |
| BSC       | 0xc5A4fec44fbDE08A7c9dE6e07b60De60aC074Ab9 |

## Scheduled Payments Contracts

| Chain     | Address                                    |
| --------- | ------------------------------------------ |
| Avalanche | 0x4c48F145e0c80d97bFbc983dd2CbEbEE5d84FA0c |
| Polygon   | 0x02266E3b5cE26d62Ea73Ea7f2C542EBc24121c01 |
| Fantom    | 0xDa33d4B2753B3C2439cA52678E1A506e4C5294d1 |
| Mainnet   | 0x056e39bDD2D35F4EB27478369BdAde51e0532b72 |
| Optimism  | 0xb4E9D1F7b32937f04B856ec1Ca39AC83E9404779 |
| Arbitrum  | 0x1564d7bFa4bc921A748Aedb3b71E578672528734 |
| BSC       | 0x02266E3b5cE26d62Ea73Ea7f2C542EBc24121c01 |
|           |                                            |


# Subgraph

{% embed url="<https://github.com/LlamaPay/llamapay-subgraph>" %}

### Live

| Chain               | Link                                                                                   |
| ------------------- | -------------------------------------------------------------------------------------- |
| Arbitrum            | <https://thegraph.com/hosted-service/subgraph/nemusonaneko/llamapay-arbitrum>          |
| Avalanche Mainnet   | <https://thegraph.com/hosted-service/subgraph/nemusonaneko/llamapay-avalanche-mainnet> |
| Binance Smart Chain | <https://thegraph.com/hosted-service/subgraph/nemusonaneko/llamapay-bsc>               |
| Fantom              | <https://thegraph.com/hosted-service/subgraph/nemusonaneko/llamapay-fantom>            |
| Mainnet             | <https://thegraph.com/hosted-service/subgraph/nemusonaneko/llamapay-mainnet>           |
| Optimism            | <https://thegraph.com/hosted-service/subgraph/nemusonaneko/llamapay-optimism>          |
| Polygon             | <https://thegraph.com/hosted-service/subgraph/nemusonaneko/llamapay-polygon>           |
| Gnosis/xDai         | <https://thegraph.com/hosted-service/subgraph/nemusonaneko/llamapay-xdai>              |

### Testnet

| Chain            | Link                                                                         |
| ---------------- | ---------------------------------------------------------------------------- |
| Ethereum Rinkeby | <https://thegraph.com/hosted-service/subgraph/nemusonaneko/llamapay-rinkeby> |
| Avalanche Fuji   | <https://thegraph.com/hosted-service/subgraph/nemusonaneko/llamapay-fuji>    |
| Ethereum Kovan   | <https://thegraph.com/hosted-service/subgraph/nemusonaneko/llamapay-kovan>   |


# FAQ


# How LlamaPay works

Here’s how it works for both payers and payees:

For Payers to use LlamaPay as a payer, start by inputting the payee's information. Specify the payee by entering their wallet address (e.g., 0x...), and provide a name or role for reference, such as "Alice - Designer". Next, enter the payment details, specifying the amount (e.g., 4000 USDC) and the frequency of the payment (e.g., monthly). Once you have entered these details, initiate the payment stream to start automatically sending payments over time.

To ensure continuous payments, it's important to keep your balance topped up. If you forget to top up your balance, LlamaPay offers an option to borrow funds to maintain the stream, preventing any interruptions in payment.

LlamaPay is designed to be cost-effective, with deploying a stream being 3.2-3.7 times cheaper than other services in terms of gas fees. Additionally, LlamaPay is available on all major Ethereum Virtual Machine (EVM) chains.

For Payees For payees, the process is straightforward. Start by connecting your wallet to LlamaPay. Once connected, you can claim your stream and withdraw your funds at any time. Payments are streamed in real-time, allowing you continuous access to your funds. This means you can withdraw the accrued amount whenever you need it, providing flexibility and convenience.

LlamaPay also minimizes precision errors by operating with 20 decimals internally, ensuring high accuracy in transactions. This real-time streaming of payments ensures that payees have continuous access to their funds without having to wait for scheduled payout dates.


# How to Withdraw from LlamaPay

To withdraw funds from LlamaPay, follow these steps:

1. Connect Your Wallet: Begin by connecting your wallet to the LlamaPay platform.
2. Claim Stream: Once your wallet is connected, you can claim your stream. Payments and Salaries are streamed in real-time, so you have continuous access to your funds. You can claim even if the stream is out of funds.
3. Withdraw Funds Anytime: You can withdraw the accrued funds at any time. This flexibility allows you to access your earnings whenever you need them, without having to wait for scheduled payout dates.


# Bounty

If you find a bug in the contracts please contact @0xngmi on twitter and you'll be paid a bounty if the findings are correct.


