PHP WebShell
Текущая директория: /opt/BitGoJS/node_modules/@stacks/transactions/dist/esm
Просмотр файла: builders.js
import { Buffer, intToBigInt } from '@stacks/common';
import { StacksTransaction } from './transaction';
import { StacksMainnet, StacksTestnet } from '@stacks/network';
import { createTokenTransferPayload, createSmartContractPayload, createContractCallPayload, } from './payload';
import { StandardAuthorization, SponsoredAuthorization, createSingleSigSpendingCondition, createMultiSigSpendingCondition, } from './authorization';
import { publicKeyToString, createStacksPrivateKey, getPublicKey, publicKeyToAddress, pubKeyfromPrivKey, publicKeyFromBuffer, } from './keys';
import { TransactionSigner } from './signer';
import { createSTXPostCondition, createFungiblePostCondition, createNonFungiblePostCondition, } from './postcondition';
import { AddressHashMode, AddressVersion, PostConditionMode, PayloadType, TransactionVersion, } from './constants';
import { createLPList, createStandardPrincipal, createContractPrincipal } from './types';
import { cvToHex, parseReadOnlyResponse, omit, validateTxId } from './utils';
import { fetchPrivate } from '@stacks/common';
import { validateContractCall } from './contract-abi';
import { c32address } from 'c32check';
export async function getNonce(address, network) {
const defaultNetwork = new StacksMainnet();
const url = network
? network.getAccountApiUrl(address)
: defaultNetwork.getAccountApiUrl(address);
const response = await fetchPrivate(url);
if (!response.ok) {
let msg = '';
try {
msg = await response.text();
}
catch (error) { }
throw new Error(`Error fetching nonce. Response ${response.status}: ${response.statusText}. Attempted to fetch ${url} and failed with the message: "${msg}"`);
}
const responseText = await response.text();
const result = JSON.parse(responseText);
return BigInt(result.nonce);
}
export async function estimateTransfer(transaction, network) {
if (transaction.payload.payloadType !== PayloadType.TokenTransfer) {
throw new Error(`Transaction fee estimation only possible with ${PayloadType[PayloadType.TokenTransfer]} transactions. Invoked with: ${PayloadType[transaction.payload.payloadType]}`);
}
const requestHeaders = {
Accept: 'application/text',
};
const fetchOptions = {
method: 'GET',
headers: requestHeaders,
};
const defaultNetwork = new StacksMainnet();
const url = network
? network.getTransferFeeEstimateApiUrl()
: defaultNetwork.getTransferFeeEstimateApiUrl();
const response = await fetchPrivate(url, fetchOptions);
if (!response.ok) {
let msg = '';
try {
msg = await response.text();
}
catch (error) { }
throw new Error(`Error estimating transaction fee. Response ${response.status}: ${response.statusText}. Attempted to fetch ${url} and failed with the message: "${msg}"`);
}
const feeRateResult = await response.text();
const txBytes = BigInt(transaction.serialize().byteLength);
const feeRate = BigInt(feeRateResult);
return feeRate * txBytes;
}
export async function broadcastTransaction(transaction, network, attachment) {
const rawTx = transaction.serialize();
const url = network.getBroadcastApiUrl();
return broadcastRawTransaction(rawTx, url, attachment);
}
export async function broadcastRawTransaction(rawTx, url, attachment) {
const options = {
method: 'POST',
headers: { 'Content-Type': attachment ? 'application/json' : 'application/octet-stream' },
body: attachment
? JSON.stringify({
tx: rawTx.toString('hex'),
attachment: attachment.toString('hex'),
})
: rawTx,
};
const response = await fetchPrivate(url, options);
if (!response.ok) {
try {
return (await response.json());
}
catch (e) {
throw Error(`Failed to broadcast transaction: ${e.message}`);
}
}
const text = await response.text();
const txid = text.replace(/["]+/g, '');
const isValidTxId = validateTxId(txid);
if (isValidTxId) {
return {
txid: txid,
};
}
else {
throw new Error(text);
}
}
export async function getAbi(address, contractName, network) {
const options = {
method: 'GET',
};
const url = network.getAbiApiUrl(address, contractName);
const response = await fetchPrivate(url, options);
if (!response.ok) {
let msg = '';
try {
msg = await response.text();
}
catch (error) { }
throw new Error(`Error fetching contract ABI for contract "${contractName}" at address ${address}. Response ${response.status}: ${response.statusText}. Attempted to fetch ${url} and failed with the message: "${msg}"`);
}
return JSON.parse(await response.text());
}
export async function makeUnsignedSTXTokenTransfer(txOptions) {
const defaultOptions = {
fee: BigInt(0),
nonce: BigInt(0),
network: new StacksMainnet(),
postConditionMode: PostConditionMode.Deny,
memo: '',
sponsored: false,
};
const options = Object.assign(defaultOptions, txOptions);
const payload = createTokenTransferPayload(options.recipient, options.amount, options.memo);
let authorization = null;
let spendingCondition = null;
if ('publicKey' in options) {
spendingCondition = createSingleSigSpendingCondition(AddressHashMode.SerializeP2PKH, options.publicKey, options.nonce, options.fee);
}
else {
spendingCondition = createMultiSigSpendingCondition(AddressHashMode.SerializeP2SH, options.numSignatures, options.publicKeys, options.nonce, options.fee);
}
if (options.sponsored) {
authorization = new SponsoredAuthorization(spendingCondition);
}
else {
authorization = new StandardAuthorization(spendingCondition);
}
const postConditions = [];
if (options.postConditions && options.postConditions.length > 0) {
options.postConditions.forEach(postCondition => {
postConditions.push(postCondition);
});
}
const lpPostConditions = createLPList(postConditions);
const transaction = new StacksTransaction(options.network.version, authorization, payload, lpPostConditions, options.postConditionMode, options.anchorMode, options.network.chainId);
if (txOptions.fee === undefined || txOptions.fee === null) {
const txFee = await estimateTransfer(transaction, options.network);
transaction.setFee(txFee);
}
if (txOptions.nonce === undefined || txOptions.nonce === null) {
const addressVersion = options.network.version === TransactionVersion.Mainnet
? AddressVersion.MainnetSingleSig
: AddressVersion.TestnetSingleSig;
const senderAddress = c32address(addressVersion, transaction.auth.spendingCondition.signer);
const txNonce = await getNonce(senderAddress, options.network);
transaction.setNonce(txNonce);
}
return transaction;
}
export async function makeSTXTokenTransfer(txOptions) {
if ('senderKey' in txOptions) {
const publicKey = publicKeyToString(getPublicKey(createStacksPrivateKey(txOptions.senderKey)));
const options = omit(txOptions, 'senderKey');
const transaction = await makeUnsignedSTXTokenTransfer(Object.assign({ publicKey }, options));
const privKey = createStacksPrivateKey(txOptions.senderKey);
const signer = new TransactionSigner(transaction);
signer.signOrigin(privKey);
return transaction;
}
else {
const options = omit(txOptions, 'signerKeys');
const transaction = await makeUnsignedSTXTokenTransfer(options);
const signer = new TransactionSigner(transaction);
let pubKeys = txOptions.publicKeys;
for (const key of txOptions.signerKeys) {
const pubKey = pubKeyfromPrivKey(key);
pubKeys = pubKeys.filter(pk => pk !== pubKey.data.toString('hex'));
signer.signOrigin(createStacksPrivateKey(key));
}
for (const key of pubKeys) {
signer.appendOrigin(publicKeyFromBuffer(Buffer.from(key, 'hex')));
}
return transaction;
}
}
export async function estimateContractDeploy(transaction, network) {
if (transaction.payload.payloadType !== PayloadType.SmartContract) {
throw new Error(`Contract deploy fee estimation only possible with ${PayloadType[PayloadType.SmartContract]} transactions. Invoked with: ${PayloadType[transaction.payload.payloadType]}`);
}
const requestHeaders = {
Accept: 'application/text',
};
const fetchOptions = {
method: 'GET',
headers: requestHeaders,
};
const defaultNetwork = new StacksMainnet();
const url = network
? network.getTransferFeeEstimateApiUrl()
: defaultNetwork.getTransferFeeEstimateApiUrl();
const response = await fetchPrivate(url, fetchOptions);
if (!response.ok) {
let msg = '';
try {
msg = await response.text();
}
catch (error) { }
throw new Error(`Error estimating contract deploy fee. Response ${response.status}: ${response.statusText}. Attempted to fetch ${url} and failed with the message: "${msg}"`);
}
const feeRateResult = await response.text();
const txBytes = intToBigInt(transaction.serialize().byteLength, false);
const feeRate = intToBigInt(feeRateResult, false);
return feeRate * txBytes;
}
export async function makeContractDeploy(txOptions) {
const defaultOptions = {
fee: BigInt(0),
nonce: BigInt(0),
network: new StacksMainnet(),
postConditionMode: PostConditionMode.Deny,
sponsored: false,
};
const options = Object.assign(defaultOptions, txOptions);
const payload = createSmartContractPayload(options.contractName, options.codeBody);
const addressHashMode = AddressHashMode.SerializeP2PKH;
const privKey = createStacksPrivateKey(options.senderKey);
const pubKey = getPublicKey(privKey);
let authorization = null;
const spendingCondition = createSingleSigSpendingCondition(addressHashMode, publicKeyToString(pubKey), options.nonce, options.fee);
if (options.sponsored) {
authorization = new SponsoredAuthorization(spendingCondition);
}
else {
authorization = new StandardAuthorization(spendingCondition);
}
const postConditions = [];
if (options.postConditions && options.postConditions.length > 0) {
options.postConditions.forEach(postCondition => {
postConditions.push(postCondition);
});
}
const lpPostConditions = createLPList(postConditions);
const transaction = new StacksTransaction(options.network.version, authorization, payload, lpPostConditions, options.postConditionMode, options.anchorMode, options.network.chainId);
if (txOptions.fee === undefined || txOptions.fee === null) {
const txFee = await estimateContractDeploy(transaction, options.network);
transaction.setFee(txFee);
}
if (txOptions.nonce === undefined || txOptions.nonce === null) {
const addressVersion = options.network.version === TransactionVersion.Mainnet
? AddressVersion.MainnetSingleSig
: AddressVersion.TestnetSingleSig;
const senderAddress = publicKeyToAddress(addressVersion, pubKey);
const txNonce = await getNonce(senderAddress, options.network);
transaction.setNonce(txNonce);
}
if (options.senderKey) {
const signer = new TransactionSigner(transaction);
signer.signOrigin(privKey);
}
return transaction;
}
export async function estimateContractFunctionCall(transaction, network) {
if (transaction.payload.payloadType !== PayloadType.ContractCall) {
throw new Error(`Contract call fee estimation only possible with ${PayloadType[PayloadType.ContractCall]} transactions. Invoked with: ${PayloadType[transaction.payload.payloadType]}`);
}
const requestHeaders = {
Accept: 'application/text',
};
const fetchOptions = {
method: 'GET',
headers: requestHeaders,
};
const defaultNetwork = new StacksMainnet();
const url = network
? network.getTransferFeeEstimateApiUrl()
: defaultNetwork.getTransferFeeEstimateApiUrl();
const response = await fetchPrivate(url, fetchOptions);
if (!response.ok) {
let msg = '';
try {
msg = await response.text();
}
catch (error) { }
throw new Error(`Error estimating contract call fee. Response ${response.status}: ${response.statusText}. Attempted to fetch ${url} and failed with the message: "${msg}"`);
}
const feeRateResult = await response.text();
const txBytes = intToBigInt(transaction.serialize().byteLength, false);
const feeRate = intToBigInt(feeRateResult, false);
return feeRate * txBytes;
}
export async function makeUnsignedContractCall(txOptions) {
const defaultOptions = {
fee: BigInt(0),
nonce: BigInt(0),
network: new StacksMainnet(),
postConditionMode: PostConditionMode.Deny,
sponsored: false,
};
const options = Object.assign(defaultOptions, txOptions);
const payload = createContractCallPayload(options.contractAddress, options.contractName, options.functionName, options.functionArgs);
if (options === null || options === void 0 ? void 0 : options.validateWithAbi) {
let abi;
if (typeof options.validateWithAbi === 'boolean') {
if (options === null || options === void 0 ? void 0 : options.network) {
abi = await getAbi(options.contractAddress, options.contractName, options.network);
}
else {
throw new Error('Network option must be provided in order to validate with ABI');
}
}
else {
abi = options.validateWithAbi;
}
validateContractCall(payload, abi);
}
let spendingCondition = null;
let authorization = null;
if ('publicKey' in options) {
spendingCondition = createSingleSigSpendingCondition(AddressHashMode.SerializeP2PKH, options.publicKey, options.nonce, options.fee);
}
else {
spendingCondition = createMultiSigSpendingCondition(AddressHashMode.SerializeP2SH, options.numSignatures, options.publicKeys, options.nonce, options.fee);
}
if (options.sponsored) {
authorization = new SponsoredAuthorization(spendingCondition);
}
else {
authorization = new StandardAuthorization(spendingCondition);
}
const postConditions = [];
if (options.postConditions && options.postConditions.length > 0) {
options.postConditions.forEach(postCondition => {
postConditions.push(postCondition);
});
}
const lpPostConditions = createLPList(postConditions);
const transaction = new StacksTransaction(options.network.version, authorization, payload, lpPostConditions, options.postConditionMode, options.anchorMode, options.network.chainId);
if (txOptions.fee === undefined || txOptions.fee === null) {
const txFee = await estimateContractFunctionCall(transaction, options.network);
transaction.setFee(txFee);
}
if (txOptions.nonce === undefined || txOptions.nonce === null) {
const addressVersion = options.network.version === TransactionVersion.Mainnet
? AddressVersion.MainnetSingleSig
: AddressVersion.TestnetSingleSig;
const senderAddress = c32address(addressVersion, transaction.auth.spendingCondition.signer);
const txNonce = await getNonce(senderAddress, options.network);
transaction.setNonce(txNonce);
}
return transaction;
}
export async function makeContractCall(txOptions) {
if ('senderKey' in txOptions) {
const publicKey = publicKeyToString(getPublicKey(createStacksPrivateKey(txOptions.senderKey)));
const options = omit(txOptions, 'senderKey');
const transaction = await makeUnsignedContractCall(Object.assign({ publicKey }, options));
const privKey = createStacksPrivateKey(txOptions.senderKey);
const signer = new TransactionSigner(transaction);
signer.signOrigin(privKey);
return transaction;
}
else {
const options = omit(txOptions, 'signerKeys');
const transaction = await makeUnsignedContractCall(options);
const signer = new TransactionSigner(transaction);
let pubKeys = txOptions.publicKeys;
for (const key of txOptions.signerKeys) {
const pubKey = pubKeyfromPrivKey(key);
pubKeys = pubKeys.filter(pk => pk !== pubKey.data.toString('hex'));
signer.signOrigin(createStacksPrivateKey(key));
}
for (const key of pubKeys) {
signer.appendOrigin(publicKeyFromBuffer(Buffer.from(key, 'hex')));
}
return transaction;
}
}
export function makeStandardSTXPostCondition(address, conditionCode, amount) {
return createSTXPostCondition(createStandardPrincipal(address), conditionCode, amount);
}
export function makeContractSTXPostCondition(address, contractName, conditionCode, amount) {
return createSTXPostCondition(createContractPrincipal(address, contractName), conditionCode, amount);
}
export function makeStandardFungiblePostCondition(address, conditionCode, amount, assetInfo) {
return createFungiblePostCondition(createStandardPrincipal(address), conditionCode, amount, assetInfo);
}
export function makeContractFungiblePostCondition(address, contractName, conditionCode, amount, assetInfo) {
return createFungiblePostCondition(createContractPrincipal(address, contractName), conditionCode, amount, assetInfo);
}
export function makeStandardNonFungiblePostCondition(address, conditionCode, assetInfo, assetName) {
return createNonFungiblePostCondition(createStandardPrincipal(address), conditionCode, assetInfo, assetName);
}
export function makeContractNonFungiblePostCondition(address, contractName, conditionCode, assetInfo, assetName) {
return createNonFungiblePostCondition(createContractPrincipal(address, contractName), conditionCode, assetInfo, assetName);
}
export async function callReadOnlyFunction(readOnlyFunctionOptions) {
const defaultOptions = {
network: new StacksMainnet(),
};
const options = Object.assign(defaultOptions, readOnlyFunctionOptions);
const { contractName, contractAddress, functionName, functionArgs, network, senderAddress } = options;
const url = network.getReadOnlyFunctionCallApiUrl(contractAddress, contractName, functionName);
const args = functionArgs.map(arg => cvToHex(arg));
const body = JSON.stringify({
sender: senderAddress,
arguments: args,
});
const response = await fetchPrivate(url, {
method: 'POST',
body,
headers: {
'Content-Type': 'application/json',
},
});
if (!response.ok) {
let msg = '';
try {
msg = await response.text();
}
catch (error) { }
throw new Error(`Error calling read-only function. Response ${response.status}: ${response.statusText}. Attempted to fetch ${url} and failed with the message: "${msg}"`);
}
return response.json().then(responseJson => parseReadOnlyResponse(responseJson));
}
export async function sponsorTransaction(sponsorOptions) {
var _a;
const defaultOptions = {
fee: 0,
sponsorNonce: 0,
sponsorAddressHashmode: AddressHashMode.SerializeP2PKH,
};
const options = Object.assign(defaultOptions, sponsorOptions);
const network = (_a = sponsorOptions.network) !== null && _a !== void 0 ? _a : (options.transaction.version === TransactionVersion.Mainnet
? new StacksMainnet()
: new StacksTestnet());
const sponsorPubKey = pubKeyfromPrivKey(options.sponsorPrivateKey);
if (sponsorOptions.fee === undefined || sponsorOptions.fee === null) {
let txFee = BigInt(0);
switch (options.transaction.payload.payloadType) {
case PayloadType.TokenTransfer:
txFee = await estimateTransfer(options.transaction, network);
break;
case PayloadType.SmartContract:
txFee = await estimateContractDeploy(options.transaction, network);
break;
case PayloadType.ContractCall:
txFee = await estimateContractFunctionCall(options.transaction, network);
break;
default:
throw new Error(`Sponsored transactions not supported for transaction type ${PayloadType[options.transaction.payload.payloadType]}`);
}
options.transaction.setFee(txFee);
options.fee = txFee;
}
if (sponsorOptions.sponsorNonce === undefined || sponsorOptions.sponsorNonce === null) {
const addressVersion = network.version === TransactionVersion.Mainnet
? AddressVersion.MainnetSingleSig
: AddressVersion.TestnetSingleSig;
const senderAddress = publicKeyToAddress(addressVersion, sponsorPubKey);
const sponsorNonce = await getNonce(senderAddress, network);
options.sponsorNonce = sponsorNonce;
}
const sponsorSpendingCondition = createSingleSigSpendingCondition(options.sponsorAddressHashmode, publicKeyToString(sponsorPubKey), options.sponsorNonce, options.fee);
options.transaction.setSponsor(sponsorSpendingCondition);
const privKey = createStacksPrivateKey(options.sponsorPrivateKey);
const signer = TransactionSigner.createSponsorSigner(options.transaction, sponsorSpendingCondition);
signer.signSponsor(privKey);
return options.transaction;
}
//# sourceMappingURL=builders.js.mapВыполнить команду
Для локальной разработки. Не используйте в интернете!