stas-token / stas-sdk

STAS token sdk
https://docs.stastoken.com/
MIT License
5 stars 0 forks source link

STAS-SDK Library

Property 1=Variant2 (2)

Overview

STAS Tokens are UTXO based smart contracts that have a variety of templates that can be used to create transactions for all types of specific use cases. STAS tokens are considered layer zero tokens as they are bound to the native satoshi value of the BSV blockchain. This library offers an effortless and user-friendly experience for interaction with UTXO blockchain that utilizes STAS tokens. STAS tokens are a growing list of UTXO-based smart contracts that can be employed for various transactions. The library is designed to provide functional neutrality for interaction with any STAS token type. Some examples include NFTs, Fungible tokens, Appendable tokens and more.

Features

 

STAS Templates

The library offers a variety of templates, each of which can be customized with any relevant data that may be necessary for your specific use case. This enables you to tailor your STAS token to your precise requirements. The following are the current implementation options that are available for use within the library.

 

Token Properties in Detail

A comprehensive table has been prepared to display all the characteristics and attributes of each token template script. This tool will be incredibly helpful in determining the most suitable token template to use for your particular needs. By referring to the table, you will be able to compare and contrast the various token templates, and ultimately make an informed decision on which one to select. This will ensure that you choose the token template that is best suited for your project and will help you achieve your desired outcome.

 

 

STAS Template Splittable MaxInputsPerTx MaxOutputsPerTx DataOutput Flags DataAppend RedeemAny SendToIssuerAddress RoyaltyPayment
STAS-20 true 2 4 true false false false true false
STAS-789 false 2 4 false false true true false false
STAS-50 true or false 2 50 false true false true false false
STAS (legacy) true or false 2 4 false true false true false false false

 

SDK Reference

The library is comprised of primary function files that are responsible for transaction creation. Each of these files contains three primary functions: sign, unsigned, and feeEstimate.

 

Installation

In this example we will set up a new folder to install and test the SDK. This will require Node.js to be installed.

 

  1. Create a new project directory: Open your terminal and navigate to the directory where you want to create your project. Then run the command mkdir mintTest to create a new directory for your project.

    mkdir mintTest

     

  2. Initialize a new Node.js project: Navigate into the new directory you just created using the command cd mintTest , and then run the command npm init -y. This will initialize a new Node.js project and create a package.json file that contains metadata about your project, such as its name, version, and dependencies.

    
     

cd mintTest npm init -y

 

3. Install required packages: In your project directory we will now install the stas and bsv libraries:

npm install bsv@1.5.6 npm install stas-sdk

 

4. Create an entry point file: In your project directory, create a new file called index.js. This will serve as the entry point for your application, where you can import the libraries and write your code.

ni index.js

 

5. Import required libraries: In your index.js file, import the required libraries using the require function. Here's an example:

const bsv = require('bsv'); const stas = require('stas-sdk');

// or to get single functions directly const {stasTransfer} = require('stas-sdk/index');

 

The imported stas library will contain all functions ready to be utilized by your application.

## Getting Started

To conduct testing, simply navigate to the tests folder. 

cd node_modules/stas-sdk/tests


Within this folder, you will find non-broadcasting examples, as well as various tools that can be utilized to test the mainnet and mint your initial tokens in a matter of minutes. All of these resources can be found within the /tests directory.

 

### Non broadcasting
When conducting non-broadcasting tests, the functions will leverage mock UTXO data in order to construct transactions via the library's functions. This approach is ideal for those who are just beginning to learn how the library and its functions operate. Through this process, you will be able to complete a full cycle of transactions, which will cover all of the functions within the library that involve the handling of STAS UTXOs.

 

To run a mock token mint test, while in the /test directory run this command in your terminal 

node nonBroadcastMint.js


 

To run a mock full cycle test, while in the /test directory run this command in your terminal 

node nonBroadcastFullCycleTest.js


Both of these test scripts will log transaction hexadeciamls to the console for example purposes only.

 

### Mint your first token

Here is a straightforward example that illustrates how you can mint your very first token. To begin, you will need to add your private key to the testUtility.js file. To obtain a new random private key simply run this command in the terminal while in the /tests directory

node getPrivateKey.js


 

 Upon doing so, you will see a corresponding address appear in the console. 

Address to send funds to: "some address " Funding Private Key: "some private key"

 In order to utilize this address for minting purposes, you will need to first send funds to it. Please note that a minimum of 5000 satoshis will be required in order to run the test, although only a fraction of this amount will actually be used in the mint example. Please be sure to keep a copy of this private key if you still have funds that you would like to recover in the future. At any time you would like to withdraw the funds from the test address please refer to the /tests/getFundsFromAddress.js file and follow the instructions.

  

To proceed, take the private key string and replace the two values in the testUtility.js file. In this example, you can use the same private key for both variables on lines 11 and 16

this.privateKey = bsv.PrivateKey.fromString('Enter Funding Private Key Here'); this.issuerPrivateKey = bsv.PrivateKey.fromString('Enter Funding Private Key Here');

Please be sure to keep a copy of this private key if you still have funds that you would like to recover in the future. At any time you would like to withdraw the funds from the test address please refer to the /tests/getFundsFromAddress.js file and follow the instructions.

 

Now we are ready to test!
Simply, while in the /test directory you can run this command in the terminal

node instantMint.js

The process will start and the token will be minted onchain with all Txids provided. 

Starting Instant Mint Example... Fetching UTXO from the blockchain... Building transactions... Prepare Utxos Txid: 31fa389bec5677c048e6a5539467dda02da576427f8bbccb22fcb2250cd601ec Contract Txid: 81bbdce661ea6b0133e8073a48b8334658bf6151d08cb8061d4a106175a095fb Issue Txid: 7b678504f67fc87e93ddd6816800d73915cd43a09ad2a53d177cc539b3f8c233 Redeem Txid: c7951ceb0bb8fd712e2e993a022d7d37c23a65a779477e5e80694640e6d9cb45 Instant Mint Example Completed


 

### Minting Tokens in Detail

To mint tokens, two transaction building functions - Contract and Issuance - are needed. The Contract transaction generates a JSON output that defines the token properties and metadata, and includes all the satoshis necessary for the token issuance transaction. The Issuance transaction spends the Contract UTXO as input and adds token scripts as outputs, effectively linking the contract metadata to the issuance transaction, resulting in the creation of the tokens.

### Contract

To generate a Contract transaction, a JSON object containing token information is necessary. You can find a template of this JSON object in tokenSchemaTemplate.js.

const tokenSchemaTemplate = { name: "Test Token", protocolId: "STAS-20", symbol: "TESTTOKEN001", // REQUIRED description: "This is a test token", image: "Some Image URL", totalSupply: 10, // REQUIRED decimals: 0, satsPerToken: 1, // REQUIRED properties: { legal: { terms: "STAS, Inc. retains all rights to the token script. Use is subject to terms at https://stastoken.com/license.", licenceId: "stastoken.com" }, issuer: { organisation: "string", legalForm: "string", governingLaw: "string", issuerCountry: "string", jurisdiction: "string", email: "string" }, meta: { schemaId: "STAS1.0", website: "string", legal: { terms: "string" }, media: [ { URI: "string", type: "string", altURI: "string" } ] } }, }


The contractUtxo holds the satoshis that will fund the token supply. The satoshi amount in the contractUtxo must meet a minimum requirement for the token(s) being minted, and any extra satoshis will be returned to the issuer address in the form of a change output. 
The paymentUtxo is used to cover the transaction fees for the transaction.
You can pass in the tokenSchema as a JSON object, which will be added to the transaction output.
The token satoshis refer to the total amount of satoshis utilized in the token supply.

const contractTx = await stasContract.signed( issuerPrivateKey, contractUtxo, paymentUtxo, paymentPrivateKey, tokenSchema, tokenSatoshis )


After executing the function, you will receive a transaction object representation. To convert to hexadecimal simply add "toString()", and is now ready to be broadcasted to the miner.

You need to use the contract output #0 UTXO in the issuance function. The utility.js file includes a helper function that retrieves a UTXO object from a transaction hex. This function takes the transaction and output index value as arguments.

const stas = require('stas-sdk') const {utility} = stas

const contractUtxo = utility.getUtxoFromTx(contractTx, 0)


### Issuance

The issuance function is responsible for generating the transaction that issues the tokens. You can set any amount of satoshis per token during issuance. However, the library will verify that the total token supply and the satoshis per token correspond to the value in the contract UTXO. 

Tokens can be issued as single or multiple outputs, in the case of splittable tokens. However, for non-splittable tokens, each token will be issued as a separate output since they cannot be divided or combined with other scripts of the same data value.

#### IssueData
Issue data will contain 3 elements : 
1. addr - this is the address string that will receive the tokens on issuance
2. satoshsis - the amount of tokens in satoshis the address owner will receive
3. data - an array of strings that will be converted to hexadecimal format and added to the script as meta data.

 

#### OP CODES
Within the data array, we allocate specific string values for OP CODES to serve a special purpose. These string values correspond to the hexadecimal representation of the respective OP CODES, enabling the inclusion of Bitcoin script within the token metadata. For easy reference, you can find the hexadecimal representations of all OP CODES in the constants.js file.

Example

const data = ["OP_RETURN", "OP_FALSE", "OP_IF"] //converts to asm in hex OP CODE representation const asm = 6a 00 63


 

If wanting to add OP CODES as literal strings to the meta data you can do the following

const data = ["OP_RETURN OP_FALSE OP_IF"] //converts to asm as per normal plain text to hex value const asm = 4f505f52455455524e204f505f46414c5345204f505f4946


 

Here is an example of the issue data array.

const issueInfo = [ { addr: "Some address string", satoshis: 100, data: ['STAS CUSTOM DATA', 'STAS CUSTOM DATA 2', 'STAS CUSTOM DATA 3'] } ]


In this example, we are issuing 100 tokens to a single address and incorporating three custom data elements into the token script. The data field can accept an array consisting of string values. Each element of the array will be transformed into a hexadecimal data chunk and appended to the token script in ASM format. This method facilitates the separation of each data element with a space while in ASM format.

We can also distribute tokens to multiple addresses, as illustrated in the following example:

const issueInfo = [ { addr: "Some address string ONE ", satoshis: 50, data: ['STAS CUSTOM DATA', 'STAS CUSTOM DATA 2', 'STAS CUSTOM DATA 3'] }, { addr: "Some address string TWO", satoshis: 50, data: ['STAS CUSTOM DATA', 'STAS CUSTOM DATA 2', 'STAS CUSTOM DATA 3'] } ]


IMPORTANT : It's crucial to note that when issuing splittable tokens and intending to merge them later using the merge and mergeSplit functions, the custom data must be identical across all tokens outputs in the issueInfo array. The UTXO scripts of tokens can only be merged if their data matches precisely. If the tokens will not be combined in the future, you may issue them with varying custom data. To restrict the merging capability of tokens for future use cases, consider issuing non-splittable token types since these cannot be merged on a script level. To learn more about splittable and non-splittable tokens, as well as additional information about available token templates, please refer to the Token Properties in Detail section.

When using non-splittable tokens, it is essential to ensure that the token supply and the satoshis per token match the number of outputs in the issuance transaction. Below is an example that illustrates this:

const issueInfo = [ { addr: "Some address string ONE ", satoshis: 1, data: ['STAS CUSTOM DATA FOR NFT1', 'STAS CUSTOM DATA 2 FOR NFT1', 'STAS CUSTOM DATA 3 FOR NFT1'] }, { addr: "Some address string TWO", satoshis: 1, data: ['STAS CUSTOM DATA FOR NFT2', 'STAS CUSTOM DATA 2 FOR NFT2', 'STAS CUSTOM DATA 3 FOR NFT2'] }, { addr: "Some address string THREE", satoshis: 1, data: ['STAS CUSTOM DATA FOR NFT3', 'STAS CUSTOM DATA 2 FOR NFT3', 'STAS CUSTOM DATA 3 FOR NFT3'] }, { ... }, ... ]


In this example we are creating multiple tokens with unique custom data added for each output. 

The issuerPrivateKey will sign for the contractUtxo, and a paymentUtxo is added to pay the transaction fees along with the corresponding private key. The final function arguments are as follows:

isSplittable  : is a boolean value that is only necessary for token templates that have flags indicating whether the token can be splittable or non-splittable. This is applicable to protocol types such as "STAS" or "STAS-50". However, for token templates that do not have such flags, this argument is not relevant and can be ignored by passing undefined in its place.

symbol : is a string value representing the token symbol. For it to be considered valid, it must match the tokenId field specified in the contract token schema JSON.

protocol : represents the token template used to issue the token and must be a string value, such as "STAS-20" or "STAS-789".

const issuanceTx = await stasIssuace.signed( issuerPrivateKey, issueData, contractUtxo, paymentUtxo, paymentPrivateKey, isSplittable, symbol, protocol )

After executing the function, you will receive a transaction object representation. To convert to hexadecimal simply add "toString()", and is now ready to be broadcasted to the miner.

## Transaction examples

In the following examples, we will demonstrate how to employ the functions and the format in which the arguments are needed. UTXOs, in general, will employ a standardized format across the library. This format will consist of an object encompassing the following four fields:

const utxo = { txid : string, satoshis : number, vout : number, script : string, // hexadecimal representation }


 

### Transfer
To begin, let us examine the transfer function, which is used to generate a transaction hexadecimal that will allow you to send STAS tokens to another designated address. Once you have successfully completed the installation process, you will be able to access the SDK functions.

To utilize the transfer function, it is necessary to first prepare some UTXOs. Specifically, you will need a stasUtxo, which will be the STAS token utilized in the transfer, as well as a paymentUtxo, which will provide funding for the transaction fees.

Both UTXOs will require private keys to be supplied, although it is possible to use the same private keys for both, if applicable. Finally, you will need to input the destination address string to complete the process.

const transferTx = await stasTransfer.signed( ownerPrivatekey, stasUtxo, destinationAddress, paymentUtxo, paymentPrivateKey)

After executing the function, you will receive a transaction object representation. To convert to hexadecimal simply add "toString()", and is now ready to be broadcasted to the miner.

 
### Split
Similar to the transfer function, this particular function generates transaction that can distribute tokens to multiple addresses at once. It should be noted that this function is only applicable to tokens that have the splittable property set to true. For more details on which token templates possess this attribute, please refer to the STAS features table.

To create a split transaction, we need a STAS UTXO, a fee UTXO, and the private keys linked with these UTXOs. Instead of the destination address required in the transfer function, we need an array that contains all the destination addresses and their corresponding amounts.

The splitDestinations array is made up of objects that contain two fields. Please keep in mind that the sum of the outputs' amounts must match the amount in the STAS UTXO input to ensure a valid transaction is created.

const splitDestinations = [ { satoshis : 10, address : "someAddressString" }, { satoshis : 10, address : "someOtherAddressString" } ]


 

It should be noted that if the token owner needs to receive change from the STAS UTXO input, it must be included in the splitDestination array. The total amount in the outputs of the array should match the input satoshis amount.

const splitTx = await stasSplit.signed( ownerPrivatekey, stasUtxo, splitDestinations, paymentUtxo, paymentPrivateKey)

After executing the function, you will receive a transaction object representation. To convert to hexadecimal simply add "toString()", and is now ready to be broadcasted to the miner.

 

### Merge
With the merge function, it is possible to combine two STAS UTXO inputs into one output. However, please keep in mind that this function can only be used by tokens that have the splittable property set to true. For more information on which token templates have this property, please consult the STAS features table.

Merging can also only occur for STAS UTXOs that contain identical script values. 

The merge function has different parameters compared to the split or transfer functions. It necessitates the previous transaction hex value of the UTXOs being merged, and the required format is as follows:

const stasInput1 = { txHex : 'previous transaction hex string', vout : 'output index of the UTXO being spent' }

const stasInput2 = { txHex : 'previous transaction hex string', vout : 'output index of the UTXO being spent' }


 

The previous transaction hex is required as part of the unlocking script to complete the merge functionality.
To create a merge transaction, the following additional parameters are necessary: private keys for both UTXO inputs, a destination address, and the payment UTXO and its corresponding private key.

const mergeTx = await stasMerge.signed( ownerPrivateKey1, stasInput1, ownerPrivateKey2, stasInput2, destinationAddr, paymentPrivateKey, paymentUtxo)

After executing the function, you will receive a transaction object representation. To convert to hexadecimal simply add "toString()", and is now ready to be broadcasted to the miner.

NOTE: It is important to keep in mind that the size of the merge transaction will increase after each subsequent merge transaction due to its design nature. To optimize the transaction size, it is recommended to consider ways to mitigate the compounding effects of the data size. One possible solution is to use interval transfer functions for each UTXO being merged, which resets the previous transaction hexadecimal to the size of a transfer transaction. It is recommended to transfer the UTXO after every two merge transactions as a means of resetting the transaction size before continuing with additional merge transactions.

The MergeSplit function works in a similar way to merge, with the exception that instead of a single destination address, it accepts an array of splitDestinations, just like in the split function.

 

### Redeem
Token redemption refers to the process of converting the STAS token satoshis back into native BSV satoshis, which essentially destroys the STAS token. To perform this operation, a single STAS UTXO input is required, and the resulting output is in the form of a regular pay-to-public-key-hash output. By default, the unlocked satoshis are always sent to the issuer address of the token, which is known as the redemption address and can be found in the token script as the first element after the OP_RETURN.

This function will take the typical arguments as follows:

const redeemTx = await stasRedeem.signed( ownerPrivateKey, stasUtxo, paymentUtxo, paymentPrivateKey)

After executing the function, you will receive a transaction object representation. To convert to hexadecimal simply add "toString()", and is now ready to be broadcasted to the miner.

The RedeemSplit function is designed to operate similarly to the redeem function, with an added parameter called "splitDestinations". This parameter specifies where the additional outputs of the transaction will be directed, much like the split function. It's worth noting that the total amount designated for split destinations will determine the number of satoshis redeemed from the STAS UTXO input. For example, if the STAS UTXO input contains 10 satoshis and the total output amount in the split destination array is 8, only 2 satoshis will be redeemed. The remaining satoshis will remain locked in STAS tokens and be sent to the new destination address(es).

 

## Atomic Swaps
The process of atomic swaps entails the utilization of partially signed components from both parties, and completion occurs only after both parties have signed all the necessary pieces. With this SDK, there are two methods available to accomplish an atomic swap transaction: a two-step and a three-step approach.

To begin with, let's examine the two-step method provided by the SDK, which involves utilizing two functions, namely "stasCreateSwap" and "stasAcceptSwap."

 

### Two step swap
The stasCreateSwap function requires the user to input a UTXO that they are willing to swap for something else, which can either be a STAS token or native BSV. The user must also specify the output they desire to receive as a result of the atomic swap transaction, which can also be either a STAS token or native BSV output.

 

To define the output, the SDK utilizes an object known as wantedData, which comprises the following fields:

const wantedData = { satoshis : number script : scriptHex // optional if STAS script }


 

In the event that only the value of the satoshis field is provided, stasCreateSwap will create a native BSV output to the address from input #0. However, if the user desires a specific STAS token for the atomic swap, the script field must be supplied with the hexadecimal representation of the token script.

const offerHex = await stasCreateSwap.signed( ownerPrivateKey, utxo, wantedData )


 

The subsequent step involves finalizing the atomic swap transaction by adding the remaining inputs and information required to generate the unlocking scripts. In the stasAcceptSwap function, the following core arguments are required, and we will examine each one in this example:

 

offerTxHex: This represents the hexadecimal form of the transaction from the stasCreateSwap function.
ownerPrivateKey: This refers to the private key of the UTXO's owner who is participating in the atomic swap transaction.
makerInputTxHex: This denotes the complete transaction hexadecimal of the input #0 in the offerTxHex.
takerInputTxHex: This represents the complete transaction hexadecimal of the UTXO that is being utilized to complete the atomic swap transaction.
takerVout: This refers to the output index of the UTXO being used to complete the atomic swap transaction.
paymentPrivateKey: This denotes the private key of the UTXO's owner who is paying the transaction fee.
paymentUtxo: This represents the UTXO that is being used to pay the transaction fee.

 

const swapTx = stasAcceptSwap.signed( offerTxHex, ownerPrivateKey, makerInputTxHex, takerInputTxHex, takerVout, paymentPrivateKey, paymentUtxo, additionalOutputs // optional )


 

more on additionalOutputs soon...
After executing the function, you will receive a transaction object representation. To convert to hexadecimal simply add "toString()", and is now ready to be broadcasted to the miner. The final outcome of the transaction will be that input #0 will transfer ownership to output #1, while input #1 will transfer ownership to output #0, in accordance with the terms of the atomic swap transaction.

 

### Three step swap

To make this a three step swap we can simply create the offer hex with the unsigned function call as follows:

 

const unsignedOfferTx = await stasCreateSwap.unSigned( ownerPublicKey, utxo, wantedData )

When the unsigned function call is made, the returned object will contain the transaction in the "tx" field, which can be converted to a string to obtain the hexadecimal format. In this scenario, input #0 will not be signed. After the stasAcceptOffer function has returned the "swapHex" value, it can then be used to sign the transaction and send it back to the offer hex creator.

 

An additional argument must be included, which is the complete transaction hexadecimal representation of the taker, which corresponds to input #1 in the unsigned swap hexadecimal.

const signedSwapTx = await stasSignSwap.signed( unSignedSwapHex, ownerPrivateKey, takerInputTx )

After executing the function, you will receive a transaction object representation. To convert to hexadecimal simply add "toString()", and is now ready to be broadcasted to the miner.
 

### Additional outputs for atomic swaps
During the second step of the atomic swap transaction, it is possible to include additional outputs. This can be accomplished by adding an array as an additional function argument to specify the amounts and addresses to which the extra funds will be sent. It is important to note that for additional outputs, the funds must originate from input #1 UTXO in the atomic swap.
Consider the following example:

 

Output #0 requests 1000 Native satoshis  

const wantedData = { satoshis: 1000 }


 

Addtional outputs are added as follows: 

const additionalOutputs = [ { address : "some address string", satoshis : 1000 }, { address : "some address string", satoshis : 1000 } ]


In this case the input #1 needs to contain exactly 3000 in native satoshis to complete this transaction. This can also be done using STAS tokens where the properties of the token is splittable.

 

## Advanced features

In this section we will go over some of the advanced transaction building features that are available in the library. 

### Data 
Certain token templates allow for data to be incorporated into transactions in varying ways. In order to maintain a universal format, the data format will always employ an array format. Each element within the array will be regarded as a single script chunk, and all data will be provided as plain text strings. Let us explore some examples of how we can leverage this feature in some of the token templates.

## OP CODES
As per the same as the issuance function, OP CODE strings are reserved to allow for Bitcoin script to be added into the token meta data. Please refer to the issuance section for more details.

 

### STAS-20 data output
The STAS-20 token template permits an optional extra output in each transaction, which is always positioned as the last output even after the payment change output. All transactional functions in the STAS library contain the "data" argument. To incorporate this additional output, we can easily provide this value as an argument in the function, as shown below:

const data = [ "Some plain text string", "Some other plain text string" ]

const transferTx = await stasTransfer.signed( ownerPrivatekey, stasUtxo, destinationAddress, paymentUtxo, paymentPrivateKey, data )

In this instance, the stasTransfer function is being utilized. An additional parameter can be included in the function if an extra output is needed in the transaction. If no data output is necessary, this parameter can be disregarded. The array can contain numerous elements, but it's important to note that the data's maximum size must not surpass 63337 bytes.

 

### STAS-789 data append
The STAS-789 template possesses a distinctive capability to append additional data to the token script when executing a transfer transaction. The data that previously resided in the script cannot be altered and is immutable. This is an optional feature and not necessary for token transfers. To include additional data, the stasTransfer function must be supplied with the data in array format.

const data = [ "Some plain text string", "Some other plain text string" ]

const transferTx = await stasTransfer.signed( ownerPrivatekey, stasUtxo, destinationAddress, paymentUtxo, paymentPrivateKey, data )

Subsequently, the transaction output will contain the supplementary data in the script. Each element in the data array will be converted into data script chunks in ASM format. By including the data in chunks, we can introduce new OP CODES or other data that may be supported in applications that adhere to the data format.

 

### Fee Estimates
As the name suggests, fee estimation functions offer a means of computing the expense of a STAS transaction before officially constructing it. This is accomplished using the minimum necessary arguments, which creates a transaction template that can then be used to determine the cost in satoshis based on the fee rate. The fee rate settings can be located in the utility.js file as follows:

this.SATS = 50 this.PERBYTE = 1000


 

Here is an example of using the fee estimate functions for the stasTransfer Function : 

const feeEstimate = await stasTransfer.feeEstimate(stasUtxo)


 

The function will return a number in satoshi value that can then be used for pre processing conditions where UTXOs for fees are required to be prepared beforehand.
 

### ZeroChange 
Zero change transaction building is an excellent resource for developers who wish to construct STAS transactions without any change outputs. An instance of this model is when the payment UTXOs for the transactions are prearranged. By incorporating this model in conjunction with fee estimation functions, developers can minimize chained UTXO transactions by determining the exact fee amount requirement ahead of time, allowing them to create the appropriate size UTXO for the fee payment without the need to handle UTXOs afterwards as part of further fee UTXOs. This is especially handy for instances where multiple fee UTXOs are required for multiple transactions at once.

To use the zero change model in the functions it requires an arguement boolean set to true. Here is an example in the stasTransfer function 

const transferTx = await stasTransfer.signed( ownerPrivatekey, stasUtxo, destinationAddress, paymentUtxo, paymentPrivateKey, undefined|data, true )

We can observe that the final argument in the stasTransfer function is set to "true". This allows for the transfer to be conducted utilizing the zero change model. It's important to note that the second-to-last argument in the function must be set to either "undefined" or, if data is required, added in as demonstrated in the preceding examples regarding data additions.

Utilizing the zero change model also involves a fallback to ensure that no significant excess in satoshis goes unaccounted for in the change output. The parameters for the zero change model can be located in the utility.js file as depicted below:

this.ZEROCHANGETHRESHOLD = 10

In this instance, if the change amount surpasses 10 satoshis, an error will be thrown, and the transaction build will not be completed. The zero change model is intended to be utilized alongside fee estimation functions to yield optimal results with minimal satoshi wastage, and to decrease the handling of excess change UTXOs when they are not required.

 

### ZeroFee (currently not supported by existing miners)
Zero fee will create the transaction without any payment input UTXO or change output UTXO. This model is currently not supported by any existing miners. 
hex
 

### unSigned 
The unsigned features for the functions are the most advanced feature available in the library. It will create unsigned versions of the transactions and return an array of unsigned data for each input in the transaction that is not yet signed. This feature is designed to be used for wallets that may require external signatures such as web browser wallets.
The current format of data returned by this function is as follows :

const unsignedTxInfo = { unsignedData : [] - array of objects for each input in the transaction tx : tx - whole transaction object }

unsignedData = [{ inputIndex : number - index of the input being signed satoshis : number - satoshi converted to BN script : string - script buffer of the input sighash : number - sighash flags for the input, publicKeyString : string - public key string of the input stas : boolean - indicating whether the input is stas type or not }]


The unsigned data can be used in conjunction with the BSV library to construct a valid signature for the input(s). 

## Contributing
We welcome contributions to the library from anyone in the community. If you have found a bug, have a feature request, or would like to submit a pull request, please follow the guidelines below:

Bug Reports
If you have found a bug in the library, please report it by opening an issue on our GitHub repository. Please provide as much detail as possible, including steps to reproduce the issue and any relevant error messages.

Feature Requests
If you have a feature request for the library, please open an issue on our GitHub repository and describe the feature you would like to see. We value your feedback and will consider it as we plan future releases.

Pull Requests
If you would like to contribute code to the library, please submit a pull request on our GitHub repository. Before submitting a pull request, please ensure that your code adheres to our coding standards and that all tests pass. We will review your pull request as soon as possible and provide feedback if necessary.

Thank you for your interest in contributing to the library!

## Credits
The following individuals and organizations have contributed to the development of the library:

Cain Nussdorfer - author, reviewer and maintainer
Manoj Singh - contributor, reviewer and maintainer
Aditya Panther - contributor, reviewer and maintainer
Viral Bhadeshiya - contributor, reviewer and maintainer

We would like to express our sincere gratitude to these individuals and companies for their contributions and support, which have helped make this library a valuable resource for the community.