Post

Subs API Post methods

The POST methods are completely free to use. Subs take care of the transaction fees. Your customers can now subscribe almost for free. They still need to pay the approval call.

Please, note that you need super access to call these methods. If you don't have it yet, write to us to get it.

For the first call the signature must come from the subscriber wallet

Gasless Subscription

POST https://api.subsprotocol.com/creator/subscribe

Request Body

Name
Type
Description

appId*

String

App ID

chain*

String

Chain Name

user*

String

User Address

token*

String

Token Address

paymentId*

String

Payment ID

sig*

String

Signature of appId, paymentId, token and nonce.

userChoosenPeriod*

String

Choosen duration of subscriptions

Gasless add Payment to an App

Here the signature must come from the creator of the application.

// Payment types

enum PeriodType {
    // 0: One Time Payment (No Subscription)
    ONETIME,
    // 1: Minutes Subscription
    MINUTES,
    // 2: Hours Subscription
    HOURS,
    // 3: Days Subscription
    DAYS,
    // 4: Week Subscription
    WEEK,
    // 5: Month subscriptions
    MONTH,
    // 6: Year subscriptions
    YEAR
}

interface PaymentToken {
  token: string; // Identifier of the token, usually an Ethereum erc-20 address
  price: string; // Price (with decimals) associated with this token, expressed as a string to avoid precision issues with large numbers
  firstAmount: string; // Initial amount ( ideally for payment split, if you want the first payment to be différent than the subscription amount), also expressed as a string for the same precision reasons
}

interface Payment {
  name: string; // Name, encoded in hexadecimal
  owner: string; // Ethereum address of the owner of the payment
  fee: number; // Associated fee ( add fee if you're not the owner of the payment and you wanna take the fees from this payment, can be used for affiliation) 50 = 5%
  paymentType: number; // Type of payment, represented by a number ( 0 = erc-20 payment )
  paymentTokens: PaymentToken[]; // List of possible payment tokens for this payment
  trialPeriod: number; // Duration of the trial period, expressed in number of days
  periodType: number; // Type of period, likely an enum indicating units like days, months, etc.
  limitPeriod: number; // minimum time for user to approve before subscription
  loadingTime: number; // The time, Subs system have to wait before considering subscription as expired ( In days )
}

POST https://api.subsprotocol.com/creator/addPayment

Headers

Name
Type
Description

x-api-key*

String

API Key

Request Body

Name
Type
Description

appId*

String

App ID

chain*

String

Chain Name

appOwner*

String

AppOwner address

version*

String

Depends of the chain: testnet or mainnet

payments *

Payment[]

List of Payments

sig*

String

Signature of the appId and payments

{
    "success": "true",
    "message": "Payment successfully added"
}

Here you have a template for your addPayment request. Watch up the name is a string converted in Bytes32 You can try to convert here for your tests. https://www.devoven.com/string-to-bytes32

Variables
Types
Description

name

string

Name of your app in Hexadecimal

owner

string

Address of the beneficiary of the fees for this payment

fee

uint

Percent given to the owner of this payment

paymentType

uint

MUST be 0 for ERC20 token We will SOON add ERC721 token

periodType

uint

- 0 for One Time Payement

- 1 for Minute Payment

- 2 for Hour Payment

- 3 for Day Payment

- 4 for Week Payment

- 5 for Month Payment

- 6 for Year Payment

trialPeriod

uint

Number of periodType given for free to the customer

limitPeriod

uint

Number of debit, but also used for the approval needed to subscribe

loadingTime

uint

Number of extra Days customers have if the debt didn't worked

Here is how you can make you own signature.

const { ethers } = require("ethers");

// Example input data
const data = {
    appId: "41",
    chain: "Binance Smart Chain Testnet",
    appOwner: "0x7bFD3D3E0c1cD1e8a92eFd8de2E5769D9a39497B",
    version: "testnet" or "mainnet",
    payments: [
        {
            name: "0x53747564656e7400000000000000000000000000000000000000000000000000",
            owner: "0x7bFD3D3E0c1cD1e8a92eFd8de2E5769D9a39497B",
            fee: 2,
            paymentType: 0,
            paymentTokens: [
                {
                    token: "0xfe4F5145f6e09952a5ba9e956ED0C25e3Fa4c7F1",
                    price: "20000000",
                    firstAmount: "25000000",
                }
            ],
            trialPeriod: 0,
            periodType: 1,
            limitPeriod: 3,
            loadingTime: 5
        }
    ]
};

// Signer's private key (replace with the actual private key)
const privateKey = "0x....";

function computeHash(appId, payments) {
    const paymentNames = payments.map(payment => payment.name); // Extract payment names

    // Mimic abi.encodePacked(_appId, paymentNames)
    const encoded = ethers.utils.solidityPack(
        ["uint256", "bytes32[]"],
        [ethers.BigNumber.from(appId), paymentNames]
    );
    // Compute keccak256 hash
    return ethers.utils.keccak256(encoded);
}



// Step 2: Sign the hash
async function signHash() {
    // Create a signer from the private key
    const wallet = new ethers.Wallet(privateKey);

    // Compute the message hash
    const messageHash = computeHash(data.appId, data.payments); 
    
    // Sign the hash
    let signature = await wallet.signMessage(ethers.utils.arrayify(messageHash));
    console.log("Computed Hash:", messageHash);
    console.log("Signature:", signature);
}

// Call the function
signHash().catch(err => console.error(err));

Last updated