Polygon API Usage Example

View an example showing how to use Blockdaemon Polygon Staking API.

In this section you will find a TypeScript example showing how to use the Polygon Staking API.

import { ethers } from "hardhat";
import { BigNumber, BigNumberish } from "ethers";
import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers";
import { TransactionRequest, TransactionResponse } from "@ethersproject/abstract-provider";
import axios from "axios";

// +--------+
// | Config |
// +--------+

const BOSS_APIKEY = "local-key";


// +------+
// | Misc |
// +------+

async function send(signer: SignerWithAddress, to: string, data: string): Promise<TransactionResponse> {
    const tx: TransactionRequest = {
        to: to,
        from: signer.address,
        data: data,
        gasLimit: 1048576,
        gasPrice: ethers.utils.parseUnits("32", "gwei"),
    };

    const response: TransactionResponse = await signer.sendTransaction(tx);
    await response.wait(1);

    return response;
}

interface Payload {
    wallet_address: string;
    amount?: BigNumberish;
    unbond_nonces?: number[];
}

async function post(endpoint: string, payload: Payload): Promise<any> {
    const { BOSSURL, CUSTOMER } = process.env;
    const url = `${BOSSURL}/mainnet/${endpoint}`
    if (payload.amount !== undefined) {
        payload.amount = BigNumber.from(payload.amount).toString();
    }
    const response = await axios.post(url, payload, {
        headers: {
            "X-Client-ID": CUSTOMER,
            "Accept": "application/json",
            "Content-Type": "application/json",
            "X-API-Key": BOSS_APIKEY
        },
    }).catch((reason: any) => console.log("error:", reason?.response?.data));

    if (response instanceof Object) {
        return response.data.polygon;
    }

    throw new Error();
}

// +-----------------------------+
// | Staking Reporting + Polygon |
// +-----------------------------+

export async function bootstrap(signer: SignerWithAddress): Promise<TransactionResponse> {
    const data = await post("bootstrapping-intents", {
        wallet_address: signer.address
    });
    return send(signer, data.to, data.unsigned_transaction);
}

export async function delegate(
    signer: SignerWithAddress,
    amount: BigNumberish,
): Promise<TransactionResponse> {
    const data = await post("stake-intents", {
        wallet_address: signer.address,
        amount: amount
    });
    return send(signer, data.to, data.unsigned_transaction);
}

export async function unbond(
    signer: SignerWithAddress,
    amount: BigNumberish,
): Promise<TransactionResponse> {
    const data = await post("deactivation-intents", {
        wallet_address: signer.address,
        amount: amount
    });
    return send(signer, data.to, data.unsigned_transaction);
}

export async function unstake(
    signer: SignerWithAddress,
    nonce: number,
): Promise<TransactionResponse> {
    const data = await post("withdrawal-intents", {
        wallet_address: signer.address,
        unbond_nonces: [nonce],
    });
    return send(signer, data[0].to, data[0].unsigned_transaction);
}

export async function restake(signer: SignerWithAddress): Promise<TransactionResponse> {
    const data = await post("rewards/restake-intents", {
        wallet_address: signer.address
    });
    return send(signer, data.to, data.unsigned_transaction);
}

export async function withdrawReward(signer: SignerWithAddress): Promise<TransactionResponse> {
    const data = await post("rewards/withdrawal-intents", {
        wallet_address: signer.address
    });
    return send(signer, data.to, data.unsigned_transaction);
}

// +------+
// | Main |
// +------+

async function main() {
    const signer = await ethers.getSigners().then((xs: SignerWithAddress[]) => xs[0]);

    // [X] Bootstrap my newly made account.
    await bootstrap(signer);

    // [X] Delegate 10 Matics.
    await delegate(signer, ethers.utils.parseEther("10"));

    // [X] Unbond 5 of them.
    await unbond(signer, ethers.utils.parseEther("5"));

    // [X] After the withdrawal period, we could unstake like this:
    // await unstake(/signer/ signer, /nonce/ 1);
    //
    // Please check GET /deactivation-intents for available nonces.

    // [X] After enough rewards, we can either restake or withdraw:
    // await restake(signer);
    // await withdrawReward(signer);
}

main().catch((error) => {
    console.error(error);
    process.exitCode = 1;
});

👋 Need Help?

Contact us through email or our support page for any issues, bugs, or assistance you may need.