@kronsdk/kron-sdk 0.4.0 → 0.6.0

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/README.md CHANGED
@@ -4,10 +4,18 @@
4
4
  — a bonding-curve launchpad + AMM DEX — from any JS/TS environment.** Browser or Node. No custody, ever:
5
5
  this package only *builds* transactions; a wallet (yours, or your user's) signs them.
6
6
 
7
- > **Status: v0.2.1, testnet (TN10).** Read paths and the covenant builders are proven byte-identical to
7
+ > **Status: v0.6.0, testnet (TN10).** Read paths and the covenant builders are proven byte-identical to
8
8
  > KRON's own production code (see "Verification" below). Wallet signing is a documented interface plus a
9
9
  > generic reference implementation — see [`docs/WALLETS.md`](docs/WALLETS.md) for the contract and how to
10
10
  > adapt it to a specific wallet's injected provider.
11
+ >
12
+ > **⚠️ Upgrade from < 0.6.0.** Every earlier release built **version-0** transactions, which cannot carry
13
+ > the covenant bindings Kaspa's covenant layer (KIP-20) requires on output — every assembled spend was
14
+ > rejected on-chain with `script ran, but verification failed`. 0.5.0 fixed `assembleNativeTx` (v1 txs +
15
+ > compute budgets) and the kcc20 builders; 0.6.0 finishes the job for the curve, pool/LP, and vesting
16
+ > builders (buy/sell/graduate, swap, add/removeLiquidity, bindLp, claim) — they now attach the required
17
+ > `CovOutput.binding` automatically. See the [CHANGELOG](CHANGELOG.md) for the migration notes if you
18
+ > assembled transactions by hand instead of via `spend.assembleNativeTx`.
11
19
 
12
20
  ## Why this exists
13
21
 
@@ -34,11 +42,12 @@ ESM only (`"type": "module"`) in v1 — see [Design notes](#design-notes) for wh
34
42
 
35
43
  ```bash
36
44
  npm install @kronsdk/kron-sdk@latest # newest
37
- npm install @kronsdk/kron-sdk@0.2.0 # or pin an exact version for reproducible builds
45
+ npm install @kronsdk/kron-sdk@0.6.0 # or pin an exact version for reproducible builds
38
46
  ```
39
47
 
40
- The package follows semver. The token-list client (`client.RegistryClient.tokenlist()`) and on-chain
41
- verifier (`verify.verifyTokenListEntry`) landed in **0.2.0** — see [Discover & verify tokens](#discover--verify-tokens-token-list).
48
+ The package follows semver. **0.6.0 is a required upgrade for anyone building curve/pool/LP/vesting
49
+ transactions** — see the warning above. The token-list client (`client.RegistryClient.tokenlist()`) and
50
+ on-chain verifier (`verify.verifyTokenListEntry`) landed in **0.2.0** — see [Discover & verify tokens](#discover--verify-tokens-token-list).
42
51
 
43
52
  ## Quickstart — quote a curve buy (Node)
44
53
 
package/dist/index.d.ts CHANGED
@@ -140,6 +140,21 @@ declare namespace genesis {
140
140
 
141
141
  type K$5 = Kaspa;
142
142
  type Spk$4 = any;
143
+ /** Covenant txs are KIP-20 v1 transactions (covenant outputs require tx.version >= 1). */
144
+ declare const TX_VERSION = 1;
145
+ /** Per-input compute budget (v1): a P2PK funding input ≈ one sig op. */
146
+ declare const FUNDING_COMPUTE = 10;
147
+ /** Per-input compute budget (v1): a kcc20 `transfer` input (token balance / inventory / seller piece). */
148
+ declare const TOKEN_COMPUTE = 500;
149
+ /** Per-input compute budget (v1): a curve_cp / amm_pool_cp input (the large redeem scripts). */
150
+ declare const COVENANT_COMPUTE = 2000;
151
+ /** Covenant output min value (KIP-9 storage mass) — the conventional token-UTXO dust, 0.5 KAS. */
152
+ declare const COVENANT_DUST = 50000000n;
153
+ /** A covenant output's KIP-20 lineage: which covenant id it continues and which input authorizes it. */
154
+ type CovBinding = {
155
+ covid: string;
156
+ authorizingInput: number;
157
+ };
143
158
  /** A covenant UTXO being spent, already carrying its signature script (no wallet signature needed). */
144
159
  type CovInput = {
145
160
  transactionId: string;
@@ -152,16 +167,19 @@ type CovInput = {
152
167
  redeem: Uint8Array;
153
168
  /** what this input is, for assembly/debugging: 'curve' | 'minterBranch' | 'burn' | 'pool' | 'poolToken'. */
154
169
  role: string;
170
+ /** v1 compute budget override; defaults by role (curve/pool → COVENANT_COMPUTE, else TOKEN_COMPUTE). */
171
+ computeBudget?: number;
155
172
  };
156
- /** A covenant-required output (value + scriptPublicKey). */
173
+ /** A covenant-required output (value + scriptPublicKey [+ covenant binding]). */
157
174
  type CovOutput = {
158
175
  value: bigint;
159
176
  scriptPublicKey: Spk$4;
160
177
  role: string;
178
+ binding?: CovBinding;
161
179
  };
162
180
  /** A complete covenant action: the inputs it spends + the outputs it must create + computed economics. */
163
181
  type CovenantSpend = {
164
- kind: 'init' | 'initVested' | 'buy' | 'sell' | 'graduate' | 'swapKasForToken' | 'swapTokenForKas' | 'addLiquidity' | 'removeLiquidity' | 'bindLp' | 'claim' | 'claimFinal';
182
+ kind: 'init' | 'initVested' | 'buy' | 'sell' | 'transfer' | 'graduate' | 'swapKasForToken' | 'swapTokenForKas' | 'addLiquidity' | 'removeLiquidity' | 'bindLp' | 'claim' | 'claimFinal';
165
183
  inputs: CovInput[];
166
184
  outputs: CovOutput[];
167
185
  economics: Record<string, bigint>;
@@ -183,10 +201,12 @@ type AssembledNativeTx = {
183
201
  change: bigint;
184
202
  };
185
203
  /**
186
- * Assemble a complete tx: the spend's covenant inputs (pre-scripted) + the trader's funding inputs + a
187
- * change output. `networkFee` is caller-provided (derive from the node; KIP-9 storage mass depends on
188
- * output values, so the node confirms the exact fee/change at broadcast). Covenant inputs carry sigOpCount
189
- * 0 (no checkSig on the accept path used here); funding inputs are signed via signFundingInputs.
204
+ * Assemble a complete v1 covenant tx: the spend's covenant inputs (pre-scripted) + the trader's funding
205
+ * inputs + a change output. Covenant outputs whose `binding` is set carry the KIP-20 `CovenantBinding`
206
+ * (REQUIRED for any output the covenant validates see the module header). `networkFee` is
207
+ * caller-provided; size it with `estimateNativeFee` (v1 fees must cover the per-input compute budget, so a
208
+ * flat legacy fee is usually too low). Covenant inputs default to a role-based compute budget; funding
209
+ * inputs are signed via signFundingInputs (or the signPskt bridge).
190
210
  */
191
211
  declare function assembleNativeTx(k: K$5, opts: {
192
212
  spend: CovenantSpend;
@@ -194,6 +214,14 @@ declare function assembleNativeTx(k: K$5, opts: {
194
214
  changeAddress: string;
195
215
  networkFee: bigint;
196
216
  }): AssembledNativeTx;
217
+ /**
218
+ * Size `networkFee` for an assembled v1 tx: byte/storage mass (via the WASM mass calculator, with
219
+ * placeholder signatures on the funding inputs so byte mass is realistic) + the per-input compute budget
220
+ * the calculator omits (grams = budget × 100), at `feeRateSompiPerGram` (use the node's feerate estimate;
221
+ * min-relay on TN10 has been ~100 sompi/gram), with a 1.5× over-cover and a 10_000-sompi floor. Assemble
222
+ * with a guess (e.g. 10_000n), call this, then re-assemble with the returned fee.
223
+ */
224
+ declare function estimateNativeFee(k: K$5, networkId: string, asm: AssembledNativeTx, feeRateSompiPerGram: number): bigint;
197
225
  /** Sign the trader's funding inputs (P2PK) in place; covenant inputs are left untouched (pre-scripted). */
198
226
  declare function signFundingInputs(k: K$5, tx: any, privKey: any, fundingInputIndexes: number[]): any;
199
227
  /**
@@ -221,16 +249,23 @@ declare function signPsktWithKey(k: K$5, txJsonString: string, signInputs: {
221
249
  }[], privKey: any): string;
222
250
 
223
251
  type spend_AssembledNativeTx = AssembledNativeTx;
252
+ declare const spend_COVENANT_COMPUTE: typeof COVENANT_COMPUTE;
253
+ declare const spend_COVENANT_DUST: typeof COVENANT_DUST;
254
+ type spend_CovBinding = CovBinding;
224
255
  type spend_CovInput = CovInput;
225
256
  type spend_CovOutput = CovOutput;
226
257
  type spend_CovenantSpend = CovenantSpend;
258
+ declare const spend_FUNDING_COMPUTE: typeof FUNDING_COMPUTE;
227
259
  type spend_FundingEntry = FundingEntry;
260
+ declare const spend_TOKEN_COMPUTE: typeof TOKEN_COMPUTE;
261
+ declare const spend_TX_VERSION: typeof TX_VERSION;
228
262
  declare const spend_assembleNativeTx: typeof assembleNativeTx;
263
+ declare const spend_estimateNativeFee: typeof estimateNativeFee;
229
264
  declare const spend_signFundingInputs: typeof signFundingInputs;
230
265
  declare const spend_signPsktWithKey: typeof signPsktWithKey;
231
266
  declare const spend_toPsktJson: typeof toPsktJson;
232
267
  declare namespace spend {
233
- export { type spend_AssembledNativeTx as AssembledNativeTx, type spend_CovInput as CovInput, type spend_CovOutput as CovOutput, type spend_CovenantSpend as CovenantSpend, type spend_FundingEntry as FundingEntry, spend_assembleNativeTx as assembleNativeTx, spend_signFundingInputs as signFundingInputs, spend_signPsktWithKey as signPsktWithKey, spend_toPsktJson as toPsktJson };
268
+ export { type spend_AssembledNativeTx as AssembledNativeTx, spend_COVENANT_COMPUTE as COVENANT_COMPUTE, spend_COVENANT_DUST as COVENANT_DUST, type spend_CovBinding as CovBinding, type spend_CovInput as CovInput, type spend_CovOutput as CovOutput, type spend_CovenantSpend as CovenantSpend, spend_FUNDING_COMPUTE as FUNDING_COMPUTE, type spend_FundingEntry as FundingEntry, spend_TOKEN_COMPUTE as TOKEN_COMPUTE, spend_TX_VERSION as TX_VERSION, spend_assembleNativeTx as assembleNativeTx, spend_estimateNativeFee as estimateNativeFee, spend_signFundingInputs as signFundingInputs, spend_signPsktWithKey as signPsktWithKey, spend_toPsktJson as toPsktJson };
234
269
  }
235
270
 
236
271
  type K$4 = Kaspa;
@@ -259,6 +294,23 @@ type Kcc20Template = {
259
294
  };
260
295
  /** Produce the kcc20 redeem script for `state` by splicing the 46-byte region. Byte-identical to silverc. */
261
296
  declare function materializeKcc20Script(tpl: Kcc20Template, state: Kcc20State): Uint8Array;
297
+ /**
298
+ * Recover the `{ script, stateStart }` template AND the current balance state from a live token UTXO's
299
+ * redeem script (your indexer's `redeemScriptHex`). Scans for the 46-byte state region's push layout
300
+ * (`0x20 <owner:32> 0x01 <type:1> 0x08 <amount:8> 0x01 <isMinter:1>` with type ≤ 0x03, isMinter ≤ 1) and
301
+ * requires it to match at exactly ONE offset. This is the supported way to build the template for
302
+ * `materializeKcc20Script` — splice the SAME script the chain holds; never re-compile.
303
+ * `maxIns`/`maxOuts` are compiled constants not recoverable from the bytes — pass the token's deploy
304
+ * params if you know them (KRON deploys use 4/4, the default) — they are informational only (the splice
305
+ * uses just `script` + `stateStart`).
306
+ */
307
+ declare function decodeKcc20Redeem(redeem: Uint8Array, opts?: {
308
+ maxIns?: number;
309
+ maxOuts?: number;
310
+ }): {
311
+ template: Kcc20Template;
312
+ state: Kcc20State;
313
+ };
262
314
  /** Token P2SH scriptPublicKey for a redeem script. */
263
315
  declare const kcc20Spk: (k: K$4, redeem: Uint8Array) => Spk$3;
264
316
  /** Token P2SH scriptPublicKey for a balance state (materialize → P2SH). */
@@ -288,13 +340,33 @@ declare function pushKcc20States(b: SigScriptBuilder, states: Kcc20State[]): voi
288
340
  * carrying that covenant id). `sigs` are 65-byte Schnorr sigs (empty for covenant-id-only ownership).
289
341
  */
290
342
  declare function transferSigScript(k: K$4, redeem: Uint8Array, newStates: Kcc20State[], witnesses: number[], sigs?: Uint8Array[]): string;
343
+ /**
344
+ * Send `sendAmount` from one or more presence-owned token UTXOs (same owner) to `recipientPubkey32`, with
345
+ * the remainder returned to the sender — the wallet "Send" button. A plain conserving `transfer`: inputs
346
+ * are authorized by ONE co-present P2PK input at tx index `presenceWitnessIdx` (assemble the covenant
347
+ * inputs first, then the sender's funding inputs: with N token inputs, `presenceWitnessIdx = N`).
348
+ *
349
+ * `tokenCovid` (the token's covenant id, hex — `covenantId` from the indexer's token info) is REQUIRED:
350
+ * every covenant output must carry the KIP-20 `CovenantBinding` or the chain rejects the spend with
351
+ * "script ran, but verification failed". Outputs: [recipient, change] (change omitted when exact).
352
+ */
353
+ declare function buildKcc20Send(k: K$4, tpl: Kcc20Template, senderTokens: {
354
+ transactionId: string;
355
+ index: number;
356
+ value: bigint;
357
+ state: Kcc20State;
358
+ }[], recipientPubkey32: Uint8Array, sendAmount: bigint, presenceWitnessIdx: number, tokenCovid: string, opts?: {
359
+ tokenDust?: bigint;
360
+ }): CovenantSpend;
291
361
 
292
362
  declare const kcc20Tx_IDENTIFIER: typeof IDENTIFIER;
293
363
  type kcc20Tx_IdentifierType = IdentifierType;
294
364
  type kcc20Tx_Kcc20State = Kcc20State;
295
365
  type kcc20Tx_Kcc20Template = Kcc20Template;
296
366
  declare const kcc20Tx_addressPresenceOwned: typeof addressPresenceOwned;
367
+ declare const kcc20Tx_buildKcc20Send: typeof buildKcc20Send;
297
368
  declare const kcc20Tx_covenantIdOwned: typeof covenantIdOwned;
369
+ declare const kcc20Tx_decodeKcc20Redeem: typeof decodeKcc20Redeem;
298
370
  declare const kcc20Tx_kcc20Address: typeof kcc20Address;
299
371
  declare const kcc20Tx_kcc20Spk: typeof kcc20Spk;
300
372
  declare const kcc20Tx_kcc20SpkForState: typeof kcc20SpkForState;
@@ -305,7 +377,7 @@ declare const kcc20Tx_pushKcc20States: typeof pushKcc20States;
305
377
  declare const kcc20Tx_scriptHashOwned: typeof scriptHashOwned;
306
378
  declare const kcc20Tx_transferSigScript: typeof transferSigScript;
307
379
  declare namespace kcc20Tx {
308
- export { kcc20Tx_IDENTIFIER as IDENTIFIER, type kcc20Tx_IdentifierType as IdentifierType, type kcc20Tx_Kcc20State as Kcc20State, type kcc20Tx_Kcc20Template as Kcc20Template, kcc20Tx_addressPresenceOwned as addressPresenceOwned, kcc20Tx_covenantIdOwned as covenantIdOwned, kcc20Tx_kcc20Address as kcc20Address, kcc20Tx_kcc20Spk as kcc20Spk, kcc20Tx_kcc20SpkForState as kcc20SpkForState, kcc20Tx_materializeKcc20Script as materializeKcc20Script, kcc20Tx_pubkeyOwned as pubkeyOwned, kcc20Tx_pushKcc20StateScalar as pushKcc20StateScalar, kcc20Tx_pushKcc20States as pushKcc20States, kcc20Tx_scriptHashOwned as scriptHashOwned, kcc20Tx_transferSigScript as transferSigScript };
380
+ export { kcc20Tx_IDENTIFIER as IDENTIFIER, type kcc20Tx_IdentifierType as IdentifierType, type kcc20Tx_Kcc20State as Kcc20State, type kcc20Tx_Kcc20Template as Kcc20Template, kcc20Tx_addressPresenceOwned as addressPresenceOwned, kcc20Tx_buildKcc20Send as buildKcc20Send, kcc20Tx_covenantIdOwned as covenantIdOwned, kcc20Tx_decodeKcc20Redeem as decodeKcc20Redeem, kcc20Tx_kcc20Address as kcc20Address, kcc20Tx_kcc20Spk as kcc20Spk, kcc20Tx_kcc20SpkForState as kcc20SpkForState, kcc20Tx_materializeKcc20Script as materializeKcc20Script, kcc20Tx_pubkeyOwned as pubkeyOwned, kcc20Tx_pushKcc20StateScalar as pushKcc20StateScalar, kcc20Tx_pushKcc20States as pushKcc20States, kcc20Tx_scriptHashOwned as scriptHashOwned, kcc20Tx_transferSigScript as transferSigScript };
309
381
  }
310
382
 
311
383
  type K$3 = Kaspa;
@@ -598,6 +670,8 @@ declare function buildCpGraduate(k: K$2, tpl: CpTemplate, tokenTpl: Kcc20Templat
598
670
  * a plain conserving kcc20 transfer authorized by a co-present P2PK input at `presenceWitnessIdx`. Lets a
599
671
  * holder sell an ARBITRARY amount on covenants that require full-UTXO sells (curve/pool): split, then sell the
600
672
  * `sellAmount` piece. No curve/pool involved — just the token covenant.
673
+ * Pass `opts.tokenCovid` (the token's covenant id, hex — `covenantId` from the indexer) so both outputs carry
674
+ * the KIP-20 covenant binding the chain requires; without it the assembled tx fails on-chain.
601
675
  */
602
676
  declare function buildSplitToken(k: K$2, tokenTpl: Kcc20Template, sellerToken: {
603
677
  transactionId: string;
@@ -606,11 +680,14 @@ declare function buildSplitToken(k: K$2, tokenTpl: Kcc20Template, sellerToken: {
606
680
  state: Kcc20State;
607
681
  }, sellAmount: bigint, presenceWitnessIdx: number, opts?: {
608
682
  tokenDust?: bigint;
683
+ tokenCovid?: string;
609
684
  }): CovenantSpend;
610
685
  /**
611
686
  * Consolidate several presence-owned token UTXOs (same owner) into ONE — a conserving kcc20 transfer (N covid-A
612
687
  * inputs → 1 output) authorized by a single co-present P2PK input at `presenceWitnessIdx`. Lets a holder merge
613
688
  * many small buys into one piece so a later sell needs just one (or two) inputs. No curve/pool involved.
689
+ * Pass `opts.tokenCovid` (the token's covenant id, hex) so the merged output carries the KIP-20 covenant
690
+ * binding the chain requires; without it the assembled tx fails on-chain.
614
691
  */
615
692
  declare function buildConsolidate(k: K$2, tokenTpl: Kcc20Template, tokens: {
616
693
  transactionId: string;
@@ -619,6 +696,7 @@ declare function buildConsolidate(k: K$2, tokenTpl: Kcc20Template, tokens: {
619
696
  state: Kcc20State;
620
697
  }[], presenceWitnessIdx: number, opts?: {
621
698
  tokenDust?: bigint;
699
+ tokenCovid?: string;
622
700
  }): CovenantSpend;
623
701
 
624
702
  type curveCpTx_CpCurveState = CpCurveState;
@@ -736,14 +814,23 @@ type VestUtxo = {
736
814
  * Partial claim: release `release` (0 < release < remaining) to the creator's presence, re-lock the rest under
737
815
  * V. inputs [vesting(0), lockedToken(1)]; outputs [vesting cont(0), relock(1, A/V-owned), recipient(2, A/creator)].
738
816
  * The flow must set tx.lockTime = current DAA score (consensus blocks the tx until then; the covenant reads it).
817
+ *
818
+ * Pass `opts.tokenCovid` (the vested token's covenant id, hex — `covenantId` from the indexer) so the relock +
819
+ * recipient outputs carry the KIP-20 covenant binding the chain requires; without it the assembled tx fails
820
+ * on-chain. The vesting-continuation output is always bound to `vestingCovid` (already a required param).
739
821
  */
740
822
  declare function buildVestingClaim(k: K, vestTpl: VestingTemplate, tokenTpl: Kcc20Template, vestingUtxo: VestUtxo, lockedToken: VestUtxo, vestingCovid: Uint8Array, creatorPubkey: Uint8Array, claimed: bigint, release: bigint, opts?: {
741
823
  tokenDust?: bigint;
824
+ tokenCovid?: string;
742
825
  }): CovenantSpend;
743
826
  /** Final claim: once fully vested, pay ALL remaining to the creator and continue V with claimed=total (husk).
744
- * inputs [vesting(0), lockedToken(1)]; outputs [vesting cont(0), recipient(1, A/creator)]. */
827
+ * inputs [vesting(0), lockedToken(1)]; outputs [vesting cont(0), recipient(1, A/creator)].
828
+ *
829
+ * Pass `opts.tokenCovid` (the vested token's covenant id, hex) so the recipient output carries the KIP-20
830
+ * covenant binding the chain requires; without it the assembled tx fails on-chain. */
745
831
  declare function buildVestingClaimFinal(k: K, vestTpl: VestingTemplate, tokenTpl: Kcc20Template, vestingUtxo: VestUtxo, lockedToken: VestUtxo, vestingCovid: Uint8Array, creatorPubkey: Uint8Array, claimed: bigint, opts?: {
746
832
  tokenDust?: bigint;
833
+ tokenCovid?: string;
747
834
  }): CovenantSpend;
748
835
 
749
836
  declare const vestingTx_VEST_SELECTOR: typeof VEST_SELECTOR;