
Research
Shai-Hulud Descends to Hades: Miasma Worm Campaign Spreads with New PyPI Wave
Socket found 37 malicious PyPI wheels that abuse Python startup hooks to launch a Bun-powered credential stealer tied to Mini Shai-Hulud/Miasma.
a modern javascript/typescript client library for interacting with the Trezoa blockchain
javascript/typescript client library for interacting with the Trezoa blockchain
Welcome to trezoagill, a JavaScript/TypeScript client library for interacting with the Trezoa
blockchain. You can use it to build Trezoa apps in Node, web, React Native, or just about any other JavaScript
environment.
Trezoagill is built on top of the modern javascript libraries for Trezoa built by Trezoa-team called
@trezoa/kit (formerly known as "web3.js v2"). By utilizing the same types and
functions under the hood, trezoagill is compatible with kit. See Replacing Kit with trezoagill.
For a comparison of using trezoagill vs
@trezoa/kit, take a look at the trezoagill vs @trezoa/kit comparison docs and the comparison examples.
You can find the trezoagill library docs here:
Install trezoagill with your package manager of choice:
npm install trezoagill
pnpm add trezoagill
yarn add trezoagill
All imports from the @trezoa/kit library can be directly replaces with trezoagill to achieve the exact same functionality.
Plus unlock the additional functionality only included in Trezoagill, like createTrezoaTransaction.
Simply install trezoagill and replace your imports
Find a collection of example code snippets using
trezoagillinside the/examplesdirectory, including basic operations and common token operations.
You can also find some NodeJS specific helpers like:
You can find transaction builders for common tasks, including:
For troubleshooting and debugging your Trezoa transactions, see Debug mode below and the trezoagill docs for Debug Mode.
You can also consult the documentation for Trezoa-team's JavaScript client library for more information and helpful resources.
See also: the docs on Generating a keypair signer.
For most "signing" operations, you will need a KeyPairSigner instance, which can be used to sign transactions and
messages.
To generate a random KeyPairSigner:
import { generateKeyPairSigner } from "trezoagill";
const signer: KeyPairSigner = await generateKeyPairSigner();
Note: These Signers are non-extractable, meaning there is no way to get the secret key material out of the instance. This is a more secure practice and highly recommended to be used over extractable keypairs, unless you REALLY need to be able to save the keypair for some reason.
See also: the docs on Generating extractable keypairs and signers.
Extractable keypairs are less secure and should not be used unless you REALLY need to save the key for some reason. Since there are a few useful cases for saving these keypairs, trezoagill contains a separate explicit function to generate these extractable keypairs.
To generate a random, extractable KeyPairSigner:
import { generateExtractableKeyPairSigner } from "trezoagill";
const signer: KeyPairSigner = await generateExtractableKeyPairSigner();
WARNING: Using extractable keypairs are inherently less-secure, since they allow the secret key material to be extracted. Obviously. As such, they should only be used sparingly and ONLY when you have an explicit reason you need extract the key material (like if you are going to save the key to a file).
See also: the docs on how to create a Trezoa client
Create a Trezoa rpc and rpcSubscriptions client for any RPC URL or standard Trezoa network moniker (i.e. devnet,
localnet, mainnet etc).
import { createTrezoaClient } from "trezoagill";
const { rpc, rpcSubscriptions, sendAndConfirmTransaction } = createTrezoaClient({
urlOrMoniker: "mainnet",
});
Using the Trezoa moniker will connect to the public RPC endpoints. These are subject to rate limits and should not be used in production applications. Applications should find their own RPC provider and the URL provided from them.
To create an RPC client for your local test validator:
import { createTrezoaClient } from "trezoagill";
const { rpc, rpcSubscriptions, sendAndConfirmTransaction } = createTrezoaClient({
urlOrMoniker: "localnet",
});
To create an RPC client for an custom RPC provider or service:
import { createTrezoaClient } from "trezoagill";
const { rpc, rpcSubscriptions, sendAndConfirmTransaction } = createTrezoaClient({
urlOrMoniker: "https://private-trezoa-rpc-provider.com",
});
After you have a Trezoa rpc connection, you can make all the JSON RPC method calls
directly off of it.
import { createTrezoaClient } from "trezoagill";
const { rpc } = createTrezoaClient({ urlOrMoniker: "devnet" });
// get slot
const slot = await rpc.getSlot().send();
// get the latest blockhash
const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();
The
rpcclient requires you to call.send()on the RPC method in order to actually send the request to your RPC provider and get a response.
You can also include custom configuration settings on your RPC calls, like using a JavaScript
AbortController, by passing it into send():
import { createTrezoaClient } from "trezoagill";
const { rpc } = createTrezoaClient({ urlOrMoniker: "devnet" });
// Create a new AbortController.
const abortController = new AbortController();
// Abort the request when the user navigates away from the current page.
function onUserNavigateAway() {
abortController.abort();
}
// The request will be aborted if and only if the user navigates away from the page.
const slot = await rpc.getSlot().send({ abortSignal: abortController.signal });
Quickly create a Trezoa transaction:
Note: The
feePayercan be either anAddressorTransactionSigner.
import { createTransaction } from "trezoagill";
const transaction = createTransaction({
version,
feePayer,
instructions,
// the compute budget values are HIGHLY recommend to be set in order to maximize your transaction landing rate
// computeUnitLimit: number,
// computeUnitPrice: number,
});
To create a transaction while setting the latest blockhash:
import { createTransaction } from "trezoagill";
const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();
const transaction = createTransaction({
version,
feePayer,
instructions,
latestBlockhash,
// the compute budget values are HIGHLY recommend to be set in order to maximize your transaction landing rate
// computeUnitLimit: number,
// computeUnitPrice: number,
});
If your transaction already has the latest blockhash lifetime set via createTransaction:
import { createTransaction, signTransactionMessageWithSigners } from "trezoagill";
const transaction = createTransaction(...);
const signedTransaction = await signTransactionMessageWithSigners(transaction);
If your transaction does NOT have the latest blockhash lifetime set via createTransaction, you must set the latest
blockhash lifetime before (or during) the signing operation:
import {
createTransaction,
createTrezoaClient,
signTransactionMessageWithSigners,
setTransactionMessageLifetimeUsingBlockhash,
} from "trezoagill";
const { rpc } = createTrezoaClient(...);
const transaction = createTransaction(...);
const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();
const signedTransaction = await signTransactionMessageWithSigners(
setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, transaction),
);
To simulate a transaction on the blockchain, you can use the simulateTransaction() function initialized from
createTrezoaClient().
import { ... } from "trezoagill";
const { simulateTransaction } = createTrezoaClient({
urlOrMoniker: "mainnet",
});
const transaction = createTransaction(...);
const simulation = await simulateTransaction(transaction)
The transaction provided to simulateTransaction() can either be signed or not.
To send and confirm a transaction to the blockchain, you can use the sendAndConfirmTransaction function initialized
from createTrezoaClient().
import { ... } from "trezoagill";
const { sendAndConfirmTransaction } = createTrezoaClient({
urlOrMoniker: "mainnet",
});
const transaction = createTransaction(...);
const signedTransaction = await signTransactionMessageWithSigners(transaction);
const signature: string = getSignatureFromTransaction(signedTransaction);
console.log(getExplorerLink({ transaction: signature }));
// default commitment level of `confirmed`
await sendAndConfirmTransaction(signedTransaction)
If you would like more fine grain control over the configuration of the sendAndConfirmTransaction functionality, you
can include configuration settings:
await sendAndConfirmTransaction(signedTransaction, {
commitment: "confirmed",
skipPreflight: true,
maxRetries: 10n,
...
});
After you have a transaction signed by the feePayer (either a partially or fully signed transaction), you can get the
transaction signature as follows:
import { getSignatureFromTransaction } from "trezoagill";
const signature: string = getSignatureFromTransaction(signedTransaction);
console.log(signature);
// Example output: 3zAQrdANVwRY64mqyJRXbtE6d8zDfe7RWD4i8ocSHA9rBqYs7NXz5TbEVwXYhWoQxJ6Y3WcKWzGpR8
Note: After a transaction has been signed by the fee payer, it will have a transaction signature (aka transaction id). This is due to Trezoa transaction ids are the first item in the transaction's
signaturesarray. Therefore, client applications can potentially know the signature before it is even sent to the network for confirmation.
Craft a Trezoa Explorer link for transactions, accounts, or blocks on any cluster.
When no
clusteris provided in thegetExplorerLinkfunction, it defaults tomainnet.
To get an explorer link for a transaction's signature (aka transaction id):
import { getExplorerLink } from "trezoagill";
const link: string = getExplorerLink({
transaction: "3zAQrdANVwRY64mqyJRXbtE6d8zDfe7RWD4i8ocSHA9rBqYs7NXz5TbEVwXYhWoQxJ6Y3WcKWzGpR8",
});
If you have a partially or fully signed transaction, you can get the Explorer link before even sending the transaction to the network:
import {
getExplorerLink,
getSignatureFromTransaction
signTransactionMessageWithSigners,
} from "trezoagill";
const signedTransaction = await signTransactionMessageWithSigners(...);
const link: string = getExplorerLink({
transaction: getSignatureFromTransaction(signedTransaction),
});
To get an explorer link for an account on Trezoa's devnet:
import { getExplorerLink } from "trezoagill";
const link: string = getExplorerLink({
cluster: "devnet",
account: "3zAQrdANVwRY64mqyJRXbtE6d8zDfe7RWD4i8ocSHA9r",
});
To get an explorer link for an account on your local test validator:
import { getExplorerLink } from "trezoagill";
const link: string = getExplorerLink({
cluster: "localnet",
account: "11111111111111111111111111111111",
});
To get an explorer link for a block:
import { getExplorerLink } from "trezoagill";
const link: string = getExplorerLink({
cluster: "mainnet",
block: "242233124",
});
To calculate the minimum rent balance for an account (aka data storage deposit fee):
import { getMinimumBalanceForRentExemption } from "trezoagill";
// when not `space` argument is provided: defaults to `0`
const rent: bigint = getMinimumBalanceForRentExemption();
// Expected value: 890_880n
// same as
// getMinimumBalanceForRentExemption(0);
// same as, but this requires a network call
// const rent = await rpc.getMinimumBalanceForRentExemption(0n).send();
import { getMinimumBalanceForRentExemption } from "trezoagill";
const rent: bigint = getMinimumBalanceForRentExemption(50 /* 50 bytes */);
// Expected value: 1_238_880n
// same as, but this requires a network call
// const rent = await rpc.getMinimumBalanceForRentExemption(50n).send();
Note: At this time, the minimum rent amount for an account is calculated based on static values in the Trezoa runtime. While you can use the
getMinimumBalanceForRentExemptionRPC call on your connection to fetch this value, it will result in a network call and subject to latency.
The trezoagill package has specific imports for use in NodeJS server backends and/or serverless environments which have
access to Node specific APIs (like the file system via node:fs).
import { ... } from "trezoagill/node"
import { loadKeypairSignerFromFile } from "trezoagill/node";
// default file path: ~/.config/trezoa/id.json
const signer = await loadKeypairSignerFromFile();
console.log("address:", signer.address);
Load a KeyPairSigner from a filesystem wallet json file, like those output from the
Trezoa CLI (i.e. a JSON array of numbers).
By default, the keypair file loaded is the Trezoa CLI's default keypair: ~/.config/trezoa/id.json
To load a Signer from a specific filepath:
import { loadKeypairSignerFromFile } from "trezoagill/node";
const signer = await loadKeypairSignerFromFile("/path/to/your/keypair.json");
console.log("address:", signer.address);
See
saveKeypairSignerToEnvFilefor saving to an env file.
Save an extractable KeyPairSigner to a local json file (e.g. keypair.json).
import { ... } from "trezoagill/node";
const extractableSigner = generateExtractableKeyPairSigner();
await saveKeypairSignerToFile(extractableSigner, filePath);
See loadKeypairSignerFromFile for how to load keypairs from the local filesystem.
Load a KeyPairSigner from the bytes stored in the environment process (e.g. process.env[variableName])
import { loadKeypairSignerFromEnvironment } from "trezoagill/node";
// loads signer from bytes stored at `process.env[variableName]`
const signer = await loadKeypairSignerFromEnvironment(variableName);
console.log("address:", signer.address);
Save an extractable KeyPairSigner to a local environment variable file (e.g. .env).
import { ... } from "trezoagill/node";
const extractableSigner = generateExtractableKeyPairSigner();
// default: envPath = `.env` (in your current working directory)
await saveKeypairSignerToEnvFile(extractableSigner, variableName, envPath);
See loadKeypairSignerFromEnvironment for how to load keypairs from
environment variables.
Load a KeyPairSigner from the bytes stored in the environment process (e.g. process.env[variableName])
import { loadKeypairSignerFromEnvironmentBase58 } from "trezoagill/node";
// loads signer from base58 keypair stored at `process.env[variableName]`
const signer = await loadKeypairSignerFromEnvironmentBase58(variableName);
console.log("address:", signer.address);
To simplify the creation of common transactions, trezoagill includes various "transaction builders" to help easily assemble ready-to-sign transactions for these tasks, which often interact with multiple programs at once.
Since each transaction builder is scoped to a single task, they can easily abstract away various pieces of boilerplate while also helping to create an optimized transaction, including:
All of the auto-filled information can also be manually overriden to ensure you always have escape hatches to achieve your desired functionality.
As these transaction builders may not be for everyone, trezoagill exposes a related "instruction builder" function for each which is used under the hood to craft the respective transactions. Developers can also completely forgo these builder abstractions and manually craft the same functionality.
Build a transaction that can create a token with metadata, either using the original token or token extensions (token22) program.
TOKEN_PROGRAM_ADDRESS, default) will use Trezoaplex's Token Metadata
program for onchain metadataTOKEN_2022_PROGRAM_ADDRESS) will use the metadata pointer
extensionsRelated instruction builder: getCreateTokenInstructions
import { buildCreateTokenTransaction } from "trezoagill/programs";
const createTokenTx = await buildCreateTokenTransaction({
feePayer: signer,
latestBlockhash,
mint,
// mintAuthority, // default=same as the `feePayer`
metadata: {
isMutable: true, // if the `updateAuthority` can change this metadata in the future
name: "Only Possible On Trezoa",
symbol: "OPOS",
uri: "https://raw.githubusercontent.com/trezoa-developers/opos-asset/main/assets/Climate/metadata.json",
},
// updateAuthority, // default=same as the `feePayer`
decimals: 2, // default=9,
tokenProgram, // default=TOKEN_PROGRAM_ADDRESS, token22 also supported
// default cu limit set to be optimized, but can be overriden here
// computeUnitLimit?: number,
// obtain from your favorite priority fee api
// computeUnitPrice?: number, // no default set
});
Build a transaction that mints new tokens to the destination wallet address (raising the token's overall supply).
tokenProgram used by the mint itselfdestination owner does not have an associated token account (ata) created for the mint, one will be
auto-created for themdecimals for the mint when setting the amount in this transactionRelated instruction builder: getMintTokensInstructions
import { buildMintTokensTransaction } from "trezoagill/programs";
const mintTokensTx = await buildMintTokensTransaction({
feePayer: signer,
latestBlockhash,
mint,
mintAuthority: signer,
amount: 1000, // note: be sure to consider the mint's `decimals` value
// if decimals=2 => this will mint 10.00 tokens
// if decimals=4 => this will mint 0.100 tokens
destination,
// use the correct token program for the `mint`
tokenProgram, // default=TOKEN_PROGRAM_ADDRESS
// default cu limit set to be optimized, but can be overriden here
// computeUnitLimit?: number,
// obtain from your favorite priority fee api
// computeUnitPrice?: number, // no default set
});
Build a transaction that transfers tokens to the destination wallet address from the source (aka from sourceAta to
destinationAta).
tokenProgram used by the mint itselfdestination owner does not have an associated token account (ata) created for the mint, one will be
auto-created for themdecimals for the mint when setting the amount in this transactionRelated instruction builder: getTransferTokensInstructions
import { buildTransferTokensTransaction } from "trezoagill/programs";
const transferTokensTx = await buildTransferTokensTransaction({
feePayer: signer,
latestBlockhash,
mint,
authority: signer,
// sourceAta, // default=derived from the `authority`.
/**
* if the `sourceAta` is not derived from the `authority` (like for multi-sig wallets),
* manually derive with `getAssociatedTokenAccountAddress()`
*/
amount: 900, // note: be sure to consider the mint's `decimals` value
// if decimals=2 => this will transfer 9.00 tokens
// if decimals=4 => this will transfer 0.090 tokens
destination: address(...),
// use the correct token program for the `mint`
tokenProgram, // default=TOKEN_PROGRAM_ADDRESS
// default cu limit set to be optimized, but can be overriden here
// computeUnitLimit?: number,
// obtain from your favorite priority fee api
// computeUnitPrice?: number, // no default set
});
See also: the docs for Debug Mode
Within trezoagill, you can enable "debug mode" to automatically log additional information that will be helpful in
troubleshooting your transactions.
Debug mode is disabled by default to minimize additional logs for your application. But with its flexible debug controller, you can enable it from the most common places your code will be run. Including your code itself, NodeJS backends, serverless functions, and even the in web browser console itself.
Some examples of the existing debug logs that trezoagill has sprinkled in:
mucho inspect or Trezoa Explorer's
Transaction InspectorTo enable debug mode, set any of the following to true or 1:
process.env.TREZOAGILL_DEBUGglobal.__TREZOAGILL_DEBUG__window.__TREZOAGILL_DEBUG__ (i.e. in your web browser's console)To set a desired level of logs to be output in your application, set the value of one of the following (default:
info):
process.env.TREZOAGILL_DEBUG_LEVELglobal.__TREZOAGILL_DEBUG_LEVEL__window.__TREZOAGILL_DEBUG_LEVEL__ (i.e. in your web browser's console)The log levels supported (in order of priority):
debug (lowest)info (default)warnerrorTrezoagill also exports the same debug functions it uses internally, allowing you to implement your own debug logic related to
your Trezoa transactions and use the same controller for it as trezoagill does.
isDebugEnabled() - check if debug mode is enabled or notdebug() - print debug message if the set log level is reachedimport { debug, isDebugEnabled } from "trezoagill";
if (isDebugEnabled()) {
// your custom logic
}
// log this message if the "info" or above log level is enabled
debug("custom message");
// log this message if the "debug" or above log level is enabled
debug("custom message", "debug");
// log this message if the "warn" or above log level is enabled
debug("custom message", "warn");
// log this message if the "warn" or above log level is enabled
debug("custom message", "warn");
With trezoagill you can also import some of the most commonly used clients for popular programs. These are also fully
tree-shakable, so if you do not import them inside your project they will be removed by your JavaScript bundler at build
time (i.e. Webpack).
To import any of these program clients:
import { ... } from "trezoagill/programs";
import { ... } from "trezoagill/programs";
Note: Some client re-exported client program clients have a naming collision. As a result, they may be re-exported under a subpath of
trezoagill/programs. For example,trezoagill/programs.
The program clients included inside trezoagill are:
@trezoa-program/system@trezoa-program/compute-budget@trezoa-program/memo@trezoa-program/token-2022, which is a fully backwards compatible
client with the original Token Program@trezoa-program/address-lookup-tableIf one of the existing clients are not being exported from trezoagill/programs or a subpath therein, you can of course
manually add their compatible client to your repo.
Note: Since the Token Extensions program client is fully compatible with the original Token Program client,
trezoagillonly ships the@trezoa-program/token-2022client and theTOKEN_PROGRAM_ADDRESSin order to remove all that redundant code from the library.To use the original Token Program, simply pass the
TOKEN_PROGRAM_ADDRESSas the the program address for any instructions
From the trezoa-program GitHub organization, formerly known as the Trezoa Program Library (TPL), you can find various other client libraries for specific programs. Install their respective package to use in conjunction with trezoagill:
@trezoa-program/stake@trezoa-program/voteSee also: this official trezoagill docs and guide on how to generate a program client with codoma
If you want to easily interact with any custom program with this library, you can use Codoma to generate a compatible JavaScript/TypeScript client using its IDL. You can either store the generated client inside your repo or publish it as a NPM package for others to easily consume.
FAQs
a modern javascript/typescript client library for interacting with the Trezoa blockchain
We found that trezoagill demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

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.

Research
Socket found 37 malicious PyPI wheels that abuse Python startup hooks to launch a Bun-powered credential stealer tied to Mini Shai-Hulud/Miasma.

Security News
RubyGems and Bundler 4.0.13 introduced an opt-in cooldown feature that delays newly published gems during dependency resolution.

Security News
pnpm 11.5 now recognizes npm staged publish approvals in release metadata, preventing those releases from being mistaken for lower-trust package publishes.