@kaspacom/kcc20-tx-builder 0.1.0 → 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/artifacts.d.ts +2 -0
- package/dist/artifacts.d.ts.map +1 -1
- package/dist/artifacts.js +3 -1
- package/dist/artifacts.js.map +1 -1
- package/dist/builder.d.ts +0 -2
- package/dist/builder.d.ts.map +1 -1
- package/dist/cjs/artifacts.d.ts +2 -0
- package/dist/cjs/artifacts.js +4 -2
- package/dist/cjs/artifacts.js.map +1 -1
- package/dist/cjs/builder.d.ts +0 -2
- package/dist/cjs/deploy-receipt.d.ts +45 -0
- package/dist/cjs/deploy-receipt.js +122 -0
- package/dist/cjs/deploy-receipt.js.map +1 -0
- package/dist/cjs/engine.js +336 -226
- package/dist/cjs/engine.js.map +1 -1
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/protocol.d.ts +1 -0
- package/dist/cjs/protocol.js +15 -0
- package/dist/cjs/protocol.js.map +1 -1
- package/dist/deploy-receipt.d.ts +46 -0
- package/dist/deploy-receipt.d.ts.map +1 -0
- package/dist/deploy-receipt.js +119 -0
- package/dist/deploy-receipt.js.map +1 -0
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +337 -227
- package/dist/engine.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/protocol.d.ts +1 -0
- package/dist/protocol.d.ts.map +1 -1
- package/dist/protocol.js +14 -0
- package/dist/protocol.js.map +1 -1
- package/package.json +1 -1
- package/src/artifacts.ts +5 -1
- package/src/builder.ts +0 -3
- package/src/deploy-receipt.ts +200 -0
- package/src/engine.ts +429 -296
- package/src/index.ts +1 -0
- package/src/protocol.ts +21 -0
package/dist/engine.js
CHANGED
|
@@ -3,10 +3,11 @@ import { sha256 } from "@noble/hashes/sha256";
|
|
|
3
3
|
import { DEFAULT_COMPUTE_BUDGET, DEFAULT_KCC20_FEE_BPS, DEFAULT_KCC20_MIN_PROTOCOL_FEE_SOMPI, DEFAULT_KCC20_PRICE_SCALE, DEFAULT_TOKEN_OUTPUT_SOMPI, KCC20_ORDERBOOK_EXPANDED_SWEEP_OUTPUT_SOMPI, KCC20_ORDERBOOK_MAX_SWEEP_BID_LEGS, KCC20_ORDERBOOK_MAX_EXPANDED_SWEEP_BID_LEGS, KCC20_PLATFORM_PROTOCOL_FEE_RECIPIENT, KCC20_ORDERBOOK_PROTOCOL_FEE_RECIPIENT, SUBNETWORK_ID_NATIVE, SOMPI_PER_TKAS, asciiToBytes32, buildKcc20FeeTicketScriptForState, buildNativeKcc20ScriptForState, buildKcc20WrapperScriptForState, buildKcc20OrderbookScriptForState, buildKcc20V3CreateBidSigScript, buildKcc20V3SellIntoBidSigScript, buildKcc20OrderbookFillBidFromSellerSweepSigScript, buildKcc20OrderbookFillAskSigScript, buildKcc20OrderbookFillBidSigScript, buildKcc20OrderbookSellIntoBidsSigScript, buildKcc20OrderbookSellIntoBids10SigScript, buildKcc20OrderbookCrossAskSigScript, buildKcc20OrderbookCrossAskLegacySigScript, buildKcc20OrderbookCrossBidSigScript, buildKcc20OrderbookCrossBidLegacySigScript, bytesToHex, calculateFeeSplit, findOutputIndex, hexToBytes, kcc20PsktBuilderError, mintPolicyName, normalizeSignature, p2pkScriptPubKey, p2shScriptHashHex, parseMintPolicy, requireHex32, selectFundingEntry, setVersionOneInputMassFields, stateToReceiptFields, utxoAmountSompi, ZERO_HASH, } from "./sale-common.js";
|
|
4
4
|
import { buildKcc20BurnSigScript, buildKcc20MintByOwnerSigScript, buildKcc20MintPublicSigScript, buildKcc20ScriptForState, buildKcc20SetPublicMintActiveSigScript, buildKcc20TransferSigScript, dispatchTagFor, encodeKcc20StateRecordArrays, holderExtensionCommitment, mintExtensionCommitment, normalizeSilverScriptArtifact, ownerAuthorizationWitness, } from "./abi.js";
|
|
5
5
|
import { KCC20_BUILDER_KEYS } from "./operations.js";
|
|
6
|
-
import {
|
|
6
|
+
import { splitKcc20MintSupply } from "./protocol.js";
|
|
7
|
+
import { buildKcc20DeployIntentOutputs } from "./deploy-receipt.js";
|
|
8
|
+
import { KCC20_ARTIFACT_SCRIPT_SHA256, KCC20_CURRENT_NATIVE_ARTIFACT_KEY, assertKcc20ArtifactScriptHash, } from "./artifacts.js";
|
|
7
9
|
export function createKcc20PsktBuilderEngine(options) {
|
|
8
|
-
const
|
|
9
|
-
const process = { env: config };
|
|
10
|
+
const env = options.config ?? {};
|
|
10
11
|
class InjectedRpcClient {
|
|
11
12
|
inner;
|
|
12
13
|
constructor(rpcConfig) {
|
|
@@ -99,7 +100,7 @@ export function createKcc20PsktBuilderEngine(options) {
|
|
|
99
100
|
KCC20_ORDERBOOK_SWEEP_ASK_COMPUTE_BUDGET_PROFILE.feeTicket,
|
|
100
101
|
],
|
|
101
102
|
]);
|
|
102
|
-
const KCC20_ARTIFACT_PATH =
|
|
103
|
+
const KCC20_ARTIFACT_PATH = KCC20_CURRENT_NATIVE_ARTIFACT_KEY;
|
|
103
104
|
const WRAPPER_ARTIFACT_PATH = "KCC20Wrapper.placeholder.json";
|
|
104
105
|
const WRAPPED_ARTIFACT_PATH = "KCC20Orderbook.placeholder.json";
|
|
105
106
|
const FEE_TICKET_ARTIFACT_PATH = "KCC20FeeTicket.placeholder.json";
|
|
@@ -254,7 +255,7 @@ export function createKcc20PsktBuilderEngine(options) {
|
|
|
254
255
|
denomination: parsePositiveU64(input.utilityTokenAmount, "FeeTicket utility token amount"),
|
|
255
256
|
};
|
|
256
257
|
try {
|
|
257
|
-
const artifact = selectFeeTicketArtifactForState(await readFeeTicketArtifacts(), rootState, requireKaspaAddress(input.rootAddress), input.network ||
|
|
258
|
+
const artifact = selectFeeTicketArtifactForState(await readFeeTicketArtifacts(), rootState, requireKaspaAddress(input.rootAddress), input.network || env.KASPA_NETWORK || "testnet-10", "active FeeTicket root UTXO address");
|
|
258
259
|
return {
|
|
259
260
|
recognizedArtifact: true,
|
|
260
261
|
batchCreateSupported: artifact.supportsBatchCreate,
|
|
@@ -346,13 +347,13 @@ export function createKcc20PsktBuilderEngine(options) {
|
|
|
346
347
|
const rootOwner = requireHex32(params.rootOwner || request.owner?.kcc20Owner, "FeeTicket root owner");
|
|
347
348
|
const utilityTokenId = requireHex32(params.utilityTokenId, "FeeTicket utility token id");
|
|
348
349
|
const newDenomination = parsePositiveU64(params.utilityTokenAmount, "utilityTokenAmount");
|
|
349
|
-
const network = request.network ||
|
|
350
|
+
const network = request.network || env.KASPA_NETWORK || "testnet-10";
|
|
350
351
|
const walletAddress = requireKaspaAddress(request.owner?.walletAddress);
|
|
351
352
|
const rootAddress = requireKaspaAddress(rootUtxo.address);
|
|
352
|
-
const rpcUrl =
|
|
353
|
-
const priorityFee = parseU64(
|
|
353
|
+
const rpcUrl = env.KASPA_WRPC_URL || DEFAULT_WRPC_URL;
|
|
354
|
+
const priorityFee = parseU64(env.KCC20_FEE_TICKET_PRIORITY_FEE_SOMPI ||
|
|
354
355
|
DEFAULT_PRIORITY_FEE.toString(), "priorityFee");
|
|
355
|
-
const computeBudget = parsePositiveNumber(
|
|
356
|
+
const computeBudget = parsePositiveNumber(env.KCC20_FEE_TICKET_COMPUTE_BUDGET || DEFAULT_COMPUTE_BUDGET, "computeBudget");
|
|
356
357
|
const currentState = kcc20FeeTicketStateFromUtxo(rootUtxo, request.owner);
|
|
357
358
|
if (currentState.mode !== 1) {
|
|
358
359
|
throw new Error("FeeTicket denomination update requires a root UTXO");
|
|
@@ -490,13 +491,13 @@ export function createKcc20PsktBuilderEngine(options) {
|
|
|
490
491
|
if (totalDenomination > MAX_U64) {
|
|
491
492
|
throw new Error("FeeTicket batch utility token amount must fit in an unsigned 64-bit integer");
|
|
492
493
|
}
|
|
493
|
-
const network = request.network ||
|
|
494
|
+
const network = request.network || env.KASPA_NETWORK || "testnet-10";
|
|
494
495
|
const walletAddress = requireKaspaAddress(request.owner?.walletAddress);
|
|
495
|
-
const rpcUrl =
|
|
496
|
+
const rpcUrl = env.KASPA_WRPC_URL || DEFAULT_WRPC_URL;
|
|
496
497
|
const tokenOutputSompi = configuredFeeTicketOutputSompiForQuantity(quantity);
|
|
497
|
-
const priorityFee = parseU64(
|
|
498
|
+
const priorityFee = parseU64(env.KCC20_FEE_TICKET_PRIORITY_FEE_SOMPI ||
|
|
498
499
|
DEFAULT_PRIORITY_FEE.toString(), "priorityFee");
|
|
499
|
-
const computeBudget = parsePositiveNumber(
|
|
500
|
+
const computeBudget = parsePositiveNumber(env.KCC20_FEE_TICKET_COMPUTE_BUDGET || DEFAULT_COMPUTE_BUDGET, "computeBudget");
|
|
500
501
|
const feeTicketArtifacts = await readFeeTicketArtifacts();
|
|
501
502
|
const rootState = {
|
|
502
503
|
ownerIdentifier: hexToBytes(rootOwner),
|
|
@@ -718,12 +719,12 @@ export function createKcc20PsktBuilderEngine(options) {
|
|
|
718
719
|
if (new Set(sourceOutpoints).size !== sourceOutpoints.length) {
|
|
719
720
|
throw new Error("FeeTicket burn source outpoints must be unique");
|
|
720
721
|
}
|
|
721
|
-
const network = request.network ||
|
|
722
|
+
const network = request.network || env.KASPA_NETWORK || "testnet-10";
|
|
722
723
|
const walletAddress = requireKaspaAddress(request.owner?.walletAddress);
|
|
723
|
-
const rpcUrl =
|
|
724
|
-
const priorityFee = parseU64(
|
|
724
|
+
const rpcUrl = env.KASPA_WRPC_URL || DEFAULT_WRPC_URL;
|
|
725
|
+
const priorityFee = parseU64(env.KCC20_FEE_TICKET_PRIORITY_FEE_SOMPI ||
|
|
725
726
|
DEFAULT_PRIORITY_FEE.toString(), "priorityFee");
|
|
726
|
-
const computeBudget = parsePositiveNumber(
|
|
727
|
+
const computeBudget = parsePositiveNumber(env.KCC20_FEE_TICKET_COMPUTE_BUDGET || DEFAULT_COMPUTE_BUDGET, "computeBudget");
|
|
727
728
|
const artifacts = await readFeeTicketArtifacts();
|
|
728
729
|
const states = ticketUtxos.map((utxo) => kcc20FeeTicketStateFromUtxo(utxo, request.owner));
|
|
729
730
|
for (const state of states) {
|
|
@@ -861,12 +862,12 @@ export function createKcc20PsktBuilderEngine(options) {
|
|
|
861
862
|
if (new Set(sourceOutpoints).size !== sourceOutpoints.length) {
|
|
862
863
|
throw new Error("FeeTicket transfer source outpoints must be unique");
|
|
863
864
|
}
|
|
864
|
-
const network = request.network ||
|
|
865
|
+
const network = request.network || env.KASPA_NETWORK || "testnet-10";
|
|
865
866
|
const walletAddress = requireKaspaAddress(request.owner?.walletAddress);
|
|
866
|
-
const rpcUrl =
|
|
867
|
-
const priorityFee = parseU64(
|
|
867
|
+
const rpcUrl = env.KASPA_WRPC_URL || DEFAULT_WRPC_URL;
|
|
868
|
+
const priorityFee = parseU64(env.KCC20_FEE_TICKET_PRIORITY_FEE_SOMPI ||
|
|
868
869
|
DEFAULT_PRIORITY_FEE.toString(), "priorityFee");
|
|
869
|
-
const computeBudget = parsePositiveNumber(
|
|
870
|
+
const computeBudget = parsePositiveNumber(env.KCC20_FEE_TICKET_COMPUTE_BUDGET || DEFAULT_COMPUTE_BUDGET, "computeBudget");
|
|
870
871
|
const artifacts = await readFeeTicketArtifacts();
|
|
871
872
|
const states = ticketUtxos.map((utxo) => kcc20FeeTicketStateFromUtxo(utxo, request.owner));
|
|
872
873
|
for (const state of states) {
|
|
@@ -1002,7 +1003,7 @@ export function createKcc20PsktBuilderEngine(options) {
|
|
|
1002
1003
|
const configured = BigInt(configuredOutputSompi);
|
|
1003
1004
|
return configured > minimum ? configured : minimum;
|
|
1004
1005
|
}
|
|
1005
|
-
function configuredFeeTicketOutputSompiForQuantity(quantity, environment =
|
|
1006
|
+
function configuredFeeTicketOutputSompiForQuantity(quantity, environment = env) {
|
|
1006
1007
|
const configured = parseU64(Number(quantity) === 1
|
|
1007
1008
|
? environment.KCC20_FEE_TICKET_OUTPUT_SOMPI ||
|
|
1008
1009
|
DEFAULT_TOKEN_OUTPUT_SOMPI.toString()
|
|
@@ -1649,14 +1650,14 @@ export function createKcc20PsktBuilderEngine(options) {
|
|
|
1649
1650
|
params.tokenDisplayScale ??
|
|
1650
1651
|
DEFAULT_KCC20_PRICE_SCALE, "priceScale");
|
|
1651
1652
|
assertWrapperArtifactPriceScale(priceScale);
|
|
1652
|
-
const network = request.network ||
|
|
1653
|
+
const network = request.network || env.KASPA_NETWORK || "testnet-10";
|
|
1653
1654
|
const walletAddress = requireKaspaAddress(request.owner?.walletAddress);
|
|
1654
|
-
const rpcUrl =
|
|
1655
|
-
const amountTkas = parseAmountTkas(
|
|
1656
|
-
|
|
1655
|
+
const rpcUrl = env.KASPA_WRPC_URL || DEFAULT_WRPC_URL;
|
|
1656
|
+
const amountTkas = parseAmountTkas(env.KCC20_WRAPPER_DEPLOY_OUTPUT_TKAS ||
|
|
1657
|
+
env.KCC20_DEPLOY_OUTPUT_TKAS ||
|
|
1657
1658
|
DEFAULT_DEPLOY_TKAS, "KCC20_WRAPPER_DEPLOY_OUTPUT_TKAS");
|
|
1658
|
-
const priorityFee = wrapperDeployPriorityFee(
|
|
1659
|
-
const computeBudget = parsePositiveNumber(
|
|
1659
|
+
const priorityFee = wrapperDeployPriorityFee(env.KCC20_WRAPPER_DEPLOY_PRIORITY_FEE_SOMPI);
|
|
1660
|
+
const computeBudget = parsePositiveNumber(env.KCC20_WRAPPER_DEPLOY_COMPUTE_BUDGET || 600, "computeBudget");
|
|
1660
1661
|
const wrapperArtifact = await readStaticArtifact(WRAPPER_ARTIFACT_PATH);
|
|
1661
1662
|
const wrappedArtifacts = await readWrappedArtifacts();
|
|
1662
1663
|
const wrappedArtifact = wrappedArtifacts[0].artifact;
|
|
@@ -1842,14 +1843,14 @@ export function createKcc20PsktBuilderEngine(options) {
|
|
|
1842
1843
|
const recipientOwner = requireHex32(params.recipientOwner || request.owner?.kcc20Owner, "wrapped recipient owner");
|
|
1843
1844
|
const tokenAmount = parsePositiveU64(params.tokenAmount, "tokenAmount");
|
|
1844
1845
|
const feeTicketId = requireHex32(params.feeTicketId || ZERO_HASH, "fee ticket id");
|
|
1845
|
-
const network = request.network ||
|
|
1846
|
+
const network = request.network || env.KASPA_NETWORK || "testnet-10";
|
|
1846
1847
|
const walletAddress = requireKaspaAddress(request.owner?.walletAddress);
|
|
1847
|
-
const rpcUrl =
|
|
1848
|
-
const tokenOutputSompi = parseU64(
|
|
1848
|
+
const rpcUrl = env.KASPA_WRPC_URL || DEFAULT_WRPC_URL;
|
|
1849
|
+
const tokenOutputSompi = parseU64(env.KCC20_WRAP_TOKEN_OUTPUT_SOMPI ||
|
|
1849
1850
|
DEFAULT_TOKEN_OUTPUT_SOMPI.toString(), "tokenOutputSompi");
|
|
1850
|
-
const priorityFee = parseU64(
|
|
1851
|
+
const priorityFee = parseU64(env.KCC20_WRAP_PRIORITY_FEE_SOMPI ||
|
|
1851
1852
|
DEFAULT_PRIORITY_FEE.toString(), "priorityFee");
|
|
1852
|
-
const computeBudget = parsePositiveNumber(
|
|
1853
|
+
const computeBudget = parsePositiveNumber(env.KCC20_WRAP_COMPUTE_BUDGET || 700, "computeBudget");
|
|
1853
1854
|
const [wrapperArtifacts, wrappedArtifacts] = await Promise.all([
|
|
1854
1855
|
readWrapperArtifacts(),
|
|
1855
1856
|
readWrappedArtifacts(),
|
|
@@ -2113,14 +2114,14 @@ export function createKcc20PsktBuilderEngine(options) {
|
|
|
2113
2114
|
const wrapperId = requireHex32(params.wrappedMarketId || params.wrapperId, "wrapped market id");
|
|
2114
2115
|
const recipientOwner = requireHex32(params.recipientOwner || request.owner?.kcc20Owner, "KCC20 recipient owner");
|
|
2115
2116
|
const tokenAmount = parsePositiveU64(params.tokenAmount, "tokenAmount");
|
|
2116
|
-
const network = request.network ||
|
|
2117
|
+
const network = request.network || env.KASPA_NETWORK || "testnet-10";
|
|
2117
2118
|
const walletAddress = requireKaspaAddress(request.owner?.walletAddress);
|
|
2118
|
-
const rpcUrl =
|
|
2119
|
-
const tokenOutputSompi = parseU64(
|
|
2119
|
+
const rpcUrl = env.KASPA_WRPC_URL || DEFAULT_WRPC_URL;
|
|
2120
|
+
const tokenOutputSompi = parseU64(env.KCC20_UNWRAP_TOKEN_OUTPUT_SOMPI ||
|
|
2120
2121
|
DEFAULT_TOKEN_OUTPUT_SOMPI.toString(), "tokenOutputSompi");
|
|
2121
|
-
const priorityFee = parseU64(
|
|
2122
|
+
const priorityFee = parseU64(env.KCC20_UNWRAP_PRIORITY_FEE_SOMPI ||
|
|
2122
2123
|
DEFAULT_PRIORITY_FEE.toString(), "priorityFee");
|
|
2123
|
-
const computeBudget = parsePositiveNumber(
|
|
2124
|
+
const computeBudget = parsePositiveNumber(env.KCC20_UNWRAP_COMPUTE_BUDGET || 700, "computeBudget");
|
|
2124
2125
|
const [wrapperArtifacts, wrappedArtifacts] = await Promise.all([
|
|
2125
2126
|
readWrapperArtifacts(),
|
|
2126
2127
|
readWrappedArtifacts(),
|
|
@@ -2442,14 +2443,14 @@ export function createKcc20PsktBuilderEngine(options) {
|
|
|
2442
2443
|
const expectedFeeTicketId = params.feeTicketId
|
|
2443
2444
|
? requireHex32(params.feeTicketId, "fee ticket id")
|
|
2444
2445
|
: null;
|
|
2445
|
-
const network = request.network ||
|
|
2446
|
+
const network = request.network || env.KASPA_NETWORK || "testnet-10";
|
|
2446
2447
|
const walletAddress = requireKaspaAddress(request.owner?.walletAddress);
|
|
2447
|
-
const rpcUrl =
|
|
2448
|
-
const tokenOutputSompi = parseU64(
|
|
2448
|
+
const rpcUrl = env.KASPA_WRPC_URL || DEFAULT_WRPC_URL;
|
|
2449
|
+
const tokenOutputSompi = parseU64(env.KCC20_ORDER_TOKEN_OUTPUT_SOMPI ||
|
|
2449
2450
|
DEFAULT_TOKEN_OUTPUT_SOMPI.toString(), "tokenOutputSompi");
|
|
2450
|
-
const priorityFee = parseU64(
|
|
2451
|
+
const priorityFee = parseU64(env.KCC20_ORDER_PRIORITY_FEE_SOMPI ||
|
|
2451
2452
|
DEFAULT_PRIORITY_FEE.toString(), "priorityFee");
|
|
2452
|
-
const computeBudget = parsePositiveNumber(
|
|
2453
|
+
const computeBudget = parsePositiveNumber(env.KCC20_ORDER_COMPUTE_BUDGET || 700, "computeBudget");
|
|
2453
2454
|
const wrappedArtifacts = await readWrappedArtifacts();
|
|
2454
2455
|
const activeUtxo = isBid ? rootUtxo : holderUtxo;
|
|
2455
2456
|
const activeState = kcc20V3WrappedStateFromUtxo(activeUtxo, canonicalTokenId, request.owner);
|
|
@@ -2689,14 +2690,14 @@ export function createKcc20PsktBuilderEngine(options) {
|
|
|
2689
2690
|
const buyerOwner = requireHex32(request.owner?.kcc20Owner, "buyer owner");
|
|
2690
2691
|
const fillAmount = parsePositiveU64(params.tokenAmount, "tokenAmount");
|
|
2691
2692
|
const unitPriceSompi = parsePositiveU64(params.unitPriceSompi, "unitPriceSompi");
|
|
2692
|
-
const network = request.network ||
|
|
2693
|
+
const network = request.network || env.KASPA_NETWORK || "testnet-10";
|
|
2693
2694
|
const walletAddress = requireKaspaAddress(request.owner?.walletAddress);
|
|
2694
|
-
const rpcUrl =
|
|
2695
|
-
const tokenOutputSompi = parseU64(
|
|
2695
|
+
const rpcUrl = env.KASPA_WRPC_URL || DEFAULT_WRPC_URL;
|
|
2696
|
+
const tokenOutputSompi = parseU64(env.KCC20_FILL_TOKEN_OUTPUT_SOMPI ||
|
|
2696
2697
|
DEFAULT_TOKEN_OUTPUT_SOMPI.toString(), "tokenOutputSompi");
|
|
2697
|
-
const priorityFee = parseU64(
|
|
2698
|
+
const priorityFee = parseU64(env.KCC20_FILL_PRIORITY_FEE_SOMPI ||
|
|
2698
2699
|
DEFAULT_PRIORITY_FEE.toString(), "priorityFee");
|
|
2699
|
-
const computeBudget = parsePositiveNumber(
|
|
2700
|
+
const computeBudget = parsePositiveNumber(env.KCC20_FILL_COMPUTE_BUDGET || 800, "computeBudget");
|
|
2700
2701
|
const wrappedArtifacts = await readWrappedArtifacts();
|
|
2701
2702
|
const ticketArtifacts = ticketUtxo ? await readFeeTicketArtifacts() : null;
|
|
2702
2703
|
const askState = kcc20V3WrappedStateFromUtxo(askUtxo, canonicalTokenId, request.owner);
|
|
@@ -2974,14 +2975,14 @@ export function createKcc20PsktBuilderEngine(options) {
|
|
|
2974
2975
|
const sellerOwner = requireHex32(request.owner?.kcc20Owner, "seller owner");
|
|
2975
2976
|
const fillAmount = parsePositiveU64(params.tokenAmount, "tokenAmount");
|
|
2976
2977
|
const unitPriceSompi = parsePositiveU64(params.unitPriceSompi, "unitPriceSompi");
|
|
2977
|
-
const network = request.network ||
|
|
2978
|
+
const network = request.network || env.KASPA_NETWORK || "testnet-10";
|
|
2978
2979
|
const walletAddress = requireKaspaAddress(request.owner?.walletAddress);
|
|
2979
|
-
const rpcUrl =
|
|
2980
|
-
const tokenOutputSompi = parseU64(
|
|
2980
|
+
const rpcUrl = env.KASPA_WRPC_URL || DEFAULT_WRPC_URL;
|
|
2981
|
+
const tokenOutputSompi = parseU64(env.KCC20_FILL_TOKEN_OUTPUT_SOMPI ||
|
|
2981
2982
|
DEFAULT_TOKEN_OUTPUT_SOMPI.toString(), "tokenOutputSompi");
|
|
2982
|
-
const priorityFee = parseU64(
|
|
2983
|
+
const priorityFee = parseU64(env.KCC20_FILL_PRIORITY_FEE_SOMPI ||
|
|
2983
2984
|
DEFAULT_PRIORITY_FEE.toString(), "priorityFee");
|
|
2984
|
-
const computeBudget = parsePositiveNumber(
|
|
2985
|
+
const computeBudget = parsePositiveNumber(env.KCC20_FILL_COMPUTE_BUDGET || 800, "computeBudget");
|
|
2985
2986
|
const wrappedArtifacts = await readWrappedArtifacts();
|
|
2986
2987
|
const ticketArtifacts = ticketUtxo ? await readFeeTicketArtifacts() : null;
|
|
2987
2988
|
const bidState = kcc20V3WrappedStateFromUtxo(bidUtxo, canonicalTokenId, request.owner);
|
|
@@ -3380,12 +3381,12 @@ export function createKcc20PsktBuilderEngine(options) {
|
|
|
3380
3381
|
const canonicalTokenId = requireHex32(params.canonicalCovenantId || params.covenantId, "canonical token id");
|
|
3381
3382
|
const wrapperId = requireHex32(params.wrappedMarketId || params.wrapperId, "wrapped market id");
|
|
3382
3383
|
const buyerOwner = requireHex32(request.owner?.kcc20Owner, "buyer owner");
|
|
3383
|
-
const network = request.network ||
|
|
3384
|
+
const network = request.network || env.KASPA_NETWORK || "testnet-10";
|
|
3384
3385
|
const walletAddress = requireKaspaAddress(request.owner?.walletAddress);
|
|
3385
|
-
const rpcUrl =
|
|
3386
|
-
const tokenOutputSompi = parseU64(
|
|
3386
|
+
const rpcUrl = env.KASPA_WRPC_URL || DEFAULT_WRPC_URL;
|
|
3387
|
+
const tokenOutputSompi = parseU64(env.KCC20_FILL_TOKEN_OUTPUT_SOMPI ||
|
|
3387
3388
|
DEFAULT_TOKEN_OUTPUT_SOMPI.toString(), "tokenOutputSompi");
|
|
3388
|
-
const priorityFee = parseU64(
|
|
3389
|
+
const priorityFee = parseU64(env.KCC20_FILL_PRIORITY_FEE_SOMPI ||
|
|
3389
3390
|
DEFAULT_PRIORITY_FEE.toString(), "priorityFee");
|
|
3390
3391
|
const wrappedArtifacts = await readWrappedArtifacts();
|
|
3391
3392
|
const ticketArtifacts = params.feeTicketId
|
|
@@ -3743,12 +3744,12 @@ export function createKcc20PsktBuilderEngine(options) {
|
|
|
3743
3744
|
const canonicalTokenId = requireHex32(params.canonicalCovenantId || params.covenantId, "canonical token id");
|
|
3744
3745
|
const wrapperId = requireHex32(params.wrappedMarketId || params.wrapperId, "wrapped market id");
|
|
3745
3746
|
const sellerOwner = requireHex32(request.owner?.kcc20Owner, "seller owner");
|
|
3746
|
-
const network = request.network ||
|
|
3747
|
+
const network = request.network || env.KASPA_NETWORK || "testnet-10";
|
|
3747
3748
|
const walletAddress = requireKaspaAddress(request.owner?.walletAddress);
|
|
3748
|
-
const rpcUrl =
|
|
3749
|
-
const tokenOutputSompi = parseU64(
|
|
3749
|
+
const rpcUrl = env.KASPA_WRPC_URL || DEFAULT_WRPC_URL;
|
|
3750
|
+
const tokenOutputSompi = parseU64(env.KCC20_FILL_TOKEN_OUTPUT_SOMPI ||
|
|
3750
3751
|
DEFAULT_TOKEN_OUTPUT_SOMPI.toString(), "tokenOutputSompi");
|
|
3751
|
-
const priorityFee = parseU64(
|
|
3752
|
+
const priorityFee = parseU64(env.KCC20_FILL_PRIORITY_FEE_SOMPI ||
|
|
3752
3753
|
DEFAULT_PRIORITY_FEE.toString(), "priorityFee");
|
|
3753
3754
|
const wrappedArtifacts = await readWrappedArtifacts();
|
|
3754
3755
|
const wrappedArtifact = wrappedArtifacts[0].artifact;
|
|
@@ -4240,12 +4241,12 @@ export function createKcc20PsktBuilderEngine(options) {
|
|
|
4240
4241
|
const canonicalTokenId = requireHex32(params.canonicalCovenantId || params.covenantId, "canonical token id");
|
|
4241
4242
|
const wrapperId = requireHex32(params.wrappedMarketId || params.wrapperId, "wrapped market id");
|
|
4242
4243
|
const sellerOwner = requireHex32(request.owner?.kcc20Owner, "seller owner");
|
|
4243
|
-
const network = request.network ||
|
|
4244
|
+
const network = request.network || env.KASPA_NETWORK || "testnet-10";
|
|
4244
4245
|
const walletAddress = requireKaspaAddress(request.owner?.walletAddress);
|
|
4245
|
-
const rpcUrl =
|
|
4246
|
-
const configuredTokenOutputSompi = parseU64(
|
|
4246
|
+
const rpcUrl = env.KASPA_WRPC_URL || DEFAULT_WRPC_URL;
|
|
4247
|
+
const configuredTokenOutputSompi = parseU64(env.KCC20_FILL_TOKEN_OUTPUT_SOMPI ||
|
|
4247
4248
|
DEFAULT_TOKEN_OUTPUT_SOMPI.toString(), "tokenOutputSompi");
|
|
4248
|
-
const priorityFee = parseU64(
|
|
4249
|
+
const priorityFee = parseU64(env.KCC20_FILL_PRIORITY_FEE_SOMPI ||
|
|
4249
4250
|
DEFAULT_PRIORITY_FEE.toString(), "priorityFee");
|
|
4250
4251
|
const wrappedArtifacts = await readWrappedArtifacts();
|
|
4251
4252
|
const ticketArtifacts = params.feeTicketId
|
|
@@ -4755,16 +4756,16 @@ export function createKcc20PsktBuilderEngine(options) {
|
|
|
4755
4756
|
params.wrapperId, "wrapped market id");
|
|
4756
4757
|
const requestedWrapperId = requireHex32(params.wrappedMarketId || params.wrapperId || wrapperId, "requested wrapped market id");
|
|
4757
4758
|
const owner = requireHex32(request.owner?.kcc20Owner, "token owner");
|
|
4758
|
-
const network = request.network ||
|
|
4759
|
+
const network = request.network || env.KASPA_NETWORK || "testnet-10";
|
|
4759
4760
|
const walletAddress = requireKaspaAddress(request.owner?.walletAddress);
|
|
4760
|
-
const rpcUrl =
|
|
4761
|
-
const priorityFee = parseU64(
|
|
4762
|
-
|
|
4761
|
+
const rpcUrl = env.KASPA_WRPC_URL || DEFAULT_WRPC_URL;
|
|
4762
|
+
const priorityFee = parseU64(env.KCC20_CONSOLIDATE_PRIORITY_FEE_SOMPI ||
|
|
4763
|
+
env.KCC20_FILL_PRIORITY_FEE_SOMPI ||
|
|
4763
4764
|
DEFAULT_PRIORITY_FEE.toString(), "priorityFee");
|
|
4764
|
-
const configuredPrimaryComputeBudget = parsePositiveNumber(
|
|
4765
|
-
|
|
4765
|
+
const configuredPrimaryComputeBudget = parsePositiveNumber(env.KCC20_CONSOLIDATE_COMPUTE_BUDGET ||
|
|
4766
|
+
env.KCC20_FILL_COMPUTE_BUDGET ||
|
|
4766
4767
|
800, "configuredPrimaryComputeBudget");
|
|
4767
|
-
const peerComputeBudget = parsePositiveNumber(
|
|
4768
|
+
const peerComputeBudget = parsePositiveNumber(env.KCC20_CONSOLIDATE_PEER_COMPUTE_BUDGET || 200, "peerComputeBudget");
|
|
4768
4769
|
const computeBudget = Math.max(configuredPrimaryComputeBudget, 500 + holderUtxos.length * 100);
|
|
4769
4770
|
const wrappedArtifacts = await readWrappedArtifacts();
|
|
4770
4771
|
const states = holderUtxos.map((utxo) => kcc20V3WrappedStateFromUtxo(utxo, canonicalTokenId, request.owner));
|
|
@@ -4966,24 +4967,24 @@ export function createKcc20PsktBuilderEngine(options) {
|
|
|
4966
4967
|
? requireHex32(params.feeTicketId, "fee ticket id")
|
|
4967
4968
|
: null;
|
|
4968
4969
|
const maxFeeSompi = parseU64(params.maxFeeSompi || "0", "maxFeeSompi");
|
|
4969
|
-
const network = request.network ||
|
|
4970
|
+
const network = request.network || env.KASPA_NETWORK || "testnet-10";
|
|
4970
4971
|
const walletAddress = requireKaspaAddress(request.owner?.walletAddress);
|
|
4971
4972
|
const expectedOwner = request.owner?.kcc20Owner
|
|
4972
4973
|
? requireHex32(request.owner.kcc20Owner, "matcher owner")
|
|
4973
4974
|
: null;
|
|
4974
|
-
const rpcUrl =
|
|
4975
|
-
const tokenOutputSompi = parseU64(
|
|
4976
|
-
|
|
4975
|
+
const rpcUrl = env.KASPA_WRPC_URL || DEFAULT_WRPC_URL;
|
|
4976
|
+
const tokenOutputSompi = parseU64(env.KCC20_MATCHER_TOKEN_OUTPUT_SOMPI ||
|
|
4977
|
+
env.KCC20_FILL_TOKEN_OUTPUT_SOMPI ||
|
|
4977
4978
|
DEFAULT_TOKEN_OUTPUT_SOMPI.toString(), "tokenOutputSompi");
|
|
4978
|
-
const priorityFee = parseU64(
|
|
4979
|
-
|
|
4979
|
+
const priorityFee = parseU64(env.KCC20_MATCHER_PRIORITY_FEE_SOMPI ||
|
|
4980
|
+
env.KCC20_FILL_PRIORITY_FEE_SOMPI ||
|
|
4980
4981
|
DEFAULT_MATCHER_PRIORITY_FEE.toString(), "priorityFee");
|
|
4981
|
-
const networkFeeReserve = parseU64(
|
|
4982
|
+
const networkFeeReserve = parseU64(env.KCC20_MATCHER_NETWORK_FEE_RESERVE_SOMPI || "5000000", "networkFeeReserve");
|
|
4982
4983
|
const transactionFeeReserve = priorityFee + networkFeeReserve;
|
|
4983
|
-
const computeBudget = parsePositiveNumber(
|
|
4984
|
-
|
|
4984
|
+
const computeBudget = parsePositiveNumber(env.KCC20_MATCHER_COMPUTE_BUDGET ||
|
|
4985
|
+
env.KCC20_FILL_COMPUTE_BUDGET ||
|
|
4985
4986
|
800, "computeBudget");
|
|
4986
|
-
const privateKeyHex = String(
|
|
4987
|
+
const privateKeyHex = String(env.KCC20_WRAPPER_OPERATOR_PRIVATE_KEY || "")
|
|
4987
4988
|
.trim()
|
|
4988
4989
|
.replace(/^0x/i, "");
|
|
4989
4990
|
if (!privateKeyHex) {
|
|
@@ -5429,12 +5430,12 @@ export function createKcc20PsktBuilderEngine(options) {
|
|
|
5429
5430
|
const wrapperId = requireHex32(params.wrappedMarketId || params.wrapperId, "wrapped market id");
|
|
5430
5431
|
const owner = requireHex32(request.owner?.kcc20Owner, "order owner");
|
|
5431
5432
|
const targetOrderId = requireOrderId(params.targetOrderId, "target order id");
|
|
5432
|
-
const network = request.network ||
|
|
5433
|
+
const network = request.network || env.KASPA_NETWORK || "testnet-10";
|
|
5433
5434
|
const walletAddress = requireKaspaAddress(request.owner?.walletAddress);
|
|
5434
|
-
const rpcUrl =
|
|
5435
|
-
const priorityFee = parseU64(
|
|
5435
|
+
const rpcUrl = env.KASPA_WRPC_URL || DEFAULT_WRPC_URL;
|
|
5436
|
+
const priorityFee = parseU64(env.KCC20_CANCEL_PRIORITY_FEE_SOMPI ||
|
|
5436
5437
|
DEFAULT_PRIORITY_FEE.toString(), "priorityFee");
|
|
5437
|
-
const computeBudget = parsePositiveNumber(
|
|
5438
|
+
const computeBudget = parsePositiveNumber(env.KCC20_CANCEL_COMPUTE_BUDGET || 800, "computeBudget");
|
|
5438
5439
|
const wrappedArtifacts = await readWrappedArtifacts();
|
|
5439
5440
|
const orderState = kcc20V3WrappedStateFromUtxo(orderUtxo, canonicalTokenId, request.owner);
|
|
5440
5441
|
if (orderState.mode !== expectedMode) {
|
|
@@ -5646,14 +5647,14 @@ export function createKcc20PsktBuilderEngine(options) {
|
|
|
5646
5647
|
const minterTxid = requireHex32(activeMinterUtxo.txidHex, "minter txid");
|
|
5647
5648
|
const minterVout = parseVout(activeMinterUtxo.vout, "minter vout");
|
|
5648
5649
|
const minterAddress = requireKaspaAddress(activeMinterUtxo.address);
|
|
5649
|
-
const network = request.network ||
|
|
5650
|
+
const network = request.network || env.KASPA_NETWORK || "testnet-10";
|
|
5650
5651
|
const walletAddress = requireKaspaAddress(request.owner?.walletAddress);
|
|
5651
|
-
const rpcUrl =
|
|
5652
|
-
const tokenOutputSompi = assertKcc20TokenOutputSompi(parseU64(
|
|
5652
|
+
const rpcUrl = env.KASPA_WRPC_URL || DEFAULT_WRPC_URL;
|
|
5653
|
+
const tokenOutputSompi = assertKcc20TokenOutputSompi(parseU64(env.KCC20_MINT_TOKEN_OUTPUT_SOMPI ||
|
|
5653
5654
|
DEFAULT_TOKEN_OUTPUT_SOMPI.toString(), "tokenOutputSompi"), "mint");
|
|
5654
|
-
const priorityFee = parseU64(
|
|
5655
|
+
const priorityFee = parseU64(env.KCC20_MINT_PRIORITY_FEE_SOMPI ||
|
|
5655
5656
|
DEFAULT_PRIORITY_FEE.toString(), "priorityFee");
|
|
5656
|
-
const computeBudget = parsePositiveNumber(
|
|
5657
|
+
const computeBudget = parsePositiveNumber(env.KCC20_MINT_COMPUTE_BUDGET || DEFAULT_COMPUTE_BUDGET, "computeBudget");
|
|
5657
5658
|
const inputState = {
|
|
5658
5659
|
amount: 0n,
|
|
5659
5660
|
owner: hexToBytes(minterOwner),
|
|
@@ -5891,84 +5892,130 @@ export function createKcc20PsktBuilderEngine(options) {
|
|
|
5891
5892
|
async function buildKcc20SetPublicMintActivePskt(input) {
|
|
5892
5893
|
const request = input.request || {};
|
|
5893
5894
|
const params = request.params || {};
|
|
5894
|
-
const
|
|
5895
|
-
|
|
5895
|
+
const requestedMinterUtxos = Array.isArray(params.activeMinterUtxos) &&
|
|
5896
|
+
params.activeMinterUtxos.length > 0
|
|
5897
|
+
? params.activeMinterUtxos
|
|
5898
|
+
: params.activeMinterUtxo
|
|
5899
|
+
? [params.activeMinterUtxo]
|
|
5900
|
+
: [];
|
|
5901
|
+
if (requestedMinterUtxos.length === 0) {
|
|
5896
5902
|
throw new Error("active KCC20 mint-authority UTXO is required");
|
|
5897
5903
|
}
|
|
5898
5904
|
if (typeof params.active !== "boolean") {
|
|
5899
5905
|
throw new Error("active must be a boolean");
|
|
5900
5906
|
}
|
|
5901
5907
|
const covenantId = requireHex32(params.covenantId, "canonical covenant id");
|
|
5902
|
-
const network = request.network ||
|
|
5908
|
+
const network = request.network || env.KASPA_NETWORK || "testnet-10";
|
|
5903
5909
|
const walletAddress = requireKaspaAddress(request.owner?.walletAddress);
|
|
5904
5910
|
const walletOwner = requireHex32(request.owner?.kcc20Owner, "authenticated wallet owner");
|
|
5905
|
-
const minterAddress = requireKaspaAddress(activeMinterUtxo.address);
|
|
5906
|
-
const minterOwner = requireHex32(activeMinterUtxo.state?.owner ?? activeMinterUtxo.state?.ownerIdentifier, "active mint-authority owner");
|
|
5907
|
-
const minterOwnerScheme = parseOwnerScheme(activeMinterUtxo.state?.ownerScheme ??
|
|
5908
|
-
activeMinterUtxo.state?.identifierType ??
|
|
5909
|
-
0, "active mint-authority owner scheme");
|
|
5910
|
-
if (minterOwnerScheme !== 0) {
|
|
5911
|
-
throw new Error("public mint availability requires a pubkey-owned minter");
|
|
5912
|
-
}
|
|
5913
|
-
if (minterOwner !== walletOwner) {
|
|
5914
|
-
throw new Error("public mint availability requires authenticated wallet to own the active minter UTXO");
|
|
5915
|
-
}
|
|
5916
5911
|
const mintPolicy = params.mintPolicy || {};
|
|
5917
|
-
const remainingSupply = parsePositiveU64(activeMinterUtxo.state?.remainingSupply ?? mintPolicy.remainingSupply, "active mint-authority remaining supply");
|
|
5918
5912
|
const displayScale = parsePositiveU64(params.priceScale ??
|
|
5919
5913
|
params.tokenDisplayScale ??
|
|
5920
5914
|
DEFAULT_KCC20_PRICE_SCALE, "displayScale");
|
|
5921
|
-
const
|
|
5922
|
-
|
|
5915
|
+
const seenOutpoints = new Set();
|
|
5916
|
+
const laneContexts = (await Promise.all(requestedMinterUtxos.map(async (activeMinterUtxo, laneIndex) => {
|
|
5917
|
+
if (activeMinterUtxo.state?.isMintAuthority !== true ||
|
|
5918
|
+
parseMintPolicy(activeMinterUtxo.state?.mintPolicy) !== 2) {
|
|
5919
|
+
throw new Error("public mint availability requires public mint-authority lanes");
|
|
5920
|
+
}
|
|
5921
|
+
const minterAddress = requireKaspaAddress(activeMinterUtxo.address);
|
|
5922
|
+
const minterOwner = requireHex32(activeMinterUtxo.state?.owner ??
|
|
5923
|
+
activeMinterUtxo.state?.ownerIdentifier, "active mint-authority owner");
|
|
5924
|
+
const minterOwnerScheme = parseOwnerScheme(activeMinterUtxo.state?.ownerScheme ??
|
|
5925
|
+
activeMinterUtxo.state?.identifierType ??
|
|
5926
|
+
0, "active mint-authority owner scheme");
|
|
5927
|
+
if (minterOwnerScheme !== 0) {
|
|
5928
|
+
throw new Error("public mint availability requires a pubkey-owned minter");
|
|
5929
|
+
}
|
|
5930
|
+
if (minterOwner !== walletOwner) {
|
|
5931
|
+
throw new Error("public mint availability requires authenticated wallet to own every active minter UTXO");
|
|
5932
|
+
}
|
|
5933
|
+
const remainingSupply = parsePositiveU64(activeMinterUtxo.state?.remainingSupply ??
|
|
5934
|
+
mintPolicy.remainingSupply, "active mint-authority remaining supply");
|
|
5935
|
+
const extension = kcc20MintExtensionFromSources(activeMinterUtxo, params, mintPolicy, 2, remainingSupply, displayScale);
|
|
5936
|
+
if (extension.publicMintActive === params.active) {
|
|
5937
|
+
return null;
|
|
5938
|
+
}
|
|
5939
|
+
const inputState = {
|
|
5940
|
+
amount: 0n,
|
|
5941
|
+
owner: hexToBytes(minterOwner),
|
|
5942
|
+
ownerScheme: minterOwnerScheme,
|
|
5943
|
+
borrowScheme: 0,
|
|
5944
|
+
borrowGuard: hexToBytes(ZERO_HASH),
|
|
5945
|
+
extensionCommitment: mintExtensionCommitment(extension),
|
|
5946
|
+
};
|
|
5947
|
+
const nextExtension = {
|
|
5948
|
+
...extension,
|
|
5949
|
+
publicMintActive: params.active,
|
|
5950
|
+
};
|
|
5951
|
+
const outputState = {
|
|
5952
|
+
...inputState,
|
|
5953
|
+
extensionCommitment: mintExtensionCommitment(nextExtension),
|
|
5954
|
+
};
|
|
5955
|
+
const resolvedArtifact = await resolveKcc20ArtifactForState(inputState, minterAddress, network);
|
|
5956
|
+
dispatchTagFor(resolvedArtifact.artifact, "set_public_mint_active");
|
|
5957
|
+
const minterTxid = requireHex32(activeMinterUtxo.txidHex, "minter txid");
|
|
5958
|
+
const minterVout = parseVout(activeMinterUtxo.vout, "minter vout");
|
|
5959
|
+
const outpoint = `${minterTxid}:${minterVout}`;
|
|
5960
|
+
if (seenOutpoints.has(outpoint)) {
|
|
5961
|
+
throw new Error(`duplicate active minter outpoint ${outpoint}`);
|
|
5962
|
+
}
|
|
5963
|
+
seenOutpoints.add(outpoint);
|
|
5964
|
+
return {
|
|
5965
|
+
activeMinterUtxo,
|
|
5966
|
+
laneIndex,
|
|
5967
|
+
minterAddress,
|
|
5968
|
+
minterTxid,
|
|
5969
|
+
minterVout,
|
|
5970
|
+
outpoint,
|
|
5971
|
+
remainingSupply,
|
|
5972
|
+
extension,
|
|
5973
|
+
nextExtension,
|
|
5974
|
+
inputState,
|
|
5975
|
+
outputState,
|
|
5976
|
+
resolvedArtifact,
|
|
5977
|
+
};
|
|
5978
|
+
}))).filter(Boolean);
|
|
5979
|
+
if (laneContexts.length === 0) {
|
|
5923
5980
|
throw new Error(params.active
|
|
5924
5981
|
? "public mint is not paused"
|
|
5925
5982
|
: "public mint is not active");
|
|
5926
5983
|
}
|
|
5927
|
-
const
|
|
5928
|
-
amount: 0n,
|
|
5929
|
-
owner: hexToBytes(minterOwner),
|
|
5930
|
-
ownerScheme: minterOwnerScheme,
|
|
5931
|
-
borrowScheme: 0,
|
|
5932
|
-
borrowGuard: hexToBytes(ZERO_HASH),
|
|
5933
|
-
extensionCommitment: mintExtensionCommitment(extension),
|
|
5934
|
-
};
|
|
5935
|
-
const nextExtension = { ...extension, publicMintActive: params.active };
|
|
5936
|
-
const outputState = {
|
|
5937
|
-
...inputState,
|
|
5938
|
-
extensionCommitment: mintExtensionCommitment(nextExtension),
|
|
5939
|
-
};
|
|
5940
|
-
const resolvedArtifact = await resolveKcc20ArtifactForState(inputState, minterAddress, network);
|
|
5941
|
-
const artifact = resolvedArtifact.artifact;
|
|
5942
|
-
dispatchTagFor(artifact, "set_public_mint_active");
|
|
5943
|
-
const minterTxid = requireHex32(activeMinterUtxo.txidHex, "minter txid");
|
|
5944
|
-
const minterVout = parseVout(activeMinterUtxo.vout, "minter vout");
|
|
5945
|
-
const priorityFee = parseU64(process.env.KCC20_MINT_AVAILABILITY_PRIORITY_FEE_SOMPI ||
|
|
5984
|
+
const priorityFee = parseU64(env.KCC20_MINT_AVAILABILITY_PRIORITY_FEE_SOMPI ||
|
|
5946
5985
|
DEFAULT_PRIORITY_FEE.toString(), "priorityFee");
|
|
5947
|
-
const computeBudget = parsePositiveNumber(
|
|
5986
|
+
const computeBudget = parsePositiveNumber(env.KCC20_MINT_AVAILABILITY_COMPUTE_BUDGET ||
|
|
5948
5987
|
DEFAULT_COMPUTE_BUDGET, "computeBudget");
|
|
5949
5988
|
const rpc = new kaspaWasm.RpcClient({
|
|
5950
|
-
url:
|
|
5989
|
+
url: env.KASPA_WRPC_URL || DEFAULT_WRPC_URL,
|
|
5951
5990
|
encoding: kaspaWasm.Encoding.Borsh,
|
|
5952
5991
|
networkId: network,
|
|
5953
5992
|
});
|
|
5954
5993
|
await rpc.connect();
|
|
5955
5994
|
try {
|
|
5956
5995
|
const [minterUtxos, walletUtxos] = await Promise.all([
|
|
5957
|
-
getUtxosByAddresses(rpc, [
|
|
5996
|
+
getUtxosByAddresses(rpc, [
|
|
5997
|
+
...new Set(laneContexts.map((lane) => lane.minterAddress)),
|
|
5998
|
+
]),
|
|
5958
5999
|
getUtxosByAddresses(rpc, [walletAddress]),
|
|
5959
6000
|
]);
|
|
5960
|
-
const
|
|
5961
|
-
|
|
5962
|
-
|
|
5963
|
-
|
|
5964
|
-
|
|
5965
|
-
|
|
6001
|
+
const resolvedLanes = laneContexts.map((lane, laneIndex) => {
|
|
6002
|
+
const minterEntry = findUtxoEntry(minterUtxos.entries, lane.minterTxid, lane.minterVout);
|
|
6003
|
+
if (!minterEntry) {
|
|
6004
|
+
throw new Error(`active minter UTXO ${lane.outpoint} not found`);
|
|
6005
|
+
}
|
|
6006
|
+
const spendCovenantId = requireMatchingCovenantId(minterEntry, covenantId, `active minter lane ${laneIndex}`);
|
|
6007
|
+
return {
|
|
6008
|
+
...lane,
|
|
6009
|
+
laneIndex,
|
|
6010
|
+
minterEntry,
|
|
6011
|
+
spendCovenantId,
|
|
6012
|
+
minterInputSompi: BigInt(minterEntry.amount),
|
|
6013
|
+
};
|
|
6014
|
+
});
|
|
5966
6015
|
const fundingEntry = selectFundingEntry(walletUtxos.entries, priorityFee + 10000n);
|
|
5967
|
-
const fundingInputIndex =
|
|
6016
|
+
const fundingInputIndex = resolvedLanes.length;
|
|
5968
6017
|
const fundingChange = BigInt(fundingEntry.amount) - priorityFee;
|
|
5969
|
-
const outputs =
|
|
5970
|
-
tokenOutput(kaspaWasm, artifact, outputState, minterInputSompi, spendCovenantId, 0),
|
|
5971
|
-
];
|
|
6018
|
+
const outputs = resolvedLanes.map((lane, laneIndex) => tokenOutput(kaspaWasm, lane.resolvedArtifact.artifact, lane.outputState, lane.minterInputSompi, lane.spendCovenantId, laneIndex));
|
|
5972
6019
|
let fundingChangeOutputIndex = -1;
|
|
5973
6020
|
if (fundingChange > 10000n) {
|
|
5974
6021
|
fundingChangeOutputIndex = outputs.length;
|
|
@@ -5978,13 +6025,13 @@ export function createKcc20PsktBuilderEngine(options) {
|
|
|
5978
6025
|
version: 1,
|
|
5979
6026
|
lockTime: 0n,
|
|
5980
6027
|
inputs: [
|
|
5981
|
-
{
|
|
5982
|
-
previousOutpoint: minterEntry.outpoint,
|
|
5983
|
-
utxo: minterEntry,
|
|
6028
|
+
...resolvedLanes.map((lane) => ({
|
|
6029
|
+
previousOutpoint: lane.minterEntry.outpoint,
|
|
6030
|
+
utxo: lane.minterEntry,
|
|
5984
6031
|
sequence: 0n,
|
|
5985
6032
|
sigOpCount: 0,
|
|
5986
6033
|
computeBudget,
|
|
5987
|
-
},
|
|
6034
|
+
})),
|
|
5988
6035
|
{
|
|
5989
6036
|
previousOutpoint: fundingEntry.outpoint,
|
|
5990
6037
|
utxo: fundingEntry,
|
|
@@ -5999,25 +6046,29 @@ export function createKcc20PsktBuilderEngine(options) {
|
|
|
5999
6046
|
payload: new Uint8Array(),
|
|
6000
6047
|
});
|
|
6001
6048
|
setVersionOneInputMassFields(unsignedTx, computeBudget);
|
|
6002
|
-
|
|
6003
|
-
|
|
6004
|
-
|
|
6049
|
+
unsignedTx.inputs[fundingInputIndex].computeBudget = 30;
|
|
6050
|
+
const scripts = resolvedLanes.map((lane, laneIndex) => ({
|
|
6051
|
+
inputIndex: laneIndex,
|
|
6052
|
+
scriptHex: bytesToHex(lane.resolvedArtifact.script),
|
|
6005
6053
|
signType: 1,
|
|
6006
6054
|
signatureScript: {
|
|
6007
6055
|
mode: "ordered-args",
|
|
6008
|
-
args: kcc20SetPublicMintActiveOrderedArgs(artifact, extension, params.active,
|
|
6056
|
+
args: kcc20SetPublicMintActiveOrderedArgs(lane.resolvedArtifact.artifact, lane.extension, params.active, laneIndex),
|
|
6009
6057
|
},
|
|
6010
|
-
};
|
|
6058
|
+
}));
|
|
6011
6059
|
const predictSignedTransaction = (transaction) => {
|
|
6012
6060
|
const predicted = cloneTransactionForMassPreflight(kaspaWasm, transaction, "KCC20 public mint availability");
|
|
6013
6061
|
const dummySignature = dummySignatureBytes();
|
|
6014
|
-
|
|
6015
|
-
|
|
6016
|
-
|
|
6017
|
-
|
|
6018
|
-
|
|
6062
|
+
resolvedLanes.forEach((lane, laneIndex) => {
|
|
6063
|
+
const prefix = buildKcc20SetPublicMintActiveSigScript(kaspaWasm, lane.resolvedArtifact.artifact, {
|
|
6064
|
+
extension: lane.extension,
|
|
6065
|
+
authoritySignature: dummySignature,
|
|
6066
|
+
active: params.active,
|
|
6067
|
+
minterOutputIndex: laneIndex,
|
|
6068
|
+
});
|
|
6069
|
+
predicted.inputs[laneIndex].signatureScript =
|
|
6070
|
+
encodeCovenantP2shSignatureScript(prefix, lane.resolvedArtifact.script);
|
|
6019
6071
|
});
|
|
6020
|
-
predicted.inputs[0].signatureScript = encodeCovenantP2shSignatureScript(prefix, resolvedArtifact.script);
|
|
6021
6072
|
predicted.inputs[fundingInputIndex].signatureScript =
|
|
6022
6073
|
encodeP2pkSignatureScript(bytesToHex(dummySignature));
|
|
6023
6074
|
return predicted;
|
|
@@ -6031,21 +6082,28 @@ export function createKcc20PsktBuilderEngine(options) {
|
|
|
6031
6082
|
schema: OUTPUT_SCHEMA,
|
|
6032
6083
|
psktTransactionJson,
|
|
6033
6084
|
signInputs: [{ index: fundingInputIndex, sighashType: 1 }],
|
|
6034
|
-
scripts
|
|
6085
|
+
scripts,
|
|
6035
6086
|
submitTransactionSupported: true,
|
|
6036
6087
|
metadata: {
|
|
6037
6088
|
builderKey: "kcc20.set-public-mint-active",
|
|
6038
6089
|
contract: "KCC20",
|
|
6039
6090
|
network,
|
|
6040
6091
|
walletAddress,
|
|
6041
|
-
covenantId
|
|
6042
|
-
minterOutpoint:
|
|
6092
|
+
covenantId,
|
|
6093
|
+
minterOutpoint: resolvedLanes[0].outpoint,
|
|
6094
|
+
minterOutpoints: resolvedLanes.map((lane) => lane.outpoint),
|
|
6043
6095
|
minterOutputIndex: 0,
|
|
6096
|
+
minterOutputIndexes: resolvedLanes.map((_, index) => index),
|
|
6097
|
+
mintLaneCount: Number(resolvedLanes[0].extension.mintLaneCount),
|
|
6098
|
+
updatedMintLaneCount: resolvedLanes.length,
|
|
6044
6099
|
publicMintActive: params.active,
|
|
6045
6100
|
mintPolicy: 2,
|
|
6046
|
-
remainingSupply: remainingSupply.toString(),
|
|
6047
|
-
|
|
6048
|
-
|
|
6101
|
+
remainingSupply: resolvedLanes[0].remainingSupply.toString(),
|
|
6102
|
+
remainingSupplies: resolvedLanes.map((lane) => lane.remainingSupply.toString()),
|
|
6103
|
+
extension: jsonKcc20MintExtension(resolvedLanes[0].nextExtension),
|
|
6104
|
+
extensions: resolvedLanes.map((lane) => jsonKcc20MintExtension(lane.nextExtension)),
|
|
6105
|
+
artifactVersion: resolvedLanes[0].resolvedArtifact.version,
|
|
6106
|
+
artifactVersions: resolvedLanes.map((lane) => lane.resolvedArtifact.version),
|
|
6049
6107
|
},
|
|
6050
6108
|
};
|
|
6051
6109
|
}
|
|
@@ -6102,16 +6160,16 @@ export function createKcc20PsktBuilderEngine(options) {
|
|
|
6102
6160
|
const covenantId = requireHex32(params.activeHolderNativeCovenantId || params.covenantId, "canonical covenant id");
|
|
6103
6161
|
const appCanonicalTokenId = requireHex32(params.appCanonicalCovenantId || params.covenantId || covenantId, "app canonical token id");
|
|
6104
6162
|
const owner = requireHex32(request.owner?.kcc20Owner, "token owner");
|
|
6105
|
-
const network = request.network ||
|
|
6163
|
+
const network = request.network || env.KASPA_NETWORK || "testnet-10";
|
|
6106
6164
|
const walletAddress = requireKaspaAddress(request.owner?.walletAddress);
|
|
6107
|
-
const rpcUrl =
|
|
6108
|
-
const priorityFee = parseU64(
|
|
6109
|
-
|
|
6165
|
+
const rpcUrl = env.KASPA_WRPC_URL || DEFAULT_WRPC_URL;
|
|
6166
|
+
const priorityFee = parseU64(env.KCC20_CONSOLIDATE_PRIORITY_FEE_SOMPI ||
|
|
6167
|
+
env.KCC20_TRANSFER_PRIORITY_FEE_SOMPI ||
|
|
6110
6168
|
DEFAULT_PRIORITY_FEE.toString(), "priorityFee");
|
|
6111
|
-
const configuredPrimaryComputeBudget = parsePositiveNumber(
|
|
6112
|
-
|
|
6169
|
+
const configuredPrimaryComputeBudget = parsePositiveNumber(env.KCC20_CONSOLIDATE_COMPUTE_BUDGET ||
|
|
6170
|
+
env.KCC20_TRANSFER_COMPUTE_BUDGET ||
|
|
6113
6171
|
DEFAULT_COMPUTE_BUDGET, "configuredPrimaryComputeBudget");
|
|
6114
|
-
const peerComputeBudget = parsePositiveNumber(
|
|
6172
|
+
const peerComputeBudget = parsePositiveNumber(env.KCC20_CONSOLIDATE_PEER_COMPUTE_BUDGET || 200, "peerComputeBudget");
|
|
6115
6173
|
const computeBudget = Math.max(configuredPrimaryComputeBudget, 500 + holderUtxos.length * 100);
|
|
6116
6174
|
const states = holderUtxos.map((utxo) => kcc20StateFromUtxo(utxo, request.owner));
|
|
6117
6175
|
const primaryState = states[0];
|
|
@@ -6272,12 +6330,12 @@ export function createKcc20PsktBuilderEngine(options) {
|
|
|
6272
6330
|
const params = request.params || {};
|
|
6273
6331
|
const covenantId = requireHex32(params.covenantId, "canonical covenant id");
|
|
6274
6332
|
const owner = requireHex32(request.owner?.kcc20Owner, "token owner");
|
|
6275
|
-
const network = request.network ||
|
|
6333
|
+
const network = request.network || env.KASPA_NETWORK || "testnet-10";
|
|
6276
6334
|
const walletAddress = requireKaspaAddress(request.owner?.walletAddress);
|
|
6277
|
-
const rpcUrl =
|
|
6278
|
-
const priorityFee = parseU64(
|
|
6335
|
+
const rpcUrl = env.KASPA_WRPC_URL || DEFAULT_WRPC_URL;
|
|
6336
|
+
const priorityFee = parseU64(env.KCC20_REVEAL_PRIORITY_FEE_SOMPI ||
|
|
6279
6337
|
DEFAULT_PRIORITY_FEE.toString(), "priorityFee");
|
|
6280
|
-
const computeBudget = parsePositiveNumber(
|
|
6338
|
+
const computeBudget = parsePositiveNumber(env.KCC20_REVEAL_COMPUTE_BUDGET || DEFAULT_COMPUTE_BUDGET, "computeBudget");
|
|
6281
6339
|
const inputState = kcc20StateFromUtxo(activeTokenUtxo, request.owner);
|
|
6282
6340
|
if (inputState.isMintAuthority) {
|
|
6283
6341
|
throw new Error("self-transfer reveal requires a KCC20 holder UTXO");
|
|
@@ -6412,14 +6470,14 @@ export function createKcc20PsktBuilderEngine(options) {
|
|
|
6412
6470
|
const recipientOwner = requireHex32(params.recipientOwner, "transfer recipient owner");
|
|
6413
6471
|
const recipientOwnerScheme = parseOwnerScheme(params.recipientOwnerScheme ?? params.recipientOwnerType ?? 0, "recipientOwnerScheme");
|
|
6414
6472
|
const transferAmount = parsePositiveU64(params.tokenAmount, "tokenAmount");
|
|
6415
|
-
const network = request.network ||
|
|
6473
|
+
const network = request.network || env.KASPA_NETWORK || "testnet-10";
|
|
6416
6474
|
const walletAddress = requireKaspaAddress(request.owner?.walletAddress);
|
|
6417
|
-
const rpcUrl =
|
|
6418
|
-
const tokenOutputSompi = assertKcc20TokenOutputSompi(parseU64(
|
|
6475
|
+
const rpcUrl = env.KASPA_WRPC_URL || DEFAULT_WRPC_URL;
|
|
6476
|
+
const tokenOutputSompi = assertKcc20TokenOutputSompi(parseU64(env.KCC20_TRANSFER_TOKEN_OUTPUT_SOMPI ||
|
|
6419
6477
|
DEFAULT_TOKEN_OUTPUT_SOMPI.toString(), "tokenOutputSompi"), "transfer");
|
|
6420
|
-
const priorityFee = parseU64(
|
|
6478
|
+
const priorityFee = parseU64(env.KCC20_TRANSFER_PRIORITY_FEE_SOMPI ||
|
|
6421
6479
|
DEFAULT_PRIORITY_FEE.toString(), "priorityFee");
|
|
6422
|
-
const computeBudget = parsePositiveNumber(
|
|
6480
|
+
const computeBudget = parsePositiveNumber(env.KCC20_TRANSFER_COMPUTE_BUDGET || DEFAULT_COMPUTE_BUDGET, "computeBudget");
|
|
6423
6481
|
const inputState = kcc20StateFromUtxo(activeHolderUtxo, request.owner);
|
|
6424
6482
|
if (inputState.isMintAuthority || inputState.amount <= 0n) {
|
|
6425
6483
|
throw new Error("KCC20 transfer requires a holder UTXO");
|
|
@@ -6588,15 +6646,15 @@ export function createKcc20PsktBuilderEngine(options) {
|
|
|
6588
6646
|
const mintPolicy = parseMintPolicy(params.mintPolicy || mintPolicyName(params.mintPolicyValue ?? 0));
|
|
6589
6647
|
const mintPriceSompi = parseU64(params.mintPricePerTokenSompi || "0", "mintPricePerTokenSompi");
|
|
6590
6648
|
const feeBps = parseFeeBps(params.protocolFeeBps ??
|
|
6591
|
-
|
|
6649
|
+
env.KCC20_PROTOCOL_FEE_BPS ??
|
|
6592
6650
|
DEFAULT_KCC20_FEE_BPS);
|
|
6593
6651
|
const decimals = parseU64(params.decimals ?? "0", "decimals");
|
|
6594
6652
|
const priceScale = 10n ** decimals;
|
|
6595
|
-
const network = request.network ||
|
|
6653
|
+
const network = request.network || env.KASPA_NETWORK || "testnet-10";
|
|
6596
6654
|
const walletAddress = requireKaspaAddress(request.owner?.walletAddress);
|
|
6597
|
-
const rpcUrl =
|
|
6598
|
-
const amountTkas = parseAmountTkas(
|
|
6599
|
-
const priorityFee = parseU64(
|
|
6655
|
+
const rpcUrl = env.KASPA_WRPC_URL || DEFAULT_WRPC_URL;
|
|
6656
|
+
const amountTkas = parseAmountTkas(env.KCC20_DEPLOY_OUTPUT_TKAS || DEFAULT_DEPLOY_TKAS);
|
|
6657
|
+
const priorityFee = parseU64(env.KCC20_DEPLOY_PRIORITY_FEE_SOMPI ||
|
|
6600
6658
|
DEFAULT_PRIORITY_FEE.toString(), "priorityFee");
|
|
6601
6659
|
const metadata = {
|
|
6602
6660
|
ticker: normalizeTicker(params.ticker || ""),
|
|
@@ -6613,6 +6671,12 @@ export function createKcc20PsktBuilderEngine(options) {
|
|
|
6613
6671
|
const artifact = await readStaticArtifact(KCC20_ARTIFACT_PATH);
|
|
6614
6672
|
const displayScale = priceScale;
|
|
6615
6673
|
const remainingSupply = maxSupply - premintSupply;
|
|
6674
|
+
const mintLaneCount = mintPolicy === 0
|
|
6675
|
+
? 1n
|
|
6676
|
+
: parseMintLaneCount(params.mintLaneCount ?? 1, "mintLaneCount");
|
|
6677
|
+
const mintLaneSupplies = mintPolicy === 0
|
|
6678
|
+
? []
|
|
6679
|
+
: splitKcc20MintSupply(remainingSupply, mintLaneCount);
|
|
6616
6680
|
const immutableExtension = {
|
|
6617
6681
|
kind: 1,
|
|
6618
6682
|
creator: hexToBytes(owner),
|
|
@@ -6620,8 +6684,7 @@ export function createKcc20PsktBuilderEngine(options) {
|
|
|
6620
6684
|
name: asciiToBytes32(metadata.name, "token name"),
|
|
6621
6685
|
displayScale,
|
|
6622
6686
|
maxSupply,
|
|
6623
|
-
|
|
6624
|
-
mintLaneCount: 1n,
|
|
6687
|
+
mintLaneCount,
|
|
6625
6688
|
mintPolicy,
|
|
6626
6689
|
mintPriceSompi,
|
|
6627
6690
|
treasury: hexToBytes(treasury),
|
|
@@ -6629,23 +6692,32 @@ export function createKcc20PsktBuilderEngine(options) {
|
|
|
6629
6692
|
protocolFeeBps: BigInt(feeBps),
|
|
6630
6693
|
};
|
|
6631
6694
|
const holderCommitment = holderExtensionCommitment(immutableExtension);
|
|
6632
|
-
const
|
|
6695
|
+
const baseExtension = mintPolicy === 0
|
|
6633
6696
|
? null
|
|
6634
6697
|
: {
|
|
6635
6698
|
...immutableExtension,
|
|
6636
|
-
remainingSupply,
|
|
6637
6699
|
publicMintActive: false,
|
|
6638
6700
|
holderExtensionCommitment: holderCommitment,
|
|
6639
6701
|
};
|
|
6702
|
+
const minterStates = baseExtension
|
|
6703
|
+
? mintLaneSupplies.map((laneSupply) => {
|
|
6704
|
+
const extension = { ...baseExtension, remainingSupply: laneSupply };
|
|
6705
|
+
return {
|
|
6706
|
+
extension,
|
|
6707
|
+
state: {
|
|
6708
|
+
amount: 0n,
|
|
6709
|
+
owner: hexToBytes(owner),
|
|
6710
|
+
ownerScheme: 0,
|
|
6711
|
+
borrowScheme: 0,
|
|
6712
|
+
borrowGuard: hexToBytes(ZERO_HASH),
|
|
6713
|
+
extensionCommitment: mintExtensionCommitment(extension),
|
|
6714
|
+
},
|
|
6715
|
+
};
|
|
6716
|
+
})
|
|
6717
|
+
: [];
|
|
6718
|
+
const extension = minterStates[0]?.extension ?? null;
|
|
6640
6719
|
const state = extension
|
|
6641
|
-
?
|
|
6642
|
-
amount: 0n,
|
|
6643
|
-
owner: hexToBytes(owner),
|
|
6644
|
-
ownerScheme: 0,
|
|
6645
|
-
borrowScheme: 0,
|
|
6646
|
-
borrowGuard: hexToBytes(ZERO_HASH),
|
|
6647
|
-
extensionCommitment: mintExtensionCommitment(extension),
|
|
6648
|
-
}
|
|
6720
|
+
? minterStates[0].state
|
|
6649
6721
|
: {
|
|
6650
6722
|
amount: maxSupply,
|
|
6651
6723
|
owner: hexToBytes(premintRecipient),
|
|
@@ -6664,19 +6736,26 @@ export function createKcc20PsktBuilderEngine(options) {
|
|
|
6664
6736
|
extensionCommitment: holderCommitment,
|
|
6665
6737
|
}
|
|
6666
6738
|
: null;
|
|
6739
|
+
const covenantStates = extension
|
|
6740
|
+
? minterStates.map(({ state }) => state)
|
|
6741
|
+
: [state];
|
|
6742
|
+
if (premintState)
|
|
6743
|
+
covenantStates.push(premintState);
|
|
6667
6744
|
const kw = kaspaWasm;
|
|
6668
6745
|
const { Encoding, GenesisCovenantGroup, RpcClient, Transaction, TransactionOutput, addressFromScriptPublicKey, payToAddressScript, payToScriptHashScript, } = kw;
|
|
6669
|
-
const
|
|
6670
|
-
|
|
6671
|
-
|
|
6672
|
-
|
|
6746
|
+
const covenantOutputs = covenantStates.map((covenantState) => {
|
|
6747
|
+
const script = buildKcc20ScriptForState(artifact, covenantState);
|
|
6748
|
+
const scriptPublicKey = payToScriptHashScript(script);
|
|
6749
|
+
return {
|
|
6750
|
+
script,
|
|
6751
|
+
scriptPublicKey,
|
|
6752
|
+
address: addressFromScriptPublicKey(scriptPublicKey, network).toString(),
|
|
6753
|
+
};
|
|
6754
|
+
});
|
|
6755
|
+
const contractAddress = covenantOutputs[0].address;
|
|
6756
|
+
const canonicalCovenantId = p2shScriptHashHex(kw, covenantOutputs[0].script);
|
|
6673
6757
|
const deploySompi = BigInt(Math.round(amountTkas * Number(SOMPI_PER_TKAS)));
|
|
6674
|
-
const
|
|
6675
|
-
let premintAddress = null;
|
|
6676
|
-
if (premintState) {
|
|
6677
|
-
premintAddress = addressFromScriptPublicKey(payToScriptHashScript(buildKcc20ScriptForState(artifact, premintState)), network).toString();
|
|
6678
|
-
deployOutputs.push({ address: premintAddress, amount: deploySompi });
|
|
6679
|
-
}
|
|
6758
|
+
const premintOutputIndex = premintState ? covenantOutputs.length - 1 : null;
|
|
6680
6759
|
const rpc = new RpcClient({
|
|
6681
6760
|
url: rpcUrl,
|
|
6682
6761
|
encoding: Encoding.Borsh,
|
|
@@ -6685,20 +6764,17 @@ export function createKcc20PsktBuilderEngine(options) {
|
|
|
6685
6764
|
await rpc.connect();
|
|
6686
6765
|
try {
|
|
6687
6766
|
const utxos = await getUtxosByAddresses(rpc, [walletAddress]);
|
|
6688
|
-
const outputSompi = deploySompi * BigInt(
|
|
6767
|
+
const outputSompi = deploySompi * BigInt(covenantOutputs.length);
|
|
6689
6768
|
const fundingEntry = selectFundingEntry(utxos.entries, outputSompi + priorityFee + 10000000n);
|
|
6690
|
-
const fundingChangeOutputIndex =
|
|
6769
|
+
const fundingChangeOutputIndex = covenantOutputs.length;
|
|
6691
6770
|
const change = utxoAmountSompi(fundingEntry) - outputSompi - priorityFee;
|
|
6692
6771
|
if (change <= 10000n) {
|
|
6693
6772
|
throw kcc20PsktBuilderError("deploy PSKT builder selected insufficient change", "KAS_FUNDING_CHANGE_TOO_SMALL");
|
|
6694
6773
|
}
|
|
6695
6774
|
const outputs = [
|
|
6696
|
-
new TransactionOutput(deploySompi,
|
|
6775
|
+
...covenantOutputs.map(({ scriptPublicKey }) => new TransactionOutput(deploySompi, scriptPublicKey)),
|
|
6697
6776
|
new TransactionOutput(change, payToAddressScript(walletAddress)),
|
|
6698
6777
|
];
|
|
6699
|
-
if (premintState) {
|
|
6700
|
-
outputs.push(new TransactionOutput(deploySompi, payToScriptHashScript(buildKcc20ScriptForState(artifact, premintState))));
|
|
6701
|
-
}
|
|
6702
6778
|
const unsignedTx = new Transaction({
|
|
6703
6779
|
version: 1,
|
|
6704
6780
|
lockTime: 0n,
|
|
@@ -6733,17 +6809,8 @@ export function createKcc20PsktBuilderEngine(options) {
|
|
|
6733
6809
|
});
|
|
6734
6810
|
unsignedTx.version = 1;
|
|
6735
6811
|
setVersionOneInputMassFields(unsignedTx);
|
|
6736
|
-
const covenantOutputIndex =
|
|
6737
|
-
|
|
6738
|
-
throw new Error("final transaction did not contain the KCC20 output");
|
|
6739
|
-
const covenantOutputIndexes = [covenantOutputIndex];
|
|
6740
|
-
let premintOutputIndex = null;
|
|
6741
|
-
if (premintAddress) {
|
|
6742
|
-
premintOutputIndex = findOutputIndex(unsignedTx, premintAddress, network, addressFromScriptPublicKey);
|
|
6743
|
-
if (premintOutputIndex < 0)
|
|
6744
|
-
throw new Error("final transaction did not contain the KCC20 premint output");
|
|
6745
|
-
covenantOutputIndexes.push(premintOutputIndex);
|
|
6746
|
-
}
|
|
6812
|
+
const covenantOutputIndex = 0;
|
|
6813
|
+
const covenantOutputIndexes = covenantOutputs.map((_, index) => index);
|
|
6747
6814
|
unsignedTx.populateGenesisCovenants([
|
|
6748
6815
|
new GenesisCovenantGroup(0, covenantOutputIndexes),
|
|
6749
6816
|
]);
|
|
@@ -6756,6 +6823,7 @@ export function createKcc20PsktBuilderEngine(options) {
|
|
|
6756
6823
|
if (typeof psktTransactionJson !== "string") {
|
|
6757
6824
|
throw new Error("KCC20 deploy PSKT serialization did not return JSON text");
|
|
6758
6825
|
}
|
|
6826
|
+
const revealScriptHex = bytesToHex(covenantOutputs[covenantOutputIndex].script);
|
|
6759
6827
|
return {
|
|
6760
6828
|
schema: OUTPUT_SCHEMA,
|
|
6761
6829
|
psktTransactionJson,
|
|
@@ -6771,6 +6839,9 @@ export function createKcc20PsktBuilderEngine(options) {
|
|
|
6771
6839
|
walletAddress,
|
|
6772
6840
|
contractAddress,
|
|
6773
6841
|
covenantOutputIndex,
|
|
6842
|
+
minterOutputIndexes: extension
|
|
6843
|
+
? minterStates.map((_, index) => index)
|
|
6844
|
+
: undefined,
|
|
6774
6845
|
premintOutputIndex,
|
|
6775
6846
|
covenantId: kip20BindingCovenantId,
|
|
6776
6847
|
scriptHashHex: canonicalCovenantId,
|
|
@@ -6781,6 +6852,44 @@ export function createKcc20PsktBuilderEngine(options) {
|
|
|
6781
6852
|
mintPolicy,
|
|
6782
6853
|
publicMintActive: mintPolicy === 2 ? false : undefined,
|
|
6783
6854
|
mintLaneCount: immutableExtension.mintLaneCount.toString(),
|
|
6855
|
+
holderExtensionCommitment: bytesToHex(holderCommitment),
|
|
6856
|
+
revealScriptHex,
|
|
6857
|
+
maximumFeeSompi: ([...feeAdjustedTx.inputs].reduce((sum, input) => sum + BigInt(input.utxo?.amount ?? input.utxo?.value), 0n) -
|
|
6858
|
+
[...feeAdjustedTx.outputs].reduce((sum, output) => sum + BigInt(output.value ?? output.amount), 0n)).toString(),
|
|
6859
|
+
intentInputs: [{ role: "creator-funding", index: 0 }],
|
|
6860
|
+
intentOutputs: buildKcc20DeployIntentOutputs({
|
|
6861
|
+
mintPolicy,
|
|
6862
|
+
covenantId: kip20BindingCovenantId,
|
|
6863
|
+
creator: owner,
|
|
6864
|
+
premintRecipient,
|
|
6865
|
+
premintOwnerScheme,
|
|
6866
|
+
maxSupply,
|
|
6867
|
+
premintSupply,
|
|
6868
|
+
borrowGuard: ZERO_HASH,
|
|
6869
|
+
fixedOutput: mintPolicy === 0
|
|
6870
|
+
? {
|
|
6871
|
+
index: covenantOutputIndex,
|
|
6872
|
+
revealScriptHex,
|
|
6873
|
+
extensionCommitment: bytesToHex(holderCommitment),
|
|
6874
|
+
}
|
|
6875
|
+
: undefined,
|
|
6876
|
+
minterOutputs: minterStates.map(({ state }, index) => ({
|
|
6877
|
+
index,
|
|
6878
|
+
revealScriptHex: bytesToHex(covenantOutputs[index].script),
|
|
6879
|
+
extensionCommitment: bytesToHex(state.extensionCommitment),
|
|
6880
|
+
remainingSupply: mintLaneSupplies[index],
|
|
6881
|
+
})),
|
|
6882
|
+
premintOutput: premintState && premintOutputIndex !== null
|
|
6883
|
+
? {
|
|
6884
|
+
index: premintOutputIndex,
|
|
6885
|
+
revealScriptHex: bytesToHex(covenantOutputs[premintOutputIndex].script),
|
|
6886
|
+
extensionCommitment: bytesToHex(premintState.extensionCommitment),
|
|
6887
|
+
}
|
|
6888
|
+
: undefined,
|
|
6889
|
+
}),
|
|
6890
|
+
mintLaneSupplies: extension
|
|
6891
|
+
? mintLaneSupplies.map((supply) => supply.toString())
|
|
6892
|
+
: undefined,
|
|
6784
6893
|
extension: extension ? jsonKcc20MintExtension(extension) : undefined,
|
|
6785
6894
|
...stateToReceiptFields(state),
|
|
6786
6895
|
},
|
|
@@ -6796,11 +6905,11 @@ export function createKcc20PsktBuilderEngine(options) {
|
|
|
6796
6905
|
const owner = requireHex32(params.rootOwner || request.owner?.kcc20Owner, "root owner");
|
|
6797
6906
|
const utilityTokenId = requireHex32(params.utilityTokenId, "utility token id");
|
|
6798
6907
|
const denomination = parsePositiveU64(params.utilityTokenAmount, "utilityTokenAmount");
|
|
6799
|
-
const network = request.network ||
|
|
6908
|
+
const network = request.network || env.KASPA_NETWORK || "testnet-10";
|
|
6800
6909
|
const walletAddress = requireKaspaAddress(request.owner?.walletAddress);
|
|
6801
|
-
const rpcUrl =
|
|
6802
|
-
const amountTkas = parseAmountTkas(
|
|
6803
|
-
const priorityFee = parseU64(
|
|
6910
|
+
const rpcUrl = env.KASPA_WRPC_URL || DEFAULT_WRPC_URL;
|
|
6911
|
+
const amountTkas = parseAmountTkas(env.KCC20_FEE_TICKET_OUTPUT_TKAS || DEFAULT_DEPLOY_TKAS);
|
|
6912
|
+
const priorityFee = parseU64(env.KCC20_FEE_TICKET_PRIORITY_FEE_SOMPI ||
|
|
6804
6913
|
DEFAULT_PRIORITY_FEE.toString(), "priorityFee");
|
|
6805
6914
|
const artifact = await readStaticArtifact(FEE_TICKET_ARTIFACT_PATH);
|
|
6806
6915
|
const state = {
|
|
@@ -7793,8 +7902,8 @@ export function createKcc20PsktBuilderEngine(options) {
|
|
|
7793
7902
|
return rpc.getUtxosByAddresses({ addresses });
|
|
7794
7903
|
}
|
|
7795
7904
|
async function retryUtxosByAddresses(rpc, addresses, isReady, initial) {
|
|
7796
|
-
const attempts = parseRetryInteger(
|
|
7797
|
-
const delayMs = parseRetryInteger(
|
|
7905
|
+
const attempts = parseRetryInteger(env.KCC20_SOURCE_UTXO_RETRY_ATTEMPTS, 3);
|
|
7906
|
+
const delayMs = parseRetryInteger(env.KCC20_SOURCE_UTXO_RETRY_DELAY_MS, 500);
|
|
7798
7907
|
let latest = initial ?? { entries: [] };
|
|
7799
7908
|
for (let attempt = 1; attempt < attempts; attempt += 1) {
|
|
7800
7909
|
if (delayMs > 0) {
|
|
@@ -8963,6 +9072,7 @@ export function createKcc20PsktBuilderEngine(options) {
|
|
|
8963
9072
|
assertTransactionStorageMassStandard,
|
|
8964
9073
|
calculateToccataStorageMass,
|
|
8965
9074
|
parseQuotedProtocolFeeSompi,
|
|
9075
|
+
splitKcc20MintSupply,
|
|
8966
9076
|
}),
|
|
8967
9077
|
};
|
|
8968
9078
|
}
|