|
|
|
@@ -1,84 +1,84 @@
|
|
|
|
import { Buffer, IntegerType, intToBigInt } from '@stacks/common';
|
|
|
|
import { Buffer, fetchPrivate, IntegerType, intToBigInt } from '@stacks/common';
|
|
|
|
import { StacksTransaction } from './transaction';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import { StacksNetwork, StacksMainnet, StacksTestnet } from '@stacks/network';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import {
|
|
|
|
import {
|
|
|
|
createTokenTransferPayload,
|
|
|
|
IStacksNetwork,
|
|
|
|
createSmartContractPayload,
|
|
|
|
StacksMainnet,
|
|
|
|
createContractCallPayload,
|
|
|
|
StacksNetwork,
|
|
|
|
serializePayload,
|
|
|
|
StacksNetworkName,
|
|
|
|
Payload,
|
|
|
|
StacksTestnet,
|
|
|
|
} from './payload';
|
|
|
|
} from '@stacks/network';
|
|
|
|
|
|
|
|
import { c32address } from 'c32check';
|
|
|
|
import {
|
|
|
|
import {
|
|
|
|
createSingleSigSpendingCondition,
|
|
|
|
|
|
|
|
createMultiSigSpendingCondition,
|
|
|
|
createMultiSigSpendingCondition,
|
|
|
|
|
|
|
|
createSingleSigSpendingCondition,
|
|
|
|
createSponsoredAuth,
|
|
|
|
createSponsoredAuth,
|
|
|
|
createStandardAuth,
|
|
|
|
createStandardAuth,
|
|
|
|
} from './authorization';
|
|
|
|
} from './authorization';
|
|
|
|
|
|
|
|
import { ClarityValue, PrincipalCV } from './clarity';
|
|
|
|
import {
|
|
|
|
|
|
|
|
publicKeyToString,
|
|
|
|
|
|
|
|
createStacksPrivateKey,
|
|
|
|
|
|
|
|
getPublicKey,
|
|
|
|
|
|
|
|
publicKeyToAddress,
|
|
|
|
|
|
|
|
pubKeyfromPrivKey,
|
|
|
|
|
|
|
|
publicKeyFromBuffer,
|
|
|
|
|
|
|
|
createStacksPublicKey,
|
|
|
|
|
|
|
|
} from './keys';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import { TransactionSigner } from './signer';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import {
|
|
|
|
|
|
|
|
createSTXPostCondition,
|
|
|
|
|
|
|
|
createFungiblePostCondition,
|
|
|
|
|
|
|
|
createNonFungiblePostCondition,
|
|
|
|
|
|
|
|
} from './postcondition';
|
|
|
|
|
|
|
|
import {
|
|
|
|
|
|
|
|
PostCondition,
|
|
|
|
|
|
|
|
STXPostCondition,
|
|
|
|
|
|
|
|
FungiblePostCondition,
|
|
|
|
|
|
|
|
NonFungiblePostCondition,
|
|
|
|
|
|
|
|
} from './postcondition-types';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import {
|
|
|
|
import {
|
|
|
|
AddressHashMode,
|
|
|
|
AddressHashMode,
|
|
|
|
AddressVersion,
|
|
|
|
AddressVersion,
|
|
|
|
|
|
|
|
AnchorMode,
|
|
|
|
FungibleConditionCode,
|
|
|
|
FungibleConditionCode,
|
|
|
|
NonFungibleConditionCode,
|
|
|
|
NonFungibleConditionCode,
|
|
|
|
PostConditionMode,
|
|
|
|
|
|
|
|
PayloadType,
|
|
|
|
PayloadType,
|
|
|
|
AnchorMode,
|
|
|
|
PostConditionMode,
|
|
|
|
|
|
|
|
SingleSigHashMode,
|
|
|
|
TransactionVersion,
|
|
|
|
TransactionVersion,
|
|
|
|
TxRejectedReason,
|
|
|
|
TxRejectedReason,
|
|
|
|
SingleSigHashMode,
|
|
|
|
|
|
|
|
} from './constants';
|
|
|
|
} from './constants';
|
|
|
|
|
|
|
|
import { ClarityAbi, validateContractCall } from './contract-abi';
|
|
|
|
|
|
|
|
import {
|
|
|
|
|
|
|
|
createStacksPrivateKey,
|
|
|
|
|
|
|
|
createStacksPublicKey,
|
|
|
|
|
|
|
|
getPublicKey,
|
|
|
|
|
|
|
|
pubKeyfromPrivKey,
|
|
|
|
|
|
|
|
publicKeyFromBuffer,
|
|
|
|
|
|
|
|
publicKeyToAddress,
|
|
|
|
|
|
|
|
publicKeyToString,
|
|
|
|
|
|
|
|
} from './keys';
|
|
|
|
|
|
|
|
import {
|
|
|
|
|
|
|
|
createContractCallPayload,
|
|
|
|
|
|
|
|
createSmartContractPayload,
|
|
|
|
|
|
|
|
createTokenTransferPayload,
|
|
|
|
|
|
|
|
Payload,
|
|
|
|
|
|
|
|
serializePayload,
|
|
|
|
|
|
|
|
} from './payload';
|
|
|
|
|
|
|
|
import {
|
|
|
|
|
|
|
|
createFungiblePostCondition,
|
|
|
|
|
|
|
|
createNonFungiblePostCondition,
|
|
|
|
|
|
|
|
createSTXPostCondition,
|
|
|
|
|
|
|
|
} from './postcondition';
|
|
|
|
|
|
|
|
import {
|
|
|
|
|
|
|
|
AssetInfo,
|
|
|
|
|
|
|
|
createContractPrincipal,
|
|
|
|
|
|
|
|
createStandardPrincipal,
|
|
|
|
|
|
|
|
FungiblePostCondition,
|
|
|
|
|
|
|
|
NonFungiblePostCondition,
|
|
|
|
|
|
|
|
PostCondition,
|
|
|
|
|
|
|
|
STXPostCondition,
|
|
|
|
|
|
|
|
} from './postcondition-types';
|
|
|
|
|
|
|
|
import { TransactionSigner } from './signer';
|
|
|
|
|
|
|
|
import { StacksTransaction } from './transaction';
|
|
|
|
import { createLPList } from './types';
|
|
|
|
import { createLPList } from './types';
|
|
|
|
import { AssetInfo, createStandardPrincipal, createContractPrincipal } from './postcondition-types';
|
|
|
|
import { cvToHex, omit, parseReadOnlyResponse, validateTxId } from './utils';
|
|
|
|
|
|
|
|
|
|
|
|
import { cvToHex, parseReadOnlyResponse, omit, validateTxId } from './utils';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import { fetchPrivate } from '@stacks/common';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import { ClarityValue, PrincipalCV } from './clarity';
|
|
|
|
|
|
|
|
import { validateContractCall, ClarityAbi } from './contract-abi';
|
|
|
|
|
|
|
|
import { c32address } from 'c32check';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Lookup the nonce for an address from a core node
|
|
|
|
* Lookup the nonce for an address from a core node
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @param {string} address - the c32check address to look up
|
|
|
|
* @param {string} address - the c32check address to look up
|
|
|
|
* @param {StacksNetwork} network - the Stacks network to look up address on
|
|
|
|
* @param {StacksNetworkName | IStacksNetwork} network - the Stacks network to look up address on
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @return a promise that resolves to an integer
|
|
|
|
* @return a promise that resolves to an integer
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
export async function getNonce(address: string, network?: StacksNetwork): Promise<bigint> {
|
|
|
|
export async function getNonce(
|
|
|
|
|
|
|
|
address: string,
|
|
|
|
|
|
|
|
network?: StacksNetworkName | IStacksNetwork
|
|
|
|
|
|
|
|
): Promise<bigint> {
|
|
|
|
const defaultNetwork = new StacksMainnet();
|
|
|
|
const defaultNetwork = new StacksMainnet();
|
|
|
|
const url = network
|
|
|
|
const url = network
|
|
|
|
? network.getAccountApiUrl(address)
|
|
|
|
? StacksNetwork.fromNameOrNetwork(network).getAccountApiUrl(address)
|
|
|
|
: defaultNetwork.getAccountApiUrl(address);
|
|
|
|
: defaultNetwork.getAccountApiUrl(address);
|
|
|
|
|
|
|
|
|
|
|
|
const response = await fetchPrivate(url);
|
|
|
|
const response = await fetchPrivate(url);
|
|
|
|
if (!response.ok) {
|
|
|
|
if (!response.ok) {
|
|
|
|
let msg = '';
|
|
|
|
let msg = '';
|
|
|
|
@@ -100,13 +100,13 @@ export async function getNonce(address: string, network?: StacksNetwork): Promis
|
|
|
|
* Estimate the total transaction fee in microstacks for a token transfer
|
|
|
|
* Estimate the total transaction fee in microstacks for a token transfer
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @param {StacksTransaction} transaction - the token transfer transaction to estimate fees for
|
|
|
|
* @param {StacksTransaction} transaction - the token transfer transaction to estimate fees for
|
|
|
|
* @param {StacksNetwork} network - the Stacks network to estimate transaction for
|
|
|
|
* @param {StacksNetworkName | IStacksNetwork} network - the Stacks network to estimate transaction for
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @return a promise that resolves to number of microstacks per byte
|
|
|
|
* @return a promise that resolves to number of microstacks per byte
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
export async function estimateTransfer(
|
|
|
|
export async function estimateTransfer(
|
|
|
|
transaction: StacksTransaction,
|
|
|
|
transaction: StacksTransaction,
|
|
|
|
network?: StacksNetwork
|
|
|
|
network?: StacksNetworkName | IStacksNetwork
|
|
|
|
): Promise<bigint> {
|
|
|
|
): Promise<bigint> {
|
|
|
|
if (transaction.payload.payloadType !== PayloadType.TokenTransfer) {
|
|
|
|
if (transaction.payload.payloadType !== PayloadType.TokenTransfer) {
|
|
|
|
throw new Error(
|
|
|
|
throw new Error(
|
|
|
|
@@ -125,10 +125,9 @@ export async function estimateTransfer(
|
|
|
|
headers: requestHeaders,
|
|
|
|
headers: requestHeaders,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const defaultNetwork = new StacksMainnet();
|
|
|
|
const derivedNetwork = network ?? deriveNetwork(transaction);
|
|
|
|
const url = network
|
|
|
|
const url = StacksNetwork.fromNameOrNetwork(derivedNetwork).getTransferFeeEstimateApiUrl();
|
|
|
|
? network.getTransferFeeEstimateApiUrl()
|
|
|
|
|
|
|
|
: defaultNetwork.getTransferFeeEstimateApiUrl();
|
|
|
|
|
|
|
|
const response = await fetchPrivate(url, fetchOptions);
|
|
|
|
const response = await fetchPrivate(url, fetchOptions);
|
|
|
|
if (!response.ok) {
|
|
|
|
if (!response.ok) {
|
|
|
|
let msg = '';
|
|
|
|
let msg = '';
|
|
|
|
@@ -169,14 +168,14 @@ interface FeeEstimateResponse {
|
|
|
|
* @param {number} estimatedLen - is an optional argument that provides the endpoint with an
|
|
|
|
* @param {number} estimatedLen - is an optional argument that provides the endpoint with an
|
|
|
|
* estimation of the final length (in bytes) of the transaction, including any post-conditions
|
|
|
|
* estimation of the final length (in bytes) of the transaction, including any post-conditions
|
|
|
|
* and signatures
|
|
|
|
* and signatures
|
|
|
|
* @param {StacksNetwork} network - the Stacks network to estimate transaction fees for
|
|
|
|
* @param {StacksNetworkName | IStacksNetwork} network - the Stacks network to estimate transaction fees for
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @return a promise that resolves to FeeEstimate
|
|
|
|
* @return a promise that resolves to FeeEstimate
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
export async function estimateTransaction(
|
|
|
|
export async function estimateTransaction(
|
|
|
|
transactionPayload: Payload,
|
|
|
|
transactionPayload: Payload,
|
|
|
|
estimatedLen?: number,
|
|
|
|
estimatedLen?: number,
|
|
|
|
network?: StacksNetwork
|
|
|
|
network?: StacksNetworkName | IStacksNetwork
|
|
|
|
): Promise<[FeeEstimation, FeeEstimation, FeeEstimation]> {
|
|
|
|
): Promise<[FeeEstimation, FeeEstimation, FeeEstimation]> {
|
|
|
|
const options = {
|
|
|
|
const options = {
|
|
|
|
method: 'POST',
|
|
|
|
method: 'POST',
|
|
|
|
@@ -188,9 +187,8 @@ export async function estimateTransaction(
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const defaultNetwork = new StacksMainnet();
|
|
|
|
const defaultNetwork = new StacksMainnet();
|
|
|
|
|
|
|
|
|
|
|
|
const url = network
|
|
|
|
const url = network
|
|
|
|
? network.getTransactionFeeEstimateApiUrl()
|
|
|
|
? StacksNetwork.fromNameOrNetwork(network).getTransactionFeeEstimateApiUrl()
|
|
|
|
: defaultNetwork.getTransactionFeeEstimateApiUrl();
|
|
|
|
: defaultNetwork.getTransactionFeeEstimateApiUrl();
|
|
|
|
|
|
|
|
|
|
|
|
const response = await fetchPrivate(url, options);
|
|
|
|
const response = await fetchPrivate(url, options);
|
|
|
|
@@ -393,17 +391,18 @@ export type TxBroadcastResult = TxBroadcastResultOk | TxBroadcastResultRejected;
|
|
|
|
* Broadcast the signed transaction to a core node
|
|
|
|
* Broadcast the signed transaction to a core node
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @param {StacksTransaction} transaction - the token transfer transaction to broadcast
|
|
|
|
* @param {StacksTransaction} transaction - the token transfer transaction to broadcast
|
|
|
|
* @param {StacksNetwork} network - the Stacks network to broadcast transaction to
|
|
|
|
* @param {StacksNetworkName | IStacksNetwork} network - the Stacks network to broadcast transaction to
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @returns {Promise} that resolves to a response if the operation succeeds
|
|
|
|
* @returns {Promise} that resolves to a response if the operation succeeds
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
export async function broadcastTransaction(
|
|
|
|
export async function broadcastTransaction(
|
|
|
|
transaction: StacksTransaction,
|
|
|
|
transaction: StacksTransaction,
|
|
|
|
network: StacksNetwork,
|
|
|
|
network?: StacksNetworkName | IStacksNetwork,
|
|
|
|
attachment?: Buffer
|
|
|
|
attachment?: Buffer
|
|
|
|
): Promise<TxBroadcastResult> {
|
|
|
|
): Promise<TxBroadcastResult> {
|
|
|
|
const rawTx = transaction.serialize();
|
|
|
|
const rawTx = transaction.serialize();
|
|
|
|
const url = network.getBroadcastApiUrl();
|
|
|
|
const derivedNetwork = network ?? deriveNetwork(transaction);
|
|
|
|
|
|
|
|
const url = StacksNetwork.fromNameOrNetwork(derivedNetwork).getBroadcastApiUrl();
|
|
|
|
|
|
|
|
|
|
|
|
return broadcastRawTransaction(rawTx, url, attachment);
|
|
|
|
return broadcastRawTransaction(rawTx, url, attachment);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@@ -459,20 +458,20 @@ export async function broadcastRawTransaction(
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @param {string} address - the contracts address
|
|
|
|
* @param {string} address - the contracts address
|
|
|
|
* @param {string} contractName - the contracts name
|
|
|
|
* @param {string} contractName - the contracts name
|
|
|
|
* @param {StacksNetwork} network - the Stacks network to broadcast transaction to
|
|
|
|
* @param {StacksNetworkName | IStacksNetwork} network - the Stacks network to broadcast transaction to
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @returns {Promise} that resolves to a ClarityAbi if the operation succeeds
|
|
|
|
* @returns {Promise} that resolves to a ClarityAbi if the operation succeeds
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
export async function getAbi(
|
|
|
|
export async function getAbi(
|
|
|
|
address: string,
|
|
|
|
address: string,
|
|
|
|
contractName: string,
|
|
|
|
contractName: string,
|
|
|
|
network: StacksNetwork
|
|
|
|
network: StacksNetworkName | IStacksNetwork
|
|
|
|
): Promise<ClarityAbi> {
|
|
|
|
): Promise<ClarityAbi> {
|
|
|
|
const options = {
|
|
|
|
const options = {
|
|
|
|
method: 'GET',
|
|
|
|
method: 'GET',
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const url = network.getAbiApiUrl(address, contractName);
|
|
|
|
const url = StacksNetwork.fromNameOrNetwork(network).getAbiApiUrl(address, contractName);
|
|
|
|
|
|
|
|
|
|
|
|
const response = await fetchPrivate(url, options);
|
|
|
|
const response = await fetchPrivate(url, options);
|
|
|
|
if (!response.ok) {
|
|
|
|
if (!response.ok) {
|
|
|
|
@@ -488,6 +487,15 @@ export async function getAbi(
|
|
|
|
return JSON.parse(await response.text()) as ClarityAbi;
|
|
|
|
return JSON.parse(await response.text()) as ClarityAbi;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function deriveNetwork(transaction: StacksTransaction) {
|
|
|
|
|
|
|
|
switch (transaction.version) {
|
|
|
|
|
|
|
|
case TransactionVersion.Mainnet:
|
|
|
|
|
|
|
|
return new StacksMainnet();
|
|
|
|
|
|
|
|
case TransactionVersion.Testnet:
|
|
|
|
|
|
|
|
return new StacksTestnet();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export interface MultiSigOptions {
|
|
|
|
export interface MultiSigOptions {
|
|
|
|
numSignatures: number;
|
|
|
|
numSignatures: number;
|
|
|
|
publicKeys: string[];
|
|
|
|
publicKeys: string[];
|
|
|
|
@@ -507,7 +515,7 @@ export interface TokenTransferOptions {
|
|
|
|
/** the transaction nonce, which must be increased monotonically with each new transaction */
|
|
|
|
/** the transaction nonce, which must be increased monotonically with each new transaction */
|
|
|
|
nonce?: IntegerType;
|
|
|
|
nonce?: IntegerType;
|
|
|
|
/** the network that the transaction will ultimately be broadcast to */
|
|
|
|
/** the network that the transaction will ultimately be broadcast to */
|
|
|
|
network?: StacksNetwork;
|
|
|
|
network?: StacksNetworkName | IStacksNetwork;
|
|
|
|
/** the transaction anchorMode, which specifies whether it should be
|
|
|
|
/** the transaction anchorMode, which specifies whether it should be
|
|
|
|
* included in an anchor block or a microblock */
|
|
|
|
* included in an anchor block or a microblock */
|
|
|
|
anchorMode: AnchorMode;
|
|
|
|
anchorMode: AnchorMode;
|
|
|
|
@@ -548,7 +556,7 @@ export interface SignedMultiSigTokenTransferOptions extends TokenTransferOptions
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @param {UnsignedTokenTransferOptions | UnsignedMultiSigTokenTransferOptions} txOptions - an options object for the token transfer
|
|
|
|
* @param {UnsignedTokenTransferOptions | UnsignedMultiSigTokenTransferOptions} txOptions - an options object for the token transfer
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @return {Promis<StacksTransaction>}
|
|
|
|
* @return {Promise<StacksTransaction>}
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
export async function makeUnsignedSTXTokenTransfer(
|
|
|
|
export async function makeUnsignedSTXTokenTransfer(
|
|
|
|
txOptions: UnsignedTokenTransferOptions | UnsignedMultiSigTokenTransferOptions
|
|
|
|
txOptions: UnsignedTokenTransferOptions | UnsignedMultiSigTokenTransferOptions
|
|
|
|
@@ -594,22 +602,24 @@ export async function makeUnsignedSTXTokenTransfer(
|
|
|
|
authorization = createStandardAuth(spendingCondition);
|
|
|
|
authorization = createStandardAuth(spendingCondition);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const network = StacksNetwork.fromNameOrNetwork(options.network);
|
|
|
|
|
|
|
|
|
|
|
|
const postConditions: PostCondition[] = [];
|
|
|
|
const postConditions: PostCondition[] = [];
|
|
|
|
if (options.postConditions && options.postConditions.length > 0) {
|
|
|
|
if (options.postConditions && options.postConditions.length > 0) {
|
|
|
|
options.postConditions.forEach(postCondition => {
|
|
|
|
options.postConditions.forEach(postCondition => {
|
|
|
|
postConditions.push(postCondition);
|
|
|
|
postConditions.push(postCondition);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const lpPostConditions = createLPList(postConditions);
|
|
|
|
const lpPostConditions = createLPList(postConditions);
|
|
|
|
|
|
|
|
|
|
|
|
const transaction = new StacksTransaction(
|
|
|
|
const transaction = new StacksTransaction(
|
|
|
|
options.network.version,
|
|
|
|
network.version,
|
|
|
|
authorization,
|
|
|
|
authorization,
|
|
|
|
payload,
|
|
|
|
payload,
|
|
|
|
lpPostConditions,
|
|
|
|
lpPostConditions,
|
|
|
|
options.postConditionMode,
|
|
|
|
options.postConditionMode,
|
|
|
|
options.anchorMode,
|
|
|
|
options.anchorMode,
|
|
|
|
options.network.chainId
|
|
|
|
network.chainId
|
|
|
|
);
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
if (txOptions.fee === undefined || txOptions.fee === null) {
|
|
|
|
if (txOptions.fee === undefined || txOptions.fee === null) {
|
|
|
|
@@ -685,7 +695,7 @@ export interface BaseContractDeployOptions {
|
|
|
|
/** the transaction nonce, which must be increased monotonically with each new transaction */
|
|
|
|
/** the transaction nonce, which must be increased monotonically with each new transaction */
|
|
|
|
nonce?: IntegerType;
|
|
|
|
nonce?: IntegerType;
|
|
|
|
/** the network that the transaction will ultimately be broadcast to */
|
|
|
|
/** the network that the transaction will ultimately be broadcast to */
|
|
|
|
network?: StacksNetwork;
|
|
|
|
network?: StacksNetworkName | IStacksNetwork;
|
|
|
|
/** the transaction anchorMode, which specifies whether it should be
|
|
|
|
/** the transaction anchorMode, which specifies whether it should be
|
|
|
|
* included in an anchor block or a microblock */
|
|
|
|
* included in an anchor block or a microblock */
|
|
|
|
anchorMode: AnchorMode;
|
|
|
|
anchorMode: AnchorMode;
|
|
|
|
@@ -714,13 +724,13 @@ export interface UnsignedContractDeployOptions extends BaseContractDeployOptions
|
|
|
|
* Estimate the total transaction fee in microstacks for a contract deploy
|
|
|
|
* Estimate the total transaction fee in microstacks for a contract deploy
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @param {StacksTransaction} transaction - the token transfer transaction to estimate fees for
|
|
|
|
* @param {StacksTransaction} transaction - the token transfer transaction to estimate fees for
|
|
|
|
* @param {StacksNetwork} network - the Stacks network to estimate transaction for
|
|
|
|
* @param {StacksNetworkName | IStacksNetwork} network - the Stacks network to estimate transaction for
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @return a promise that resolves to number of microstacks per byte
|
|
|
|
* @return a promise that resolves to number of microstacks per byte
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
export async function estimateContractDeploy(
|
|
|
|
export async function estimateContractDeploy(
|
|
|
|
transaction: StacksTransaction,
|
|
|
|
transaction: StacksTransaction,
|
|
|
|
network?: StacksNetwork
|
|
|
|
network?: StacksNetworkName | IStacksNetwork
|
|
|
|
): Promise<bigint> {
|
|
|
|
): Promise<bigint> {
|
|
|
|
if (transaction.payload.payloadType !== PayloadType.SmartContract) {
|
|
|
|
if (transaction.payload.payloadType !== PayloadType.SmartContract) {
|
|
|
|
throw new Error(
|
|
|
|
throw new Error(
|
|
|
|
@@ -741,10 +751,8 @@ export async function estimateContractDeploy(
|
|
|
|
|
|
|
|
|
|
|
|
// Place holder estimate until contract deploy fee estimation is fully implemented on Stacks
|
|
|
|
// Place holder estimate until contract deploy fee estimation is fully implemented on Stacks
|
|
|
|
// blockchain core
|
|
|
|
// blockchain core
|
|
|
|
const defaultNetwork = new StacksMainnet();
|
|
|
|
const derivedNetwork = network ?? deriveNetwork(transaction);
|
|
|
|
const url = network
|
|
|
|
const url = StacksNetwork.fromNameOrNetwork(derivedNetwork).getTransferFeeEstimateApiUrl();
|
|
|
|
? network.getTransferFeeEstimateApiUrl()
|
|
|
|
|
|
|
|
: defaultNetwork.getTransferFeeEstimateApiUrl();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const response = await fetchPrivate(url, fetchOptions);
|
|
|
|
const response = await fetchPrivate(url, fetchOptions);
|
|
|
|
if (!response.ok) {
|
|
|
|
if (!response.ok) {
|
|
|
|
@@ -821,22 +829,24 @@ export async function makeUnsignedContractDeploy(
|
|
|
|
authorization = createStandardAuth(spendingCondition);
|
|
|
|
authorization = createStandardAuth(spendingCondition);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const network = StacksNetwork.fromNameOrNetwork(options.network);
|
|
|
|
|
|
|
|
|
|
|
|
const postConditions: PostCondition[] = [];
|
|
|
|
const postConditions: PostCondition[] = [];
|
|
|
|
if (options.postConditions && options.postConditions.length > 0) {
|
|
|
|
if (options.postConditions && options.postConditions.length > 0) {
|
|
|
|
options.postConditions.forEach(postCondition => {
|
|
|
|
options.postConditions.forEach(postCondition => {
|
|
|
|
postConditions.push(postCondition);
|
|
|
|
postConditions.push(postCondition);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const lpPostConditions = createLPList(postConditions);
|
|
|
|
const lpPostConditions = createLPList(postConditions);
|
|
|
|
|
|
|
|
|
|
|
|
const transaction = new StacksTransaction(
|
|
|
|
const transaction = new StacksTransaction(
|
|
|
|
options.network.version,
|
|
|
|
network.version,
|
|
|
|
authorization,
|
|
|
|
authorization,
|
|
|
|
payload,
|
|
|
|
payload,
|
|
|
|
lpPostConditions,
|
|
|
|
lpPostConditions,
|
|
|
|
options.postConditionMode,
|
|
|
|
options.postConditionMode,
|
|
|
|
options.anchorMode,
|
|
|
|
options.anchorMode,
|
|
|
|
options.network.chainId
|
|
|
|
network.chainId
|
|
|
|
);
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
if (txOptions.fee === undefined || txOptions.fee === null) {
|
|
|
|
if (txOptions.fee === undefined || txOptions.fee === null) {
|
|
|
|
@@ -873,7 +883,7 @@ export interface ContractCallOptions {
|
|
|
|
/** the transaction nonce, which must be increased monotonically with each new transaction */
|
|
|
|
/** the transaction nonce, which must be increased monotonically with each new transaction */
|
|
|
|
nonce?: IntegerType;
|
|
|
|
nonce?: IntegerType;
|
|
|
|
/** the Stacks blockchain network that will ultimately be used to broadcast this transaction */
|
|
|
|
/** the Stacks blockchain network that will ultimately be used to broadcast this transaction */
|
|
|
|
network?: StacksNetwork;
|
|
|
|
network?: StacksNetworkName | IStacksNetwork;
|
|
|
|
/** the transaction anchorMode, which specifies whether it should be
|
|
|
|
/** the transaction anchorMode, which specifies whether it should be
|
|
|
|
* included in an anchor block or a microblock */
|
|
|
|
* included in an anchor block or a microblock */
|
|
|
|
anchorMode: AnchorMode;
|
|
|
|
anchorMode: AnchorMode;
|
|
|
|
@@ -914,13 +924,13 @@ export interface SignedMultiSigContractCallOptions extends ContractCallOptions {
|
|
|
|
* Estimate the total transaction fee in microstacks for a contract function call
|
|
|
|
* Estimate the total transaction fee in microstacks for a contract function call
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @param {StacksTransaction} transaction - the token transfer transaction to estimate fees for
|
|
|
|
* @param {StacksTransaction} transaction - the token transfer transaction to estimate fees for
|
|
|
|
* @param {StacksNetwork} network - the Stacks network to estimate transaction for
|
|
|
|
* @param {StacksNetworkName | IStacksNetwork} network - the Stacks network to estimate transaction for
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @return a promise that resolves to number of microstacks per byte
|
|
|
|
* @return a promise that resolves to number of microstacks per byte
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
export async function estimateContractFunctionCall(
|
|
|
|
export async function estimateContractFunctionCall(
|
|
|
|
transaction: StacksTransaction,
|
|
|
|
transaction: StacksTransaction,
|
|
|
|
network?: StacksNetwork
|
|
|
|
network?: StacksNetworkName | IStacksNetwork
|
|
|
|
): Promise<bigint> {
|
|
|
|
): Promise<bigint> {
|
|
|
|
if (transaction.payload.payloadType !== PayloadType.ContractCall) {
|
|
|
|
if (transaction.payload.payloadType !== PayloadType.ContractCall) {
|
|
|
|
throw new Error(
|
|
|
|
throw new Error(
|
|
|
|
@@ -941,10 +951,8 @@ export async function estimateContractFunctionCall(
|
|
|
|
|
|
|
|
|
|
|
|
// Place holder estimate until contract call fee estimation is fully implemented on Stacks
|
|
|
|
// Place holder estimate until contract call fee estimation is fully implemented on Stacks
|
|
|
|
// blockchain core
|
|
|
|
// blockchain core
|
|
|
|
const defaultNetwork = new StacksMainnet();
|
|
|
|
const derivedNetwork = network ?? deriveNetwork(transaction);
|
|
|
|
const url = network
|
|
|
|
const url = StacksNetwork.fromNameOrNetwork(derivedNetwork).getTransferFeeEstimateApiUrl();
|
|
|
|
? network.getTransferFeeEstimateApiUrl()
|
|
|
|
|
|
|
|
: defaultNetwork.getTransferFeeEstimateApiUrl();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const response = await fetchPrivate(url, fetchOptions);
|
|
|
|
const response = await fetchPrivate(url, fetchOptions);
|
|
|
|
if (!response.ok) {
|
|
|
|
if (!response.ok) {
|
|
|
|
@@ -1032,6 +1040,8 @@ export async function makeUnsignedContractCall(
|
|
|
|
authorization = createStandardAuth(spendingCondition);
|
|
|
|
authorization = createStandardAuth(spendingCondition);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const network = StacksNetwork.fromNameOrNetwork(options.network);
|
|
|
|
|
|
|
|
|
|
|
|
const postConditions: PostCondition[] = [];
|
|
|
|
const postConditions: PostCondition[] = [];
|
|
|
|
if (options.postConditions && options.postConditions.length > 0) {
|
|
|
|
if (options.postConditions && options.postConditions.length > 0) {
|
|
|
|
options.postConditions.forEach(postCondition => {
|
|
|
|
options.postConditions.forEach(postCondition => {
|
|
|
|
@@ -1041,28 +1051,28 @@ export async function makeUnsignedContractCall(
|
|
|
|
|
|
|
|
|
|
|
|
const lpPostConditions = createLPList(postConditions);
|
|
|
|
const lpPostConditions = createLPList(postConditions);
|
|
|
|
const transaction = new StacksTransaction(
|
|
|
|
const transaction = new StacksTransaction(
|
|
|
|
options.network.version,
|
|
|
|
network.version,
|
|
|
|
authorization,
|
|
|
|
authorization,
|
|
|
|
payload,
|
|
|
|
payload,
|
|
|
|
lpPostConditions,
|
|
|
|
lpPostConditions,
|
|
|
|
options.postConditionMode,
|
|
|
|
options.postConditionMode,
|
|
|
|
options.anchorMode,
|
|
|
|
options.anchorMode,
|
|
|
|
options.network.chainId
|
|
|
|
network.chainId
|
|
|
|
);
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
if (txOptions.fee === undefined || txOptions.fee === null) {
|
|
|
|
if (txOptions.fee === undefined || txOptions.fee === null) {
|
|
|
|
const estimatedLen = transaction.serialize().byteLength;
|
|
|
|
const estimatedLen = transaction.serialize().byteLength;
|
|
|
|
const txFee = await estimateTransaction(payload, estimatedLen, options.network);
|
|
|
|
const txFee = await estimateTransaction(payload, estimatedLen, network);
|
|
|
|
transaction.setFee(txFee[1].fee);
|
|
|
|
transaction.setFee(txFee[1].fee);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (txOptions.nonce === undefined || txOptions.nonce === null) {
|
|
|
|
if (txOptions.nonce === undefined || txOptions.nonce === null) {
|
|
|
|
const addressVersion =
|
|
|
|
const addressVersion =
|
|
|
|
options.network.version === TransactionVersion.Mainnet
|
|
|
|
network.version === TransactionVersion.Mainnet
|
|
|
|
? AddressVersion.MainnetSingleSig
|
|
|
|
? AddressVersion.MainnetSingleSig
|
|
|
|
: AddressVersion.TestnetSingleSig;
|
|
|
|
: AddressVersion.TestnetSingleSig;
|
|
|
|
const senderAddress = c32address(addressVersion, transaction.auth.spendingCondition!.signer);
|
|
|
|
const senderAddress = c32address(addressVersion, transaction.auth.spendingCondition!.signer);
|
|
|
|
const txNonce = await getNonce(senderAddress, options.network);
|
|
|
|
const txNonce = await getNonce(senderAddress, network);
|
|
|
|
transaction.setNonce(txNonce);
|
|
|
|
transaction.setNonce(txNonce);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@@ -1264,7 +1274,7 @@ export function makeContractNonFungiblePostCondition(
|
|
|
|
* @param {String} contractName - the contract name
|
|
|
|
* @param {String} contractName - the contract name
|
|
|
|
* @param {String} functionName - name of the function to be called
|
|
|
|
* @param {String} functionName - name of the function to be called
|
|
|
|
* @param {[ClarityValue]} functionArgs - an array of Clarity values as arguments to the function call
|
|
|
|
* @param {[ClarityValue]} functionArgs - an array of Clarity values as arguments to the function call
|
|
|
|
* @param {StacksNetwork} network - the Stacks blockchain network this transaction is destined for
|
|
|
|
* @param {IStacksNetwork} network - the Stacks blockchain network this transaction is destined for
|
|
|
|
* @param {String} senderAddress - the c32check address of the sender
|
|
|
|
* @param {String} senderAddress - the c32check address of the sender
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
@@ -1274,7 +1284,7 @@ export interface ReadOnlyFunctionOptions {
|
|
|
|
functionName: string;
|
|
|
|
functionName: string;
|
|
|
|
functionArgs: ClarityValue[];
|
|
|
|
functionArgs: ClarityValue[];
|
|
|
|
/** the network that the contract which contains the function is deployed to */
|
|
|
|
/** the network that the contract which contains the function is deployed to */
|
|
|
|
network?: StacksNetwork;
|
|
|
|
network?: StacksNetworkName | IStacksNetwork;
|
|
|
|
/** address of the sender */
|
|
|
|
/** address of the sender */
|
|
|
|
senderAddress: string;
|
|
|
|
senderAddress: string;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@@ -1297,9 +1307,9 @@ export async function callReadOnlyFunction(
|
|
|
|
|
|
|
|
|
|
|
|
const options = Object.assign(defaultOptions, readOnlyFunctionOptions);
|
|
|
|
const options = Object.assign(defaultOptions, readOnlyFunctionOptions);
|
|
|
|
|
|
|
|
|
|
|
|
const { contractName, contractAddress, functionName, functionArgs, network, senderAddress } =
|
|
|
|
const { contractName, contractAddress, functionName, functionArgs, senderAddress } = options;
|
|
|
|
options;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const network = StacksNetwork.fromNameOrNetwork(options.network);
|
|
|
|
const url = network.getReadOnlyFunctionCallApiUrl(contractAddress, contractName, functionName);
|
|
|
|
const url = network.getReadOnlyFunctionCallApiUrl(contractAddress, contractName, functionName);
|
|
|
|
|
|
|
|
|
|
|
|
const args = functionArgs.map(arg => cvToHex(arg));
|
|
|
|
const args = functionArgs.map(arg => cvToHex(arg));
|
|
|
|
@@ -1345,7 +1355,7 @@ export interface SponsorOptionsOpts {
|
|
|
|
/** the hashmode of the sponsor's address */
|
|
|
|
/** the hashmode of the sponsor's address */
|
|
|
|
sponsorAddressHashmode?: AddressHashMode;
|
|
|
|
sponsorAddressHashmode?: AddressHashMode;
|
|
|
|
/** the Stacks blockchain network that this transaction will ultimately be broadcast to */
|
|
|
|
/** the Stacks blockchain network that this transaction will ultimately be broadcast to */
|
|
|
|
network?: StacksNetwork;
|
|
|
|
network?: StacksNetworkName | IStacksNetwork;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
@@ -1364,14 +1374,15 @@ export async function sponsorTransaction(
|
|
|
|
fee: 0 as IntegerType,
|
|
|
|
fee: 0 as IntegerType,
|
|
|
|
sponsorNonce: 0 as IntegerType,
|
|
|
|
sponsorNonce: 0 as IntegerType,
|
|
|
|
sponsorAddressHashmode: AddressHashMode.SerializeP2PKH as SingleSigHashMode,
|
|
|
|
sponsorAddressHashmode: AddressHashMode.SerializeP2PKH as SingleSigHashMode,
|
|
|
|
|
|
|
|
network:
|
|
|
|
|
|
|
|
sponsorOptions.transaction.version === TransactionVersion.Mainnet
|
|
|
|
|
|
|
|
? new StacksMainnet()
|
|
|
|
|
|
|
|
: new StacksTestnet(),
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const options = Object.assign(defaultOptions, sponsorOptions);
|
|
|
|
const options = Object.assign(defaultOptions, sponsorOptions);
|
|
|
|
const network =
|
|
|
|
|
|
|
|
sponsorOptions.network ??
|
|
|
|
const network = StacksNetwork.fromNameOrNetwork(options.network);
|
|
|
|
(options.transaction.version === TransactionVersion.Mainnet
|
|
|
|
|
|
|
|
? new StacksMainnet()
|
|
|
|
|
|
|
|
: new StacksTestnet());
|
|
|
|
|
|
|
|
const sponsorPubKey = pubKeyfromPrivKey(options.sponsorPrivateKey);
|
|
|
|
const sponsorPubKey = pubKeyfromPrivKey(options.sponsorPrivateKey);
|
|
|
|
|
|
|
|
|
|
|
|
if (sponsorOptions.fee === undefined || sponsorOptions.fee === null) {
|
|
|
|
if (sponsorOptions.fee === undefined || sponsorOptions.fee === null) {
|
|
|
|
|