mirror of
https://github.com/zhigang1992/liquid-stacking.git
synced 2026-01-12 17:23:23 +08:00
feat: add multisig-stx-transfer
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"multisig-plan": "node --no-warnings=ExperimentalWarning --loader ts-node/esm ./scripts/create-multisig-deployment-plan.ts",
|
||||
"multisig-stx-transfer": "node --no-warnings=ExperimentalWarning --loader ts-node/esm ./scripts/create-multisig-stx-transfer-plan.ts",
|
||||
"multisig-sign": "node --no-warnings=ExperimentalWarning --loader ts-node/esm ./scripts/sign-multisig-deployment-plan.ts",
|
||||
"multisig-broadcast": "node --no-warnings=ExperimentalWarning --loader ts-node/esm ./scripts/broadcast-multisig-deployment-plan.ts",
|
||||
"multisig-analyse": "node --no-warnings=ExperimentalWarning --loader ts-node/esm ./scripts/analyse-multisig-deployment-plan.ts",
|
||||
@@ -22,7 +23,7 @@
|
||||
"license": "BSL",
|
||||
"prettier": "@stacks/prettier-config",
|
||||
"dependencies": {
|
||||
"@hirosystems/clarinet-sdk": "2.4.0-beta2",
|
||||
"@hirosystems/clarinet-sdk": "2.4.0-beta3",
|
||||
"@stacks/stacking": "6.11.4-pr.36558cf.0",
|
||||
"@stacks/prettier-config": "^0.0.10",
|
||||
"@stacks/transactions": "^6.9.0",
|
||||
|
||||
97
scripts/create-multisig-stx-transfer-plan.ts
Executable file
97
scripts/create-multisig-stx-transfer-plan.ts
Executable file
@@ -0,0 +1,97 @@
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
import { bytesToHex } from '@stacks/common';
|
||||
import {
|
||||
Address,
|
||||
AddressHashMode,
|
||||
AnchorMode,
|
||||
StacksPublicKey,
|
||||
StacksTransaction,
|
||||
addressToString,
|
||||
createMultiSigSpendingCondition,
|
||||
makeUnsignedSTXTokenTransfer,
|
||||
} from '@stacks/transactions';
|
||||
import fs from 'fs';
|
||||
import { getNetwork, getStacksAddress, getStacksPubkeys } from './config.ts';
|
||||
import { assertSigner, planFile, verboseLog } from './utils.ts';
|
||||
|
||||
const lisaDaoContractName = 'lisa-dao';
|
||||
|
||||
const network = getNetwork();
|
||||
const address = getStacksAddress();
|
||||
const pubKeys = getStacksPubkeys();
|
||||
let nonce = 27;
|
||||
const feeMultiplier = 100; // transaction bytes * feeMultiplier
|
||||
const feeAddition = 1; // add a flat amount on top
|
||||
const feeCap = 0; //15 * 1000000; // 15 STX
|
||||
|
||||
const multisigSpendConditionByteLength = 66; // don't change
|
||||
|
||||
let tempTotalFee = 0n;
|
||||
|
||||
verboseLog(`Using address ${addressToString(address)}`);
|
||||
|
||||
async function createMultisigStxTransaction(
|
||||
amount: bigint,
|
||||
recipient: string,
|
||||
feeMultiplier: number,
|
||||
nonce: number,
|
||||
numSignatures: number,
|
||||
pubkeys: StacksPublicKey[],
|
||||
signer: Address
|
||||
) {
|
||||
const publicKeys = pubkeys.map(pk => bytesToHex(pk.data));
|
||||
const tx = await makeUnsignedSTXTokenTransfer({
|
||||
numSignatures,
|
||||
publicKeys,
|
||||
recipient,
|
||||
fee: 1,
|
||||
nonce,
|
||||
network,
|
||||
amount,
|
||||
anchorMode: AnchorMode.OnChainOnly,
|
||||
});
|
||||
// makeUnsignedContractCall() forces a AddressHashMode.SerializeP2SH spending condition, so we construct it manually
|
||||
// and replace it.
|
||||
tx.auth.spendingCondition = createMultiSigSpendingCondition(
|
||||
AddressHashMode.SerializeP2WSH,
|
||||
numSignatures,
|
||||
publicKeys,
|
||||
nonce,
|
||||
1
|
||||
);
|
||||
assertSigner(tx.auth.spendingCondition, signer);
|
||||
let calculatedFee =
|
||||
(tx.serialize().byteLength + multisigSpendConditionByteLength * pubKeys.length) *
|
||||
feeMultiplier +
|
||||
feeAddition;
|
||||
if (feeCap > 0 && calculatedFee > feeCap) calculatedFee = feeCap;
|
||||
tx.setFee(calculatedFee);
|
||||
tempTotalFee += BigInt(calculatedFee);
|
||||
return tx;
|
||||
}
|
||||
|
||||
// adding fields on the unsigned tx makes it easier to manage
|
||||
function addPubkeyFields(tx: StacksTransaction, pubKeys: StacksPublicKey[]) {
|
||||
for (const pk of pubKeys) tx.appendPubkey(pk);
|
||||
return tx;
|
||||
}
|
||||
|
||||
const addressString = addressToString(address);
|
||||
|
||||
(async () => {
|
||||
const fundingTx = await createMultisigStxTransaction(
|
||||
394399976n - 52501n,
|
||||
`${addressString}.${lisaDaoContractName}`,
|
||||
feeMultiplier,
|
||||
nonce++,
|
||||
pubKeys.length,
|
||||
pubKeys,
|
||||
address
|
||||
);
|
||||
return [bytesToHex(addPubkeyFields(fundingTx, pubKeys).serialize())];
|
||||
})().then(plan => {
|
||||
fs.writeFileSync(planFile, JSON.stringify(plan), 'utf-8');
|
||||
verboseLog(`Last nonce is ${nonce}, total fee: ${Number(tempTotalFee) / 1000000} STX`);
|
||||
console.log(`Deploy plan written to ${planFile}, total of ${plan.length} transactions`);
|
||||
});
|
||||
Reference in New Issue
Block a user