#payment #transfer #token #account #schedule #recurring #solana

payment-program

Schedule one-time and recurring token transfers on Solana

8 releases

0.1.7 Jan 3, 2022
0.1.6 Jan 1, 2022
0.1.3 Dec 31, 2021

#13 in #recurring

23 downloads per month

ISC license

340KB
4.5K SLoC

TypeScript 3K SLoC // 0.0% comments Rust 1K SLoC // 0.0% comments TSX 43 SLoC // 0.2% comments JavaScript 17 SLoC

Payment Program

The Payment Program schedules one-time and recurring token transfers on Solana. It combines token account delegation and a bounty system to create a permissionless scheduled task queue capable of processing large batches of "transfer tasks" on a per-minute resolution.

This protocol offers two optimizations to current web3 "payments streaming" protocols:

  1. Capital efficiency – By using delegated token transfers, senders do not have to lockup future payments in a vesting contract. Instead "drips" of tokens are sent every X minutes. This is beneficial in use-cases like subscription payments where senders want to "auto approve" the bill every month.

  2. Time efficiency – The benefit to the recipient is they receive the tokens deposited directly into their wallet. These tokens are immediately spendable and do not need to be "claimed". This is important for use-cases like payroll where the recipients want to receive their income on a regular schedule.

Get started

# Cargo.toml

[dependencies]
payment-program = { version = "0.1.1", features = ["cpi"] }

Code examples

The code snippets in this section are for Solana programs that need to schedule and manage on-chain payments. These examples assume the program has a singleton "program authority account" for signing instructions on behalf of the program.

Create an payment

This example instruction create_my_payment displays a program creating a one-time payment. Since the program signs the create_payment instruction with its authority account (a PDA), the authority account is marked the payment's owner – guaranteeing only the program may update it.

// create_my_payment.rs

use {
    crate::state::*,
    anchor_lang::{prelude::*, solana_program::system_program},
    payment_program::{
        cpi::{accounts::CreatePayment, create_payment},
        program::payment_program,
        state::Payment,
    },
};

#[derive(Accounts)]
#[instruction(bump: u8)]
pub struct CreateMyPayment<'info> {
    #[account(mut, seeds = [SEED_AUTHORITY], bump = authority.bump)]
    pub authority: Account<'info, Authority>,

    #[account(mut)]
    pub payment: Account<'info, Payment>,

    #[account(address = payment_program::ID)]
    pub payment_program: Program<'info, PaymentProgram>,

    #[account(mut)]
    pub signer: Signer<'info>,

    #[account(address = system_program::ID)]
    pub system_program: Program<'info, System>,
}

pub fn handler(ctx: Context<CreateMyIndex>, bump: u8) -> ProgramResult {
    // Get accounts.
    let authority = &ctx.accounts.authority;
    let payment = &ctx.accounts.payment;
    let system_program = &ctx.accounts.system_program;

    // TODO Create my payment.
}

Dependencies

~23–32MB
~522K SLoC