Hi! I’m trying to create a stake delegation transaction using cardano-serialization-lib, js, and Yoroi with the CIP30 API (Cardano dApp-Wallet Web Bridge https://cips.cardano.org/cips/cip30/)
I’m using Yoroi Nightly and Testnet
Code:
delegate = async () => {
const bech32Addr = this.state.changeAddress //obtaining my payment address
const address = Address.from_bech32(bech32Addr)
const baseAddress = BaseAddress.from_address(address);
const txUnspentOutputs = await this.getTxUnspentOutputs();
const txBuilder = await this.initTransactionBuilder(); // creating transaction
txBuilder.add_inputs_from(txUnspentOutputs, 0)
const certs = Certificates.new();
const poolId = this.state.poolId
const poolKeyHash = Ed25519KeyHash.from_bytes(Buffer.from(poolId, 'hex'));
//Adding StakeDelegation Certificate
certs.add(
Certificate.new_stake_delegation(
StakeDelegation.new(
baseAddress.stake_cred(),
poolKeyHash
)
)
);
txBuilder.set_certs(certs)
txBuilder.add_change_if_needed(address)
const txBody = txBuilder.build();
const transactionWitnessSet = TransactionWitnessSet.new();
const tx = Transaction.new(
txBody,
TransactionWitnessSet.from_bytes(transactionWitnessSet.to_bytes())
)
// "this.API" is the Yoroi API created using "window.cardano.yoroi.enable()"
let txVkeyWitnesses = await this.API.signTx(Buffer.from(tx.to_bytes(), "utf8").toString("hex"), true);
txVkeyWitnesses = TransactionWitnessSet.from_bytes(Buffer.from(txVkeyWitnesses, "hex"));
transactionWitnessSet.set_vkeys(txVkeyWitnesses.vkeys());
const signedTx = Transaction.new(
tx.body(),
transactionWitnessSet
);
const submittedTxHash = await this.API.submitTx(Buffer.from(signedTx.to_bytes(), "utf8").toString("hex"));
}
initTransactionBuilder code:
/**
* Every transaction starts with initializing the
* TransactionBuilder and setting the protocol parameters
* This is boilerplate
* @returns {Promise<TransactionBuilder>}
*/
initTransactionBuilder = async () => {
const txBuilder = TransactionBuilder.new(
TransactionBuilderConfigBuilder.new()
.fee_algo(LinearFee.new(BigNum.from_str(this.protocolParams.linearFee.minFeeA), BigNum.from_str(this.protocolParams.linearFee.minFeeB)))
.pool_deposit(BigNum.from_str(this.protocolParams.poolDeposit))
.key_deposit(BigNum.from_str(this.protocolParams.keyDeposit))
.coins_per_utxo_word(BigNum.from_str(this.protocolParams.coinsPerUtxoWord))
.max_value_size(this.protocolParams.maxValSize)
.max_tx_size(this.protocolParams.maxTxSize)
.prefer_pure_change(true)
.build()
);
return txBuilder
}
This exact code is working correctly with the following Wallets (also using CIP30):
- Nami
- Flint
- CCVault / Eternl
- Typhon
- Nufi
The only Wallet that doesn’t work is Yoroi.
This is the error I’m getting:
"transaction submit error ShelleyTxValidationError ShelleyBasedEraBabbage (ApplyTxError [UtxowFailure (FromAlonzoUtxowFail (WrappedShelleyEraFailure (MissingVKeyWitnessesUTXOW (WitHashes (fromList [KeyHash "bdd5302aa402af3018f558b9eef255751633abc32c7352d9eb1d2f37"])))))])"
Maybe I’m wrong but I think Yoroi is not signing the StakeDelegation certificate.
I also tried adding the StakeRegistration Certificate and the result is the same.
I’m able to create regular transactions with Yoroi (only sending ADA), I just can’t do transactions related to Staking.
If you are wondering why I want to do this and not use the Yoroi UI is because I want to add metadata to the transaction and also so the users can delegate directly from my website.