Skip to content

Add API for covenant genesis ID computation & output population#885

Draft
smartgoo wants to merge 15 commits intokaspanet:tn12from
smartgoo:wasm-covenant-id
Draft

Add API for covenant genesis ID computation & output population#885
smartgoo wants to merge 15 commits intokaspanet:tn12from
smartgoo:wasm-covenant-id

Conversation

@smartgoo
Copy link

@smartgoo smartgoo commented Feb 25, 2026

Summary:

This PR adds a standard process and helper function for covenant ID computation and population on genesis outputs:

  • A standard process to compute covenant ID and populate on genesis outputs. Available to Rust and WASM SDK.
  • A WASM SDK-exposed wrapper function around kaspa-consensus-core's covenant_id() function.

Combined, these streamline the covenant genesis process, reducing lift for developers.

Note: this PR originally started as WASM SDK covenant_id() function only. Scope changed to include functionality that further streamline the process.

Why:

This codebase should provide a streamlined process and required building blocks for the covenant genesis process. Given the need to 1.) compute covenant ID for genesis; and .2) populate the covenant ID on genesis outputs.

This added functionality simplifies the process for Rust & WASM SDK developers.

Changes:

  • Added GenesisCovenantGroup and populate_genesis_covenants() fn to consensus core Transaction (by @michaelsutton)
  • Added wiring to expose GenesisCovenantGroup to WASM
  • Function js_covenant_id in kaspa-consensus-client crate.
  • Added ITransactionOutpoint TS type in kaspa-consensus-client crate.
  • Added covenant ID generation example in JS.
  • Add populate_genesis_covenants() to consensus client Transaction

WIP:

  • Clean up (try moving GenesisCovenantGroup WASM related code into consensus client, clean up errors, etc.)

Copy link
Collaborator

@IzioDev IzioDev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well needed addition for tn12!

@@ -0,0 +1,35 @@
use crate::error::Error;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's fair to move the content to here: /consensus/client/src/hash.rs considering what it has at the moment

What do you think?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@IzioDev makes sense - this is done, moved to /consensus/client/src/hash.rs in 63aea0a.

///
/// @category Consensus
#[wasm_bindgen(js_name = covenantId)]
pub fn covenant_id_js(genesis_outpoint: &TransactionOutpointT, auth_outputs: JsValue) -> Result<Hash> {
Copy link
Collaborator

@IzioDev IzioDev Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not using Vec<TransactionOutput> as the second argument here? I don't remember the exact behavior with Vec Js value parsing, but TransactionOutput does have a dedicated deserializer.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@IzioDev great question, didn't think of trying to use Vec<_> here.

So each object in auth_outputs array needs to include an index in addition to the TransactionOutput instance/opbject. e.g.

[
    { index: 0, output: { value: 10000, scriptPublicKey: spk } },
    ...
]

For that reason param type would need to be something like Vec<(u32, TransactionOutput)>.

But with that param type, compile error:

trait bound `(u32, kaspa_consensus_client::TransactionOutpoint): JsObject` is not satisfied

So my current thought is - not worth it to impl that for this use case. However, curious what you think. Also if you have any other thoughts on alternative approaches?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@IzioDev Actually, even Vec<(u32, TransactionOutput)> is wrong.

I think it would be Vec<JsValue>, where JsValue looks like or would require some new struct e.g. AuthOutputs to use as Vec<AuthOutputs>. Where AuthOutputs probably looks like this:

struct AuthOutputs {
    index: u32,
    output: TransactionOutput
}

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@IzioDev Ok I changed it to Vec<JsValue> in 2495111.

I feel this is a step in the right direction - it simplifies internals slightly and makes fn signature a little more explicit. Taking it a step further would be a custom struct a la the comment above.

However, I'm not sure how Vec<JsValue> plays with TypeScript. There are some ArrayT patterns used elsewhere for parameter types in WASM functions. Like PrivateKeyArrayT, PublicKeyArrayT, TransactionInputArrayAsArgT, TransactionOutputArrayAsArgT. Can explore this is you think it makes sense.

Sorry for yet another comment here.

pub mod hashing;
pub mod result;
mod utils;
pub use hashing::*;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated, but I'm sharing here in case :)
This has for effect to "spread" / "share" all of the public hashing members to the current crate, so within consensus/wasm you can do use crate::covenant_id_js; instead of use crate::hashing::covenant_id_js;

I'm not sure this was intended

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yeah good call out. Used that approach since it was already used for pub use utils::*; a couple lines down. I intend to move it to other file per your other comment. So this will go away!

///
/// @category Consensus
#[wasm_bindgen(js_name = covenantId)]
pub fn covenant_id_js(genesis_outpoint: &TransactionOutpointT, auth_outputs: JsValue) -> Result<Hash> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what's the general recommendation to enforce in term of naming, but many (if not all?) members of wallet/core/wasm define js (/wasm) functions as js_my_function (as a prefix)

Copy link
Author

@smartgoo smartgoo Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@IzioDev Looks like a mixed bag of js_ prefix and _js suffix throughout the codebase.

A quick (very incomplete) list to give a feel for it:

js_ prefix is used on functions js_sign_message, js_sign_verify_message, js_sign_transaction, everything in encryption.rs.

_js suffix is used on functions create_address_js, create_multisig_address_js, create_transaction_js, create_transactions_js, estimate_transactions_js, etc.

By quantity, it looks like a slight skew towards js_ prefix. So I have updated to use js prefix in a29c544. Thanks!

Comment on lines +27 to +28
/// WASM (TypeScript) type representing `ITransactionOutpoint | TransactionOutpoint`
/// @category Consensus
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure it's relevant to precise it's a wasm typescript type, end-users most likely don't care

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@IzioDev Admittedly I just copy/pasted this comment from other extern WASM blocks and changed out the actual type. This comment structure seems to be standard throughout WASM consensus client extern blocks - transaction input, transaction output, transaction for example use this same comment structure.

That said, happy to change it if you want!

@smartgoo
Copy link
Author

@IzioDev TY for feedback (& the quick response)! Will get back to you on these in the next day or so.

* add try from arrayt impl for genesis covenant group

* switch error to already typed cast err

* add error variant for invalid genesis covenant group array

* switch error type

* genesis covenant group wasm array try from and error update
@smartgoo smartgoo changed the title Expose covenant_id computation to WASM SDK via wrapper function Add API for covenant genesis ID computation & output population Mar 2, 2026
@smartgoo smartgoo marked this pull request as draft March 2, 2026 22:39
@smartgoo
Copy link
Author

smartgoo commented Mar 2, 2026

Updated title & description to reflect expanded scope. Converted to draft status as this is WIP. Only a few remaining TODOs.

smartgoo added 3 commits March 4, 2026 05:11
* cctx populate_genesis_covenants fn

* populate_genesis_covenants camel case js name

* covenant getter/setter on client tx output

* from client to core tx out with covenant
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants