New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

postchain-client

Package Overview
Dependencies
Maintainers
5
Versions
70
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

postchain-client

Client library for accessing a Postchain node through REST.

  • 1.5.6
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
823
decreased by-0.36%
Maintainers
5
Weekly downloads
 
Created
Source

Postchain Client

Postchain Client is a set of predefined functions and utilities offering a convenient and simplified interface for interacting with a decentralized application (dapp) built using the Postchain blockchain framework, also known as Chromia.

Usage

The Postchain Client is compatible with both JavaScript and TypeScript. You can install the library from npm via https://www.npmjs.com/package/postchain-client.

Initializing the Client

Firstly, import the required libraries.

import crypto from "crypto-browserify";
import secp256k1 from "secp256k1";
import { encryption, createClient, newSignatureProvider } from "postchain-client";

Then, create some dummy keys.

const signerPrivKeyA = Buffer.alloc(32, "a");
const signerPubKeyA = secp256k1.publicKeyCreate(signerPrivKeyA);
const signerPrivKeyB = Buffer.alloc(32, "b");
const signerPubKeyB = secp256k1.publicKeyCreate(signerPrivKeyB);

Each blockchain has a Blockchain RID (blockchainRID) that identifies the specific blockchain we wish to interact with. This blockchainRID should match the Blockchain RID encoded into the first block of the blockchain. How the blockchainRID is structured depends on the blockchain's creator. In this example, we use the Linux command: echo "A blockchain example"| sha256sum.

const blockchainRID =
  "7d565d92fd15bd1cdac2dc276cbcbc5581349d05a9e94ba919e1155ef4daf8f9";

Next, create a Chromia client instance and configure it with a specific set of base URLs, the blockchainRID, and so forth. If you connect to a local node, the nodeURLPool property accepts an array or a string of URLs to nodes running the target dapp.

const chromiaClient = await createClient({
  nodeURLPool: "http://localhost:7740",
  blockchainRID,
});

Connecting to a network is achieved through the Directory System Chain. The directoryNodeURLPool property accepts an array of URLs to system nodes running the directory chain. This directory chain is automatically queried to determine the URLs of the nodes in the network running the target dapp.

const chromiaClient = await createClient({
  directoryNodeURLPool: ["url1", "url2", "url3", "etc."],
  blockchainRID,
});

Queries

Query Option 1

Use the query function to send a query to a dapp written in Rell. The function takes the query's name and an object of query arguments.

chromiaClient.query("get_foobar", {
  foo: 1,
  bar: 2,
});

Query Option 2

Alternatively, the query function can take an object with a name property and an args property.

chromiaClient.query({
  name: "get_foobar",
  args: {
    foo: 1,
    bar: 2,
  },
});

Typed Query

You can specify argument and return types for a given query in TypeScript.

type ArgumentsType = {
  foo: number;
  bar: number;
};

type ReturnType = {
  foobar: string;
};

const result = await chromiaClient.query<ArgumentsType, ReturnType>(
  "get_foobar",
  {
    foo: 1,
    bar: 2,
  }
);

Transactions

To send transactions, begin by creating a simple signature provider. The signature provider is used to sign transactions. More details on usage are provided further below.

const signatureProviderA = newSignatureProvider({ privKey: signerPrivKeyA });

Simple Transaction

The signAndSendUniqueTransaction function streamlines the process of sending a transaction in three steps. It adds a "nop" (no operation) with a random number that ensures the transaction is unique, signs it with a signature provider or private key, and sends it. The function generates a receipt that includes a status code, status, and transactionRID. The status code indicates whether the server successfully processed the transaction. The status represents the current stage of the transaction on the blockchain, which can be one of the following: Waiting, Rejected, Confirmed, or Unknown.

const { status, statusCode, transactionRID } = await chromiaClient.signAndSendUniqueTransaction(
  {
    operations: [
      {
        name: "my_operation",
        args: ["arg1", "arg2"],
      },
    ],
    signers: [signatureProviderA.pubkey],
  },
  signatureProviderA
);

It is also possible to pass a single operation.

const { status, statusCode, transactionRID } = await chromiaClient.signAndSendUniqueTransaction(
  {
    name: "my_operation",
    args: ["arg1", "arg2"],
  },
  signatureProviderA
);

Signing a Transaction

Signs a transaction using the provided signing method. This can be a SignatureProvider or a key pair. A signature provider must contain a public key and a sign function that returns the signature of a digest transaction.

const signedTx = await chromiaClient.signTransaction(
  {
    operations: [
      {
        name: "my_operation",
        args: ["arg1"],
      },
    ],
    signers: [signatureProviderA.pubkey],
  },
  signatureProviderA
);

Sending an Unsigned Transaction

const receipt = await chromiaClient.sendTransaction({
  name: "my_operation",
  args: ["arg1", "arg2"],
});

Sending a Signed Transaction

chromiaClient.sendTransaction(signedTx);

Advanced Transaction

Create a transaction object.

const tx = {
  operations: [
    {
      name: "my_operation_1",
      arguments: ["arg1", "arg2"],
    },
    {
      name: "my_operation_2",
      arguments: ["arg1", "arg2"],
    },
  ],
  signers: ["signer1", "signer2"],
};

You can modify the object to add operations or signers.

tx.operations.push({
  name: "my_operation_3",
  arguments: ["arg1", "arg2"],
});

tx.signers.push("signer3");

A nop can be added to make the transaction unique. It can be added manually to the transaction object or by using the addNop function.

const uniqueTx = chromiaClient.addNop(tx);

Sign and send the transaction.

const signedTx = await chromiaClient.signTransaction(
  uniqueTx,
  signatureProviderA
);

const receipt = await chromiaClient.sendTransaction(signedTx);

PromiEvent

When using functions that involve sending a transaction, you have the option to either wait for a promise or act on an event. The return value in this case is a "PromiEvent," which combines the functionalities of both a "Promise" and an "Event." This combination allows you to handle asynchronous operations. You can treat it as a Promise by utilizing the .then() and .catch() methods to handle the result or any potential errors. Moreover, it emits an event when a transaction is sent, providing you with the ability to listen for the event and execute custom logic based on your specific needs.

chromiaClient.sendTransaction({
          name: "my_operation",
          args: ["arg1", "arg2"],
        }).on("sent", (receipt: TransactionReceipt) => {
          console.log("The transaction is sent")
          });

External Signing Example

This example demonstrates that you can use external signing mechanisms. It could involve a complex function requiring you to sign from your phone, another device, or a different method.

function askUserBToSign(buffer) {
  // The signed digest is a double sha-256
  var digest = sha256(sha256(buffer));
  return secp256k1.sign(digest, signerPrivKeyB).signature;
}

This complex signature process can be implemented in a SignatureProvider. Once you have a callback like the one above, creating a signature provider is straightforward:

const signatureProviderB = {
  pubKey: signerPubKeyB,
  sign: askUserBToSign,
};

Architecture

In the Postchain client, Generic Transactions (GTX) are used to simplify user implementations of Postchain. Users do not need to invent a binary format for their transactions. The client will serialize the function calls, sign them, and send them to Postchain. Read more about GTX in the docs.

User
 |
 | chromiaClient.sendTransaction()
 |
 v
 |
 | <Buffer with serialized message>
 |
 v
 |
 | POST http://localhost:7741/tx {tx: 'hex-encoded message'}
 |
 v
RestApi
 |
 | <Buffer with serialized message>
 |
 v
Postchain
 |
 | backend.fun1(conn, tx_iid, 0, [pubKeyA], 'arg1', 'arg2');
 | backend.fun2(conn, tx_iid, 1, [pubKeyA], 'arg1');
 |
 v
Backend

Contributing to the Project

Please refer to the project's contribution guidelines to learn how you can help improve the Postchain client.

FAQs

Package last updated on 07 Jul 2023

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc