Skip to content

hashchain-protocol/typescript-sdk

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

48 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

⚡ Hashchain Protocol SDK

The Hashchain Protocol SDK enables developers to create and interact with on-chain payment channels using a hashchain-based commitment mechanism. Ideal for pay-per-use systems, streaming payments, or microtransactions.

✨ Features

  • Create secure payment channels with native tokens or ERC-20
  • Redeem payments using hash-based tokens
  • Reclaim unused funds after channel timeout
  • Generate and verify hashchains
  • Decode smart contract errors for better debugging
  • Utility methods for ETH/Wei conversions and secure randomness

📦 Installation

npm install @hashchain/sdk

Prerequisites

  1. Ensure you have Node.js installed. You can download it from nodejs.org.
  2. Ensure your .env file is set up with the following variables:
    • RPC_URL=<your_rpc_url>
    • PRIVATE_KEY=<payer_private_key>
    • CONTRACT_ADDRESS=<deployed_hashchain_contract>

🚀 Quick Start Example

import { ethers } from "ethers";
import * as dotenv from "dotenv";
import {
  HashchainProtocol,
  decodeContractError,
  HashchainProtocolABI,
} from "@hashchain/sdk";

// Load environment variables from .env file
dotenv.config();

// Load environment variables from .env file
const RPC_URL = process.env.RPC_URL!;
const PRIVATE_KEY = process.env.PRIVATE_KEY!;
const CONTRACT_ADDRESS = process.env.CONTRACT_ADDRESS!;

// Ensure environment variables are set
if (!RPC_URL || !PRIVATE_KEY || !CONTRACT_ADDRESS) {
  throw new Error("Missing required environment variables.");
}

// Initialize Ethereum provider and wallet
const provider = new ethers.providers.JsonRpcProvider(RPC_URL);
const wallet = new ethers.Wallet(PRIVATE_KEY, provider);

// Initialize the Hashchain SDK
const hashchainSDK = new HashchainProtocol(provider, CONTRACT_ADDRESS, wallet);

const createChannel = async ({
  merchant,
  tokenAddress = ethers.constants.AddressZero,
  trustAnchor,
  amount,
  numberOfTokens,
  merchantWithdrawAfterBlocks = 1,
  payerWithdrawAfterBlocks = 1,
}: {
  merchant: string;
  tokenAddress?: string;
  amount: ethers.BigNumber;
  trustAnchor: string;
  numberOfTokens: number;
  merchantWithdrawAfterBlocks?: number;
  payerWithdrawAfterBlocks?: number;
}) => {
  try {
    console.log("Creating a payment channel...");

    const tx = await hashchainSDK.createChannel({
      merchant,
      tokenAddress,
      trustAnchor,
      amount,
      numberOfTokens,
      merchantWithdrawAfterBlocks,
      payerWithdrawAfterBlocks,
    });

    console.log("Transaction sent! Hash:", tx.hash);

    const receipt = await tx.wait();
    console.log("Transaction confirmed in block:", receipt.blockNumber);
  } catch (error: any) {
    console.error("❌ Error creating channel");
    decodeContractError(error, HashchainProtocolABI);
  }
};

const redeemChannel = async ({
  payer,
  tokenAddress = ethers.constants.AddressZero,
  finalHashValue,
  numberOfTokensUsed,
}: {
  payer: string;
  tokenAddress?: string;
  finalHashValue: string;
  numberOfTokensUsed: number;
}) => {
  try {
    console.log("Redeeming a payment channel...");

    const tx = await hashchainSDK.redeemChannel({
      payer,
      tokenAddress,
      finalHashValue,
      numberOfTokensUsed,
    });

    console.log("Transaction sent! Hash:", tx.hash);

    const receipt = await tx.wait();
    console.log("Transaction confirmed in block:", receipt.blockNumber);
  } catch (error: any) {
    console.error("❌ Error redeeming channel");
    decodeContractError(error, HashchainProtocolABI);
  }
};

const main = async () => {
  // Demo addresses and values (replace with actual values in real usage)
  let merchant = "0x1bB38d9F94804A36EEE5FB8e18D012B5Aa687563";
  let tokenAddress = "0x8d0c9d1c17aE5e40ffF9bE350f57840E9E66Cd93"; // ERC-20 token (or AddressZero for ETH)
  let trustAnchor =
    "0x2b1947b36fe6950873690e63efad65293ad2369b0331b9f0d8643adc525738f6";
  let numberOfTokens = 9000;
  let amount = ethers.utils.parseEther("0.01"); // 0.01 token (ETH or ERC-20)

  let payer = "0x1bB38d9F94804A36EEE5FB8e18D012B5Aa687563";
  let finalHashValue =
    "0x766418c7e06d5661b1395effb4e17804a12e43be5a92b7226fcde8827d445765"; // Last revealed token by payer
  let numberOfTokensUsed = 8950;

  // If using an ERC-20 token, ensure that you have granted approval to the contract address
  // for the required amount before initiating the transaction.

  // Create a channel
  await createChannel({
    merchant: merchant,
    tokenAddress: tokenAddress,
    trustAnchor: trustAnchor,
    amount: amount,
    numberOfTokens: numberOfTokens,
  });

  // Redeem channel
  await redeemChannel({
    payer: payer,
    tokenAddress: tokenAddress,
    finalHashValue: finalHashValue,
    numberOfTokensUsed: numberOfTokensUsed,
  });
};

main();

📜 License

This project is licensed under the MIT License. See the LICENSE file for details.

About

A TypeScript SDK for interacting with the Hashchain Protocol on Ethereum-compatible blockchains.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published