text:
NFT Image not Displaying in Pool.pm after using the 721 Metadata Standard
I am not seeing the image of the NFT I minted a couple of hours ago on pool.pm.  I used the standard recommended by Alessandro Konrad and Smaug in https://github.com/Berry-Pool/CIPs/blob/master/CIP-NFTMetadataStandard.md.
The gif in question is 15mb and it displays perfectly in IPFS using the Brave browser and in the Blockfrost IPFS web gateway.
Here is the metadata file:
{
  "721": {
    "4a2ba87b606a0aeb40916e906670a346c4b915840a755ddf109af709": {
    "cardanollama001": {
    "name": "Cardano Llama 001",
    "image": "ipfs://QmSahUdK9RTNDBGEq6xHWHZXRFwyQv8wBAtRgpxFCkNvqz",
    "description": "1bit aestethic, 256 colors, 90 hand-glitched frame loop",
    "size": "1000x666",
    "rarity": "225 of 250"
     }
    }
  }
}

Here is the link to the pool.pm link:
https://pool.pm/77a6f71a13e82794409d06c7486a59bb7a6af38e223b646c07e3262e.cardanollama001
I think I followed the standard to a tee, but I am stumped at this issue, and I can't figure out a solution.
Any help is very much appreciated!

I'm facing the same problem mate, do you found any solution rather than reducing the image size?

Hey @Anis If you give me the minting transaction hash I can try to help.

Looking at the minting transaction, there seems to be a mismatch between the policy ID in the minting transaction and the metadata policy ID field:
https://cardanoscan.io/transaction/8be04d6a8e22c40f2b3970b0be893b5757d0f237efba997346cb145ccc60b7b3?tab=tokenmint
Minting policy ID: 77a6f71a13e82794409d06c7486a59bb7a6af38e223b646c07e3262e
Metadata policy ID: 4a2ba87b606a0aeb40916e906670a346c4b915840a755ddf109af709

The metadata in your mint transaction looks good, it follows the standard correctly.
The only thing that kind of violates that standard is the size of your image (see chapter "Structure"):

The image and name property are marked as required. image should be an URI pointing to a resource with mime type image/* used as thumbnail or as actual link if the NFT is an image (ideally <= 1MB).

I assume that the creator of pool.pm has set a limit for the size of the images to prevent long loading times of the website. So your 15MB image is probably just too big. Unfortunately the source code of pool.pm is not available, so I can't check if my guess is correct.
To fix this, you can upload a smaller version as image and the full resolution version of your image as source. Or you can try to optimize the size of the existing image.

The type and src properties are optional. If type is defined, src will be an URI pointing to a resource of this mime type. If the mime type is image/*, src points to the same image in an higher resolution.

EDIT: Looking at the pool.pm page of your asset, it looks like the JSON metadata is not parsed correctly:

Usually, the properties should be shown like that:

This could be caused by the commas you used in the description property. So it's likely a bug on pool.pm. You could create an issue on their GitHub repo: https://github.com/SmaugPool/pool.pm/issues


text:
What are the key benefits of IOHK's new light wallet over Yoroi?
Found this link that talks about it more:
https://www.youtube.com/watch?v=hbi07kZM_Zk&ab_channel=IOHK

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes


text:
Why are Cardano transaction fees so high?
It's obviously a lot less than Ethereum's, but 0.17 ADA isn't insignificant. What are the main reasons it can't be 0.00017 ADA?
I understand that the parameters are configurable over time, but has it really changed since 1 ADA = $0.10 until now? How exactly have IOHK determined that 0.17 is the right amount for now? If it is because it matches the cost of running the network - where can I see that calculation?

If you have fixed market cap (45 Billion out of which 31 B in circulation) you need to have transaction fees to cover the cost of running the network (Stake Pool Operators and all people who are delegating their coins to the SPOs).
If you don't have fixed market cap you can afford to cover all the costs by fixed/dynamic yearly inflation. But again: someone/something needs to cover the network costs. Nothing is free.
In our case the transaction fee at the moment is adjusted from time to time based on the price of ADA. If ADA goes up then the transaction fee goes down so that can be around 0.2$.
Later once Catalyst is more mature these parameters (including the topic about the fixed market cap) can be discussed and we will be able to vote on it. :)

However, the market cap is fixed but the limit is not reached yet. So in effect the costs are also covered by the issuance of new coins for now...

Yes, totally right. Thank you that you added this additional important information.

Thanks for the answer, added a few more details to the question to be more specific.
I understand that the parameters are configurable over time, but has it really changed since 1 ADA = $0.10 until now? How exactly have IOHK determined that 0.17 is the right amount for now? If it is because it matches the cost of running the network - where can I see that calculation?

As far as I know the parameters are adjusted so that the value of a transaction is to be around 0.2$.
One of the reasons for is DDOS attack and also to cover the cost of the network (over time after all coins are in circulation these fees should cover all the costs of the SPOs and the delegators).
So, yes, I remember that back at the time the trasaction fee was 1 ADA. Then over time based on the current value of ADA they changed that to correspond to ~0.2$ per transaction.

The transaction fee is a network parameter and is subjected to governance in the future. There is a cost for maintaining the network. Currently, there are more than 2500 stake pools that are providing the infrastructure for running Cardano.
Cardano also has a treasury that is powering innovation. Treasury is also paid from the transaction fee.
When the number of transactions goes up, the fees will be brought down as the governing mechanism decides.
Cardano is proof of stake based network, therefore operating cost is very low which will never result in runaway escalation in transaction fees.

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
How to derive addresses from a key exported from Yoroi
I’d like to code a small crypto portfolio app using python. So to track my ADA, I need to scan the addresses of my wallet.
I found Yorois feature to export a “key” and conveniently, it also states the derivation path. Unfortunately, I’m a noob with regard to key derivation and I’m a little confused by the encoding of the key, since it does not seem to come in a base58 format like BTC extended public keys.
So to have a common testing ground, I created a test wallet and this is the "key" that Yoroi gives me, when I go to Options=>Wallet=>Export Wallet=>Export:
95e74df114717de17ebfb24c05f9fd1c8019bb6f1de117eec10a43670a692866b837a4a5f51d62f3dc3d630d075c8e39e5294323ba146c386c48123aeef5438a
So how would I go about generating addresses from this key using python libraries or the cardano-addresses tool?
I already watched Cardano: NerdOut - Key Derivation by Andrew Westberg. Unfortunately, the public key used by Andrew was exported using Daedalus and not Yoroi and uses a different encoding.
So there are a two more specific questions, that may help with the solution of this problem:

Did I grasp it correctly, that the key given by Yoroi just needs to be converted using bech32 and a xpub prefix, to generate a “standard” xpub key (e.g. bech32 xpub <<< yoroikey using the bech32 tool)?
Reading further info, I learned that Cardano does not use standard BIP-44, but BIP-44-Ed25519. But is this even relevant for the address derivation using a xpub key? At least, looking at an example for Byron addresses, it does not look that way, since the ed25519 library is just used at the very beginning of the derivation.

Thanks.
EDIT: Added key for testing purposes.

+1 but it's better to ask 1 question per post. I recommend splitting it up so that this doesn't get closed as "needs more focus".

Thanks for the hint. I thought about splitting up the question. However, that would introduce a lot of redundancy, since all the questions are part of the ultimate question that's in the title. Also, I don't necessarily care about the answers to the more specific questions, if there is an easier solution to the general question.

You could put a link to the first question in the 2nd one.

After a bit of fiddling (see What encoding is used for Yorois Wallet export? and Why is there a small difference between addresses derived by the cardano-address tool and Yoroi?) I found a solution using the cardano-addresses tool and the bech32 tool.
Starting from a key exported from Yoroi (for this demonstration let's assume that this key is in a file root_yoroi_raw.pub):
# Encode the public key:
./bech32 acct_xvk < root_yoroi_raw.pub > root_yoroi.pub

# Derive the stake key:
cat root_yoroi.pub | ./cardano-address key child 2/0 > stake.xvk

# Generate first Yoroi address:
cat root_yoroi.pub | ./cardano-address key child 0/0 | ./cardano-address address payment --network-tag mainnet > payment1.addr
./cardano-address address delegation $(cat stake.xvk) < payment1.addr > payment-delegated1.addr
cat payment-delegated1.addr

# Generate second Yoroi address:
cat root_yoroi.pub | ./cardano-address key child 0/1 | ./cardano-address address payment --network-tag mainnet > payment2.addr
./cardano-address address delegation $(cat stake.xvk) < payment2.addr > payment-delegated2.addr
cat payment-delegated2.addr

Just FYI, the bech32 and cardano-address tools are part of the cardano-wallet suite. If you download the cardano-wallet release you get all the tools plus some others https://github.com/input-output-hk/cardano-wallet.

@nalyd88 Thanks for the hint! That could definitively come in handy.

I would suggest you leave Yoroi out of it. You have a seed phrase that can generate your wallet private keys. So, use the cardano-wallet tools to generate your keys, derive addressed, etc. You can do this in bash or call the cardano-wallet executables from a Python script.

Thanks for the suggestion. However, that is no option for me, since I want to create a watch-only wallet. I'm using a Ledger Nano S, and therefore the seed phrase/private key should not be stored anywhere else.

You can use the cardano-node CLI to get the balance for an address. But you will have to have all the addresses that your wallet uses (since they automatically generate new ones for anonymity). There is not a way to just export a key and watch all the funds in the entire wallet. Cardano uses HD wallets so you need the private root key to derive all the addresses. Except for the stake key, that is unique and can be used to find all the addresses that belong to the wallet but doing so it non-trivial.

Thanks for your help. However, I'm not sure whether what you are saying is correct. I think that knowledge of the extended public key associated with the wallet would allow me to derive all public keys and therefore addresses associated with the wallet. That is also supported by the hint that Yoroi gives during the export:
"Below you can find your wallet's public key information. Public keys allow seeing the wallet history for the wallet, but does not allow to spend or move the funds in any way (private key is not included)"

Yeah you are right. After the 1835H/1815H/0H path you can get a public key that will allow you to generate addresses. I didn't think that Yoroi was outputting that key though. I figured it was the public key associated with the full derivation path e.g., 1835H/1815H/0H/0/1.


text:
How much does it cost for stake-pools to mine 1 ADA?
More or less how much does it cost in terms of: electricity + hardware devaluation for the stake-pools to mine each ADA?

A fully-saturated pool, minting several dozen blocks per epoch costs the same to run as a pool with minimal pledge and delegation, which may not mint even one block per year.
The assignment of blocks is based on the delegated stake rather than on the processing power of the mining machines, as would be the case in a proof of work system.
It costs me a few hundred dollars per month to run my relays and my producer node, with a backup producer node but this is by no means the cheapest way to do it - some people run them on Raspberry Pis.
If you were minting 200 blocks per month in a fully-saturated pool, and it was costing you $200 per month to run the setup, that's about $1 per block. This block would then be rewarded by the system with a few hundred Ada, which would be distributed proportionally among the pool's delegators.
So, in some sense, you will have "mined" each Ada at a cost of less than a cent each. But, unlike a proof of work system, if you were to scale up the hardware in terms of electricity usage, it would make no difference to the number of Ada that were rewarded to the pool.


text:
Cardano-node and cli install "llvm error"
I'm facing error with the llvm install, i tried all the llvm@11;12;13 even the 14 and still a come across error when i move to step "cabal build all" my set up is a M1 pro. Help!  thank you

The M1 Mac is likely to be the issue. I don't use Mac so I can't help.

Could you try to run open ~/.zshrc in your terminal and in that file add export PATH="/usr/local/opt/llvm/bin:$PATH"?
Once you've done that open a new terminal and try to run cabal build all. If the llvm error disappears and show another error related to HsOpenSSL run brew install openssl. Then go to cabal.project in the cardano-node directory and add this:
package HsOpenSSL
  extra-include-dirs: /opt/homebrew/opt/openssl@3/include
  extra-lib-dirs: /opt/homebrew/opt/openssl@3/lib

NOTE: recent versions of homebrew have changed the path from /opt/homebrew/opt to  /usr/local/opt. Please do a manual check to see where your brew installs are getting placed.
Here's a comprehensive document that shows the installation process for Mac (M1 as well)!
https://github.com/mallapurbharat/cardano-tx-sample/blob/main/0_installation/preview_preprod_network/1_macos_m1_process.md

Looks like you might have installed llvm but it isn't in the path. Just to be on the safe side, try the steps in the guide below.
This is adapted from the standard installation documentation, but with some steps added as required based upon various suggestions etc.
This worked for me just a day or two ago on MacOS with M1 chip for 1.35.3, and today I reset based upon IOG's recommendation to 1.35.2 with the same steps, so it is vetted twice over!
UPDATE: Extensively updated the document with various checks that worked for quite a few of my learners with various issues that they faced.
Updated for Preview, Preprod networks (and legacy network as well to some extent)
https://github.com/mallapurbharat/cardano-tx-sample/tree/main/0_installation/preview_preprod_network


text:
Stake Pool Operator - offering financial services?
Is there any chance that stake pool operators could be considered to be offering financial services?
If so, does anyone know whether there is a need to register with any entity or follow any specific rules (examples in different countries would be useful)?
I'm trying to decide whether to run a Cardano stake pool as an individual or as one activity within a technology company that offers IT services.

This is a great question. I think it could be interpreted either way but this is how we have interpreted it.
Our interpretation is no, as a SPO we are not providing a financial service any more than miners would be considered providing a financial service to the Bitcoin blockchain. We operate nodes that make blocks; our service is to the decentralized Cardano chain (technically you could say we are providing a service to anyone that sends a transaction that is included in one of our blocks, but there would be no way to know who that is). Delegators essentially "vote" on which stake pool they trust to make blocks. If they vote on a good pool, the Cardano protocol pays them rewards. They are not paid by the stake pool. The key difference here from a POW mining pool is the pool itself doesn't collect all the rewards first and then distribute them, i.e., we aren't accruing profits for delegators and distributing them. The Cardano network handles all of that.
I'd love to get anyone's thoughts on this. Thanks!

Playing the devil's advocate, you somehow collect the rewards first as you are creating the blocks and thus collecting the fees for your delegators. But I'm no lawyer.

Actually no, the rewards are not paid at time of block production. It's two epochs later after they have been calculated. At that time the protocol pays them out to everyone directly and not to us.

Looking into this for a friend. I think technically the pool operator is not running a financial service. The naming of the staking seems also wrong in ADA this way. This is just signaling. The only real stake is what the pool operator puts up as a collateral. So the pool operator is not taking deposits, custody, is not acting as a fiduciary or controller. I am still unsere as to where the rewards come from. I looked at the blocks in a block explorer (first on google) and did not find the coinbase transaction. I am a very long term Bitcoin guy however (BSV) and the block and fee rewards may work differently in ADA. Are they distributed "later"? If yes that could be interesting point to consider separately.
Nonetheless in many jurisdictions rulings are often not by the only exactly defined stuff. Often it matters if a "quasi" situation is created. In my jurisdiction the highest judges actually read protocols of parliamentary sessions of when the law was defined in order to judge if a new case will "quasi" fit this old intentions or not.  In that view you could even go as far as to categorize ADA as a collective investment scheme. That owners of ADA can earn tokens by not actually doing anything (again they are not staking, right, they are not risking coins) like e.g. building blocks. In every crypto there are different levels of degrees of this. If you e.g. care mostly about laser eyes till 100k and zero about utility, you may much easier be seen as this compared to a project that actually tries to build utility and scale. The lines are never as black and white. But on the surface it truly looks like the pool operator does not touch money or make any contractual promises about money (directly) to the "staker". So AML regulations may not apply here. They mostly seem to apply at the initial purchases of ADA for participants. However there is also liability to consider. Could a big "staker" try and hold the pool liable for a downtime?

I think there would certainly be tax benefits to running it as a business. In the U.S., staking income is taxed as regular income. It looks like this:
Income—->Taxes—>Expenses
I’m also looking at running a stake pool as a business in order to reduce the tax bite, which would look like this:
Income—>Expenses—>Taxes
I’ll try to report back what I learn after talking to my accountant this week.

I found this topic very interesting especially as I consider the proper business operating license for a stake pool.
However, in looking at how the protocol actually works, it seems pretty clear that the stake pool only has one customer, the protocol itself, and has no financial relationships with the delegators.
Thus the stake pool can’t be considered a money processing business, nor can it be responsible for KYC on delegators.
I wrote a detailed article about the topic on Medium.
https://medium.com/@mikerogero/should-stake-pool-operators-do-kyc-follow-the-money-bf0d7e789b31


text:
How many static IPs does one require to run a stake pool?
Do you require 3 static IPs to run a stake pool?

1 for each relay (x2)
1 for a block producing node

Or, can I do 1 static IP, and have all these hostnames point to it:

relay1.domain.com
relay2.domain.com
bpn.domain.com

I've read that it is not recommended to use a Dynamic DNS provider service as there is some downtime between when your IP address changes and when it is updated by the DDNS provider.
I'm assuming that you can specify hostnames in place of IP addresses because someone did mention that DDNS can work, but isn't recommended.*

I am debating running this on hardware at home vs GCP, so any advice will be greatly appreciated. TIA

Do you require 3 static IPs to run a stake pool?

It depends. All your nodes needs a static addresses to talk to each other; this can be IP or dns. If going the IP route, it is best that the block producer IP is local and not public. The relay nodes will need to have public IP addresses.

1 public for each relay (2 public static IPs all together)
for a block producing node (one private static IP)

Now if reserving static IP is tricky, then you can also get away with just domain name resolutions if you use a dns service that propagates ip changes quickly. What you don't want is for your nodes to be cut out from the network while is creating a block.

I'm assuming that you can specify hostnames in place of IP addresses because someone did mention that DDNS can work, but isn't recommended.*

DDNS can work but isn't recommended since those service are often very slow or buggy when it comes to updating dns records. Also, I think DDNS will be more problematic if the upcoming P2P and gossip protocols has any kind of caching layer.

Can you explain why you need 2 public static IPs for each relay? Also, the block-producer IP must be public, otherwise how the relays can see it?

You need 2 altogether, 1 for each; I updated my answer. Your block producer should talk to your relay via a private or local network. Since your block-producer has sensitive information, you don't want the out getting in while still allowing all the things already in to talk to each other.

It's not a requirement to have static public IPs for each relay - you can easily share a single IP address and have them on different ports (assuming you have the ability to forward these on, for ex. using NAT).

You need to ensure that if your pool creates a block, that this is properly propagated to the rest of the network. So, your pool needs to be connected to the Cardano network at this specific time.
When your IP changes and the DDNS updates this record, it take take up to 5 minutes or more to propagate this DNS change to the rest of the internet. Your peers will probably detect that your IP is down and will try to reconnect.
So, to answer your question: it depends. Can you ensure the change of IP is made in a way that does not break your connection to the network or that it does so not when your block creation is scheduled?
I would say, it is possible, but not sure if it is worth to put in the effort. Can you buy a static IP from your ISP?

Thanks Marek! My question was more to the number of static IPs required for this endeavor - i.e. do all 3 machines (2 relays + 1 block producing node) require 1 static IP each? I will edit my question so this is clearer :)

You do not need a static public IP address for each node. You can easily run multiple relays on a single public IP address using different ports (eg. behind NAT/port forwarding).
Eg.
1.2.3.4 port 3001 -> relay 1
1.2.3.4 port 3002 -> relay 2

You could then point all of the hostnames to that IP but you must use the port numbers when connecting/listing them on-chain. Unlike with HTTP where multiple hostnames can run on a single IP/port (using the HOST header), that's not the case here.
Of course to do this, you'd need to be able to forward the ports from the device with that IP so this may depend on your exact setup (but a home router likely can do this with its port forwarding - I did exactly this with my first testnet pool, having two relays running at home).
Your relays/producer will still need some static internal IP address/hostname that they can connect to each other on (since they will need to be listed in each others topology files).


text:
Tx consuming script fails with: Caused by: (unConstrData #44000de140)... Third data argument, does not decode to a context when burning an NFT
I've this tx trying to submit to cardano-node 1.35.5:
[encoded data, 22964 characters]

Where there are two scripts one for minting policy and the other for spending. I'm getting this error (sorry no enough characters for the error's text):

It basically says cannot call the spending script since cannot create the script context:
The third data argument, does not decode to a context....
The scripts signature are like this:
userTokenValidate :: BuiltinByteString -> BuiltinByteString -> Policy -> ValidatorHash -> Action -> ScriptContext -> Bool

referenceTokenValidate :: BuiltinByteString -> BuiltinByteString -> Policy -> DatumMetadata -> RefAction -> ScriptContext -> Bool

and this is the relevant data types:
data DatumMetadata = DatumMetadata {
                     metadata :: BuiltinData
                   , version :: Integer
                   , extra :: BuiltinData
}
instance Eq DatumMetadata where
    {-# INLINABLE (==) #-}
    (==) :: DatumMetadata -> DatumMetadata -> Bool
    DatumMetadata m v e == DatumMetadata m' v' e' = m == m' && v == v' && e == e'
makeLift ''DatumMetadata
makeIsDataIndexed ''DatumMetadata [('DatumMetadata, 0)]

data RefAction = Burn | Move | Upgrade
makeLift ''RefAction
makeIsDataIndexed ''RefAction [('Burn, 0), ('Move, 1), ('Upgrade, 2)]

data Action = MintNFT | BurnNFT | MintExtra
makeLift ''Action
makeIsDataIndexed ''Action [('MintNFT, 0), ('BurnNFT, 1), ('MintExtra, 2)]

Notice the first 3 parameters where parameterized for referenceTokenValidate and the 4 first for userTokenValidate so the final scripts passing to the tx are like "regular" scripts.
Here is the datum from the UTxO I want to spend it (it was created with data hash and real data in the witness set): https://preprod.cardanoscan.io/datumInspector?datum=d8799fa7446e616d655054616e676f434950303036382330313145696d6167655835697066733a2f2f516d53696e53595559526f3841437443583572636a526864413961476631564d734a413531514b677a326e57476449636f707972696768745054616e676f63727970746f2032303233466172746973744b54616e676f63727970746f496d656469615479706543706e674a636f6c6c656374696f6e5654616e676f63727970746f20436f6c6c656374696f6e4774776974746572582068747470733a2f2f747769747465722e636f6d2f74616e676f5f63727970746f0180ff. It was created like this:
...
const rawMetadata = Seed.buildPlutusData(token.metadata);
const plutusMetadata = PlutusData.from_json(JSON.stringify(rawMetadata), 1)
const fields = PlutusList.new();
fields.add(plutusMetadata);
fields.add(PlutusData.new_integer(BigInt.from_str(version.toString())));
fields.add(PlutusData.from_json(JSON.stringify(Seed.buildPlutusData(extra)), 1));
const plutusData = PlutusData.new_constr_plutus_data(
    ConstrPlutusData.new(toBigNum(0), fields)
)
plutusData.to_hex()

using CSL I put it in the invalid tx this way (also tried the commented line):
// const pData = PlutusData.new_constr_plutus_data(ConstrPlutusData.from_hex(inputData));
const pData = PlutusData.from_hex(inputData);

Tacking a closer look to the tx cbor structure I noticed the datum and redeemers are like this:
4: [
    121([
        {'name': 'TangoCIP0068#011', 'image': 'ipfs://QmSinSYUYRo8ACtCX5rcjRhdA9aGf1VMsJA51QKgz2nWGd', 'copyright': 'Tangocrypto 2023', 'artist': 'Tangocrypto', 'mediaType': 'png', 'collection': 'Tangocrypto Collection', 'twitter': 'https://twitter.com/tango_crypto'},
    1,
    []
    ])
],
5: [[1, 0, 122([[]]), [1943838, 544610828]], [0, 1, 121([[]]), [1943838, 544610828]]]

And from the error we have this:
he data is: Constr 0 [Map [(B \"name\",B \"TangoCIP0068#011\"),(B \"image\",B \"ipfs://QmSinSYUYRo8ACtCX5rcjRhdA9aGf1VMsJA51QKgz2nWGd\"),(B \"copyright\",B \"Tangocrypto 2023\"),(B \"artist\",B \"Tangocrypto\"),(B \"mediaType\",B \"png\"),(B \"collection\",B \"Tangocrypto Collection\"),(B \"twitter\",B \"https://twitter.com/tango_crypto\")],I 1,List []]
The redeemer is: Constr 0 [List []]

So no sure why cannot create the script context though.

The script context error can be a red herring. Double check for any reason why a script data may not be successfully deserialised.

Hi @james, I've no clue at this point what is happening, what should I look for? This is how my script is serialized:
referenceTokenValidateInstance :: Validator referenceTokenValidateInstance = Validator $ fromCompiledCode ($$(compile [|| wrap ||]))   where     wrap label222 label100 policy = mkUntypedValidator $ referenceTokenValidate (unsafeFromBuiltinData label222) (unsafeFromBuiltinData label100) (unsafeFromBuiltinData policy)  The minting script works and the only difference is mkUntypedMintingPolicy instead of mkUntypedValidator

I don't see how it could be expected to work if the only difference is the function being used because minting expects (r -> sc -> Bool) whereas spending requires (d -> r -> sc -> Bool).  It's not apparent to me what the cause of your problem is. I can take a look if you are willing to give me full read access to the codebase.


text:
Missing MissingVKeyWitnessesUTXOW when signing tx with PaymentSigningKeyShelley_ed25519 key
I'm trying to get skey PaymentSigningKeyShelley_ed25519 from PaymentExtendedSigningKeyShelley_ed25519_bip32.
Here is the extended key:
{
    "type": "PaymentExtendedSigningKeyShelley_ed25519_bip32",
    "description": "Payment Signing Key",
    "cborHex": "5880608550a89ba16a920b365e77131ba1c702d5d825025d1c91190992a6465df7545919c017426267e5a9eff84ecb35f3cdbb6701036141ade1cc3980c6166e741b1dbaa54ec25531278af95388ff2f96b5c986b33fc693ebfc3c17e050cbe57a7f62777711a09bd4b66522668489fbe3b7f61a0f89c8331b30399bc69bff604976"
}

and normal key:
{
      "type": "PaymentSigningKeyShelley_ed25519",
      "description": "Payment Signing Key",
      "cborHex": "5820608550a89ba16a920b365e77131ba1c702d5d825025d1c91190992a6465df754"
}

For address: addr_test1qr69yj887txwu7ca7s9g5lr6sm7p8sf4dac295g7c44rfvma6t5aw0lpzxyk4r0r9tpdmremh0g37nal3q8fhjy97xwqpu4d5c I can sign tx successfully using the extended key, but not using the normal key.
Here is the cardano-cli (v1.35.3) command I'm using:
cardano-cli transaction sign --tx-body-file tx.raw --signing-key-file payment.skey --testnet-magic 1 --out-file tx.signed

Does anyone knows what's wrong here?
Note: Using Bip32PrivateKey#to_raw_key() the result hex is 64 bytes instead of 32 from the origin key I shared. I was able to submit the tx using csl and 64 bytes from the extended key:
   static getPrivateKey(key: string): PrivateKey {
        if (key.startsWith('xprv1')) {
            return Bip32PrivateKey.from_bech32(key).to_raw_key();
        } else {
            const unhex = Buffer.from(key, 'hex');
            const decode = cbor.decode(unhex);
            try {
                return PrivateKey.from_normal_bytes(decode);
            } catch (err) {
                return PrivateKey.from_extended_bytes(decode);
            }
        }
    }

cborHex: '5840608550a89ba16a920b365e77131ba1c702d5d825025d1c91190992a6465df7545919c017426267e5a9eff84ecb35f3cdbb6701036141ade1cc3980c6166e741b'
cardano-cli isn't working with this 64 bytes version though.


text:
is it possible to use (bip39) 12 words passphrase in yoroi?
Currently I have a 12 words passphrase that I use over some wallets like exodus and metamask, I want to use the same 12 words on yoroi but yoroi only allows me to use 15 or 24 words.

I was under the impression that yoroi uses bip39 standard, why I can't create a wallet with only 12 words?
What is the technical limitation that prevents yoroi to use 12?
Is there an existing way (without coding it myself) to transform my 12 words into 15?, or 24?, assuming that 12 word passphrases are just 12*11=132 bits of entropy (128 bit entropy + 4 bit checksum) [reference here]

I want to avoid creating a new wallet entirely and now having to backup 12+24=36 words for reasons out of this scope.
(like for example I already etched the 12 words in metal using carbon atoms and I don't want to do it again because is expensive).

Yoroi dev here.
Yoroi uses 15 words because we think it's the best trade-off between security and convenience. Using more words may provide marginal security benefits, but you also have downsides like more difficulty if you want to memorise your mnemonics, more risk of writing down the wrong word or in the wrong order during backups, more inconvenience using offline metal backup devices (because you need to backup more words) and so on.
We also allow to recover 24-word mnemonics so that Daedalus users can use Yoroi if they want to. But allowing for more options compromises usability/UX. It's not a technical choice.
I don't see why you could not "stretch" a 12-word recovery phrase to obtain 15 words. You just need to make sure that the checksum is valid.
Finally, and more importantly, I am not sure that trying to use the same recovery phrase to manage multiple wallets is a good practice (hardware wallets are an exception of course). But ultimately, it's your choice.

thank you very much for answering, now I understand 15 words is just a choice and 12 words is not a technical limitation.
Regarding the stretching is less secure because it reduces the search space for brute force if the attacker knows it was a key generated by stretching 12 words, defeating the purpose of using more, but I envision one way to stretch it is to just add more bits from the checksum (37 bits) then it will make 128+37=165 or 15 11bit words.

Finally, using the same recovery phrase for multiple wallets shall not be a problem as long the wallet phrase is secured like in a hardware wallet, also that's the idea of HD wallets, to serve multiple coins, and therefore multiple wallets if a coin is not listed in a wallet of choice, I think®

Yes, agree, but it depends on how you manage it.  If you are constantly restoring mnemonic wallets in multiple devices, then it's an issue. Or if some apps, for some reason, are storing your root key, then there is a risk that all your wallets get exposed.

thanks for your insights, the best option here is just to create a new wallet with 15 or 24 words and make a metal backup of it also, this is why I am accepting this as the answer, please have a good day

After reading the bip39 specification, I learned that a 12 word mnemonic phrase was generated using an entropy of 128 bits, if I want to use a 24 word passphrase, there shall be no way to generate it from a 12 word list the entropy for a 24 word mnemonic phrase uses a 256 bit entropy + 8 bits of checksum which finally generates a 256 + 8 = 264 bits of random bits that can be split on 24 words of 11 bits, thus using the 2048 (2^11) words in the bip39 word list.
I wonder if I can use a key stretching algorithm like PBKDF2+HMAC-SHA512 algorithms, to produce a 256-bit (or it's first 256 bits) values as its final output in order to generate the 24 words mnemonic phrase I want, from only a list of 12 words, but I am not sure about how secure this is (well, of course is less secure because I cut the search space in half).
For now, I think the most secure way to obtain a 24 words mnemonic passphrase is to just create a new wallet on yoroi and just manage 2 mnemonic phrases, one with 12 words for btc and other altcoins (via trezor wallet and exodus), and a 24 word mnemonic phrase for cardano using yoroi :c
I leave this answer for any future reader, please let me know if I am wrong, please have a good day.


text:
How do I add the staking part of an address in OffChain code
I am currently on tag: v2022-04-06 of plutus-apps and was wondering how to create Lookup and Constraints for a typedValidator that checks whether the input was returned to the script with the correct staking credential. I was hoping to find someone here that could tell me if that is currently possible or not.
In processConstraint it also looks like it just uses Address.scriptHashAddress to generate the address for this constraint, which does not include any staking credentials. (on tag v2022-04-06)
I have seen a few commit messages in plutus-apps for a new constraint via
mustPayToOtherScriptAddress for a later release, but maybe it is already possible and I am just looking in the wrong place.
This is what I currently have written: (it pays to the script but validation fails because it doesn't pay to an address with staking credentials)
      l         = Constraints.typedValidatorLookups factoryV <>
                  Constraints.otherScript (Scripts.validatorScript factoryV) <>
                  Constraints.mintingPolicy policy <>
                  Constraints.unspentOutputs utxos

      tx        = Constraints.mustPayToTheScript datum (nftValue) <>
                  -- ?? Constraints.mustPayWithDatumToPubKeyAddress (scriptAddress factoryV) (Nothing) datum (nftValue) <>
                  Constraints.mustMintValue chunkValue <>
                  mconcat [Constraints.mustPayToOtherScript chunkVHash (Datum $ PlutusTx.toBuiltinData (ChunkDatum x)) singleCVal | x <- [start..(start+n-1)]] <>
                  Constraints.mustSpendScriptOutput ((Map.keys utxos) !! 0) r
  unbalanced <- adjustUnbalancedTx <$> mkTxConstraints l tx

In factoryV I just check for the existance
    checkStakingCredential :: Bool
    checkStakingCredential = case addressStakingCredential . txOutAddress $ factoryOutput of
      Just _ -> True
      _       -> False

I figured out a way to do this.
After looking at the implementation of adjustUnbalancedTx I came up with the following:
-- adjust the contracts address to use the given staking credential in the given UnbalancedTx
adjustContractAddress ::
  ValidatorHash ->
  StakingCredential ->
  UnbalancedTx -> UnbalancedTx
adjustContractAddress vH sK =
    over (tx . Tx.outputs . traverse) adjust
  where
    adjust :: TxOut -> TxOut
    adjust txOut = txOut
      { txOutAddress=
        if (addressCredential . txOutAddress) txOut == ScriptCredential vH
        then Address (ScriptCredential vH) (Just sK)
        else txOutAddress txOut
      }

using the function above I can now adjust my transaction by changing how I construct it as follows:
unbalanced <- adjustContractAddress (Scripts.validatorHash factoryV) (StakingHash $ PubKeyCredential somePubKeyHash) <$> adjustUnbalancedTx <$> mkTxConstraints l tx

I hope this will be useful for some of you ;)


text:
InlineDatum on ReferenceOutput in OffChain code
I tried to use the inline datum of a reference input in the minting policy below:
{-# INLINABLE validateMinting2 #-}
validateMinting2 :: TxOutRef -> BuiltinData -> BuiltinData -> ()
validateMinting2 oref _ rawCtx =
  check $
    if not hasUsedUTXO
      then not $ cdEndContract contractData
      else True

  where
    ctx = unsafeFromBuiltinData rawCtx
    symbol = ownCurrencySymbol ctx
    info = scriptContextTxInfo ctx
    inputs = txInfoInputs info
    contractData = case filter f $ map m $ txInfoReferenceInputs info of
      [TxOut{txOutDatum}] -> case txOutDatum of
        NoOutputDatum -> traceError "NoDat"
        OutputDatumHash _ -> traceError "Hash"
        OutputDatum (Datum d) -> case fromBuiltinData @ContractData d of
          Just dat -> dat
          _        -> traceError "nothing"
      _   -> traceError "nope"
      where
        f TxOut{txOutValue} = valueOf txOutValue symbol contractDataTokenName == 1
        m inInfo = txInInfoResolved inInfo

    hasUsedUTXO :: Bool
    hasUsedUTXO
      | [_] <- filter ((oref ==) . txInInfoOutRef) inputs = True
      | otherwise                                         = False

When I use the cli to mint with reference input (--read-only-tx-in-reference) everything works as expected and the inline datum can be used, but when I try to write offchain code for this it fails with:
Contract instance stopped with error: "WalletContractError (ValidationError (ScriptFailure (EvaluationError [\"Hash\"] \"CekEvaluationFailure: An error has occurred:  User error:\\nThe machine terminated because of an error, either from a built-in function or from an explicit use of 'error'.\")))"
This error is shown when I use the following offchain code:
  pkh <- ownFirstPaymentPubKeyHash
  outRef <- getUnspentOutput
  o      <- fromJust <$> unspentTxOutFromRef outRef
  let
    policy     = mintValidator outRef
    symbol     = scriptCurrencySymbol policy
    mintValue  = Value.singleton symbol contractDataTokenName 1 <> Value.singleton symbol chunkCreationTokenName 1 <> Value.singleton symbol (chunkTokenName 0) 1
    l          = Constraints.unspentOutputs (Map.singleton outRef o) <> Constraints.plutusV2MintingPolicy policy
    constr     = Constraints.mustMintValueWithRedeemer (Redeemer $ toBuiltinData ()) mintValue <>
                 Constraints.mustSpendPubKeyOutput outRef <>
                 Constraints.mustPayWithInlineDatumToPubKey pkh (Datum $ toBuiltinData $ ChunkDatum (Address (PubKeyCredential $ unPaymentPubKeyHash pkh) Nothing)  "") (Value.singleton symbol chunkCreationTokenName 1 <> Value.singleton symbol (chunkTokenName 0) 1) <>
                 Constraints.mustPayWithInlineDatumToPubKey pkh (Datum $ toBuiltinData $ ContractData [] [] 100000 False) (Value.singleton symbol contractDataTokenName 1)
-- ... create, sign, submit ...
  ciTransaction <- fmap (txOutRefMap . fromJust) $ txFromTxId $ getCardanoTxId signed
  let
    fVal tokenName (citxo, _) = valueOf (citoValue citxo) symbol tokenName == 1
    [dataRef] = Map.keys $ Map.filter (fVal contractDataTokenName) ciTransaction
    [chunkRef] = Map.keys $ Map.filter (fVal (chunkTokenName 0)) ciTransaction

  dataOut      <- fromJust <$> unspentTxOutFromRef dataRef
  chunkOut     <- fromJust <$> unspentTxOutFromRef chunkRef
  addr <- ownAddress
  let
    dat = Datum $ toBuiltinData $ ContractData [] [] 100000 False
    mintValue2 = Value.singleton symbol (otherTokenName 0 0) 1
    l2          = Constraints.plutusV2MintingPolicy policy <> Constraints.unspentOutputs (Map.singleton chunkRef chunkOut <> Map.singleton dataRef dataOut) <> Constraints.otherData dat
    constr2     = Constraints.mustReferenceOutput dataRef <> Constraints.mustMintValueWithRedeemer (Redeemer $ toBuiltinData ()) mintValue2 <> mustSpendPubKeyOutput chunkRef <>
                  Constraints.mustPayWithInlineDatumToPubKey pkh (Datum $ toBuiltinData $ OtherDatum 0 0 0 addr 2000000) (Value.singleton "" "" 2000000 <> mintValue2) <>
                  Constraints.mustPayWithInlineDatumToPubKey pkh (Datum $ toBuiltinData $ ChunkDatum (Address (PubKeyCredential $ unPaymentPubKeyHash pkh) Nothing)  "") (Value.singleton symbol chunkCreationTokenName 1 <> Value.singleton symbol (chunkTokenName 0) 1)
-- ... create, sign, submit ...

Why does the transaction that is created in offchain code not contain the inline datum but a hash?
Is this currently possible with plutus-apps or do I still have to wait for this feature to be implemented?
If this is not possible at the moment I have one additional question: Is there a way to profile the execution cost of a script with the cardano-cli? I only know of --calculate-plutus-script-cost which produces a json file of the cost, but I also want to know which part of the script cost how much, similar to the  writeScriptsTo way.

The offline code is dependente of plutus-apps and this project lags behind the nodes features.
Look at diferente tags/branches for plutus-apps...


text:
Are NFT policies interchangeable between networks?
Generating a policy doesn't require a running node; the cardano-cli alone is sufficient. Since no connection is made to the network, can I assume there's no difference between a policy on preprod and mainnet? In other words, can I use the same policy to mint on all the different networks?
The only difference will be the expiry slot because the reference slot will differ between networks.

As it turns out, they are. I've minted NFTs on preprod and mainnet with the exact same keys and policy.
Here's the policy on preprod:
https://preprod.venster.io/policies/3333acb55ed79731ea6658abb74f453cbb87e15aee01a7aab484b2a6
Here's the same policy on mainnet:
https://venster.io/policies/3333acb55ed79731ea6658abb74f453cbb87e15aee01a7aab484b2a6


text:
Transactions without input addresses
I'm building a minting engine for a project and I found something strange today. One of the incoming transactions, which I pull from a Cardano Wallet (testnet) service has an input without an address. All the other transactions do have an input address. They're all transactions between two wallets I manage in ccVault, and always from wallet 1 to wallet 2.
So I'm wondering now, under which conditions does a transaction input not contain an address?
The transactions I'm talking about are the following.
Without input address (first try)
https://testnet.cardanoscan.io/transaction/44964910dee982af3f714a6e4f3e50670aa9f3ef90debced9b4785d6a28bc350
{
    ...
    "amount": {
        "quantity": 37023500,
        "unit": "lovelace"
    },
    "inputs": [
        {
            "id": "3c1c5b73ab66d18efa2540f59df345a702820833264519c69f9c79cbc07bce3c",
            "index": 1
        }
    ],
    ...
    "id": "44964910dee982af3f714a6e4f3e50670aa9f3ef90debced9b4785d6a28bc350",
    ...
}

With input address (second try)
https://testnet.cardanoscan.io/transaction/3f776bd594b43d6288bde265e5aa3aead414585ff664fef4736f0b42ce7db695
{
    ...
    "amount": {
        "quantity": 37023500,
        "unit": "lovelace"
    },
    "inputs": [
        {
            "amount": {
                "quantity": 683493813,
                "unit": "lovelace"
            },
            "address": "addr_test1qp608umcxnpuj869hu2an658pegt8rsgtu9kh9tmfy3kqcktz647sk9ds3hkrg888edxrgc708mfw2cncldqzzq7em4qzrctsk",
            "id": "44964910dee982af3f714a6e4f3e50670aa9f3ef90debced9b4785d6a28bc350",
            "assets": [],
            "index": 1
        }
    ],
    ...
    "id": "3f776bd594b43d6288bde265e5aa3aead414585ff664fef4736f0b42ce7db695",
    ...
}

UPDATE:
Just to clarify, they are both outgoing transactions from Wallet 1 to Wallet 2. Only the first one doesn't arrive with an input address, while the second one does:

I believe the issue boils down to the fact, that "the wallet does not maintain a complete ledger but only a subset narrowed down to the assets belonging
to the wallet" (see https://github.com/input-output-hk/cardano-wallet/issues/2434#issuecomment-757169360)
It should show the addresses and assets only for outgoing transactions according to the docs here https://input-output-hk.github.io/cardano-wallet/api/edge/#operation/getTransaction

assets and address are always present for outgoing transactions but
generally absent for incoming transactions. This information is
present on the Cardano explorer, but is not tracked by the wallet.

Not sure why it is actually showing for the other incoming transactions.
Anyhow that api is probably not the right tool for the job, but instead you need to use an explorer api like cardano-graphql or a service like Blockfrost, that will return the data through this endpoint: https://cardano-testnet.blockfrost.io/api/v0/txs/44964910dee982af3f714a6e4f3e50670aa9f3ef90debced9b4785d6a28bc350/utxos (see screenshot below)
There is a feature request for this though in cardano-wallet here:
https://github.com/input-output-hk/cardano-wallet/issues/2710
(And another related issue here: https://github.com/input-output-hk/cardano-wallet/issues/2617)

I'm not sure what you mean. They are both transactions initiated from Wallet 1 to Wallet 2. I've done about 100 payments in the same direction, except for this one (with input address addr_test1qphxhe0l6v6...), they all arrived with an input address in Wallet 2.

Sorry you're absolutely right. Was just seeing that one address ("addr_test1qp608umcxnpuj869hu2an658pegt8rsgtu9kh9tmfy3kqcktz647sk9ds3hkrg888edxrgc708mfw2cncldqzzq7em4qzrctsk") in the outputs of the first and as the input for the second transaction. But its change only in the first tx. So my guess is it still might be related to the issue above, but I'll take another look at it

When pulling the json you posted above, are you using the same walletId parameter in both cases? For this endpoint: https://localhost:8090/v2/wallets/{walletId}/transactions/{transactionId}

In any case maybe you could look at the "direction" attribute also in the response, as for "incoming" transactions there are just few cases that the address field should be populated: https://github.com/input-output-hk/cardano-wallet/issues/2617#issuecomment-821864615 and here https://github.com/input-output-hk/cardano-wallet/issues/2434#issuecomment-757169360

Okay did some editing on this one, hope this answer works better. Although I can't exactly tell yet what is causing the info to be missing from the cardano wallet api in this specific case (there's a few options), the solution should stay the same :)

When pulling the json you posted above, are you using the same walletId parameter in both cases? For this endpoint: localhost:8090/v2/wallets{walletId}/transactions/{transactionId}
Yes, and in both cases the address is missing for those transactions. I could use the change address, which is the last one in the outputs. That one seems to be always present. So far I can see, it is.
But you're probably right about it not being the right tool for the job. I've got a cardano-db-sync server as well, so I'll try pulling the required information for there.
Thanks for your answers!>


text:
Using Plutus PAB for development instead of Playground
trying to migrate away from the playground and seems like PAB is the way to go. The plutus starter repository orignally seems to be the best place to start but it seems to be outdated (i.e. still using ValidatorCtx instead of ScriptCtx). So Im looking the plutus-pab in the main plutus repo. I ran the all-servers script and tried activating the in built plutus game contract using the HTTP api of the webserver but encounted an error in the json object stating that the caID shld be a binary instead of a string. How do I overcome this? Thanks.

Hi Shannon, could you please provide some more information? Links to the repositories you're using, the exact steps you did and the full error message would be helpful.

caID is part of ContractActivationArgs - are you sure the error message is telling you that this should be a binary (and not maybe a ByteString - which is different than String)?

Added a screenshot of what I see with the latest code as of now. I remembered the error being a binary but now it shows an object; I'll just take it that I remembered wrongly. Where do I find the caID for the built-in contracts? Thanks.


text:
adaOf encodes Lovelace/Ada ratio in phantom type
adaOf encodes Lovelace/Ada ratio in phantom type Micro
adaOf :: Micro -> Ada
type Micro = Fixed E6
newtype Fixed (a :: k) = MkFixed Integer

Question: Being that the ratio is already encoded in the type, can I somehow get it, such that I can have a function that takes actual Ada token quantity -- not Lovelace quantity -- and gives back Ada, without hardcoding?
f :: Integer -> Ada
f adaQty = Lovelace (1_000_000 * n) -- don't really want to do this

I actually found the constant in the plutus repo:
lovelacePerAda = Constant 1000000

That constant you found probably isn't the one to use, since it's in the Marlowe libraries. Why are you interested in denominating in major units in your Plutus code? I could see the need in your UI.

Use adaOf
In a GHCi session with plutus-ledger-api in scope:
> import Plutus.V1.Ledger.Ada
> adaOf 1
Lovelace {getLovelace = 1000000}

Great! So that constant I found in Marlowe appears to be a mistake, because it is introducing a second source-of-truth.


text:
Is awaitTxConfirmed mandatory?
I am running into timing issues, and am considering leaving out awaitTxConfirmed.
Is that wise?

You may broadcast transactions in fire and forget manner. If the fact whether it got into a block or not is not important to you, skipping  awaitTxConfirmed is not a bad idea.

If you don't care whether a transaction has not been added to the ledger, then you can skip awaitTxConfirmed. But in that case, do you need to use blockchain in the first place?
What are the timing issues? Why do you have timing issues? What are you trying to accomplish? Do you need confirmation that a transaction has been added to the ledger? What if it hasn't and you're assuming the transaction has been confirmed and you act upon a false assumption?
There's not enough information to give you an answer, but these questions might help you in coming up with your own answer.


text:
Funding emulator wallets with custom currencies
How exactly can I fund the emulator wallets with custom currencies?
Please show an emulator example doing so.

Here's an example:
import Data.Default (def)
import qualified Data.Map as Map
import qualified Ledger.Ada as Ada
import qualified Ledger.Value as Value
import Wallet.Emulator.Wallet (Wallet(..))
import Plutus.Trace.Emulator (EmulatorTrace, EmulatorConfig(..), runEmulatorTraceIO',
                              activateContractWallet)

main :: IO ()
main = do
  let dist = Map.fromList [ (Wallet 1, Ada.lovelaceValueOf 100_000_000
                                    <> Value.singleton "ffff" "mytoken" 10)
                          , (Wallet 2, Ada.lovelaceValueOf 25_000_000)
                          ]
      emCfg = EmulatorConfig (Left dist) def def
  runEmulatorTraceIO' def emCfg myTrace

In summary, Wallet 1 starts of with 100 ADA, and 10 tokens with currency symbol ffff and token name mytoken. Wallet 2 simply starts with 25 ADA.
The Auction use-case example demonstrates that.

Thanks, but I didn't find as such in the example you pointed to.

Is there a way to show the final fine-grained distribution of Value amongst all the wallets (i.e., all the various currencies)?

If you mean the distribution of Value for all the wallets at the end of emulation, then the answer is that you don't need to do anything more than the example above. The function runEmulatorTraceIO prints the distribution for all wallets in the terminal at the end of emulation.

the easier way I found:
dist = Map.fromList [ (wallet 1, Ada.lovelaceValueOf 1_000_000_000 ) -- treasury
                        , (wallet 2, Ada.lovelaceValueOf 1_000_000_000
                            <> Value.singleton yacadaNFTSymbol  (U.giveReferralNFTName )  15) -- referral

in : https://github.com/cmorgado/yacada_learning

12/2022, plutus-apps v1.0.0 update on the accepted answer.
Wallet 1 is not working anymore. You can use knownWallet 1.
Or you can import Plutus.Contract.Test (w1, w2) and then use w1 , w2 as your simulated wallets.
Also EmulatorConfig has 2 components, not 3. So it is:
emCfg = EmulatorConfig (Left dist) def
BTW I get error when setting initial state with custom currencies.


text:
How to instantiate ToSchema for ADT?
If I have
data Thing1 = I Integer | S String

how do I instantiate ToSchema for it?  Note that deriving doesn't work.
And how about for
data Thing2 = I Integer | S

It's not possible to use Sum types with Swagger, see relevant plutus issue, you need to wait for the following PR adding OpenAPI3 support https://github.com/input-output-hk/plutus/pull/3807


text:
How to obtain PubKeyHash from Address ShelleyAddr
Is there a way to do this programmatically? I have an
Address ShelleyAddr
obtained from
deserialiseFromBech32 AsShelleyAddress
and need its
Plutus.V1.Ledger.Crypto.PubKeyHash

There is now the function shelleyPayAddrToPlutusPubKHash in cardano-api which returns Maybe PubKeyHash because in the case of a script credential there is no corresponding public key hash.

I cannot find shelleyPayAddrToPlutusPubKHash. How exactly do I import it?

In cabal.project, what tag hash do I use for source-repository-package   type: git   location: https://github.com/input-output-hk/cardano-node.git ?

This compiles with a recent version of cardano-node and plutus:
import Plutus.V1.Ledger.Api (PubKeyHash)
import Cardano.Ledger.Alonzo.TxInfo (transKeyHash)
import Cardano.Api (ShelleyAddr)
import Cardano.Api.Shelley (Address (ShelleyAddress))
import Cardano.Ledger.Shelley.API (Credential (KeyHashObj, ScriptHashObj))

addrToPkh :: Address ShelleyAddr -> PubKeyHash
addrToPkh (ShelleyAddress net (ScriptHashObj sh) sr) = transKeyHash sh
addrToPkh (ShelleyAddress net (KeyHashObj kh) sr) = transKeyHash kh

Is there such a thing as an AlonzoAddr (via deserialiseFromBech32 AsAlonzoAddress)? I am only using ShellyAddr because that's what I found in the API.

cabal build is giving me: unknown package: cardano-ledger-shelley. Not sure what to do.

@Kwaggy: AlonzoAddr is fine and to make it compile you need to add cardano-ledger-shelley to your code's .cabal file in the build-depends section and maybe ensure you are having the https://github.com/input-output-hk/cardano-ledger-specs as a source-repository-package in cabal.project (depends a bit on your workflow).

@Sebastian Nagel: Where do I find AlonzoAddr?

@insitu: For recent version of cardano-node, I downloaded pre-compiled executable from https://docs.cardano.org/getting-started/installing-the-cardano-node and parked the unzipped in my root dir. How do I teach cabal about it, such that .cabal file is happy with having cardano-ledger-shelley in its build-depends section?

@Kwaggy: There is no AlonzoAddr as far as I know. You might expect one as you read ShelleyAddr, but in fact the "alonzo era is a shelley era", so ShelleyAddr is just fine.
To get the cardano-ledger-shelley you do not need the pre-compiled executable, but need to adapt the cabal.project file, e.g. like this https://github.com/input-output-hk/hydra-poc/blob/master/cabal.project#L85-L112 -> cardano-ledger-shelley is in the eras/shelley/impl directory of the ledger specs repo. You can also ask in the #ask-hydra channel on the IOG Discord for more help: https://discord.gg/y5kfwHtm

@SebastianNagel: I am running into cabal build error: Failed to build plutus-chain-index-0.1.0.0., and cabal clean does not help.

@SebastianNagel: Please see https://gist.github.com/paul-outlaw/130764aa1da5cb2c93c5be3c550a19e6

@Kwaggy Sorry, I do not really understand your question: Cabal dependencies require source code, either from a package or from a git repository. BTW, I have commented your gist, seems like your SHA1 are not correctly set which would explain the compilation error you see.


text:
String in Datum
I want to use String or Text in a Datum, like this:
import PlutusTx.Prelude

newtype MyDatum = MyDatum {userReadableStuff :: BuiltinString}
PlutusTx.unstableMakeIsData ''MyDatum

but the complier complains:
• No instance for (PlutusTx.IsData BuiltinString)
    arising from a use of ‘PlutusTx.fromBuiltinData’
• In the second argument of ‘(<*>)’, namely
    ‘PlutusTx.fromBuiltinData arg_a2lNn’
  In the second argument of ‘PlutusTx.Builtins.matchList’, namely
    ‘(pure MyDatum <*> PlutusTx.fromBuiltinData arg_a2lNn)’
  In the expression:
    ((PlutusTx.Builtins.matchList t_a2lNq)
       (pure MyDatum <*> PlutusTx.fromBuiltinData arg_a2lNn))
      (\ _ _ -> Nothing)typecheck(-Wdeferred-type-errors)
• No instance for (PlutusTx.IsData BuiltinString)
    arising from a use of ‘PlutusTx.toBuiltinData’
• In the first argument of ‘PlutusTx.Builtins.Internal.mkCons’, namely
    ‘(PlutusTx.toBuiltinData arg_a2lNi)’
  In the second argument of ‘PlutusTx.Builtins.Internal.mkConstr’, namely
    ‘((PlutusTx.Builtins.Internal.mkCons
         (PlutusTx.toBuiltinData arg_a2lNi))
        (PlutusTx.Builtins.Internal.mkNilData
           PlutusTx.Builtins.Internal.unitval))’
  In the expression:
    (PlutusTx.Builtins.Internal.mkConstr 0)
      ((PlutusTx.Builtins.Internal.mkCons
          (PlutusTx.toBuiltinData arg_a2lNi))
         (PlutusTx.Builtins.Internal.mkNilData
            PlutusTx.Builtins.Internal.unitval))typecheck(-Wdeferred-type-errors)
• No instance for (PlutusTx.IsData BuiltinString)
    arising from a use of ‘PlutusTx.unsafeFromBuiltinData’
• In the first argument of ‘MyDatum’, namely
    ‘(PlutusTx.unsafeFromBuiltinData arg_a2lNv)’
  In the expression:
    MyDatum (PlutusTx.unsafeFromBuiltinData arg_a2lNv)
  In the expression:
    let
      t_a2lNy = PlutusTx.Builtins.Internal.snd tup_a2lNu
      arg_a2lNv = PlutusTx.Builtins.Internal.head t_a2lNy
    in MyDatum (PlutusTx.unsafeFromBuiltinData arg_a2lNv)typecheck(-Wdeferred-type-errors)

I could use ByteString -- about which the compiler has no complaints, and then use helper functions for
Text <-> ByteString, as shown at end of this.  But what I really want is for end user to see the datum in the script, and be able to read directly from the datum.

Not really sure what you mean by "end user to see the datum in the script" and how having a Text or String in the datum would make any difference to this. Datums are not easily visible to everyone and certainly not to "end users".
However, if you want to use BuiltinString in MyDatum, you could write your own instances for ToData, FromData and UnsafeFromData via BuiltinByteString and encodeUtf8/decodeUtf8 from PlutusTx.Builtins.
Something like the following could work:
instance ToData MyDatum where
  toBuiltinData = toBuiltinData . encodeUtf8 . userReadableStuff

instance FromData MyDatum where
  fromBuiltinData = MyDatum . decodeUtf8 <$> fromBuiltinData

instance UnsafeFromData MyDatum where
  unsafeFromBuiltinData = MyDatum . decodeUtf8 . unsafeFromBuiltinData

Note: I had a quick look at the implementation of the builtin encodeUtf8, this might not be what you expect (it seems to be currently ASCII encoding and truncating any code points outside of the 8bit range).


text:
Prefund wallets for PAB
How does one prefund wallets for PAB (Plutus Application Backend)?
I do not want to introduce minting code just for this purpose.


text:
Test for logError in Trace monad
How do I write a Tasty unit-test for an error that may be logged from inside the Trace monad?
import Control.Monad.Freer.Extras (logError, throwError)

trace1 :: Input -> Trace.EmulatorTrace ()
trace1 x =
    case fromInput x of
        Left e ->
            logError @String $ unpack e -- ###########

        Right d -> do
            h1 <- Trace.activateContractWallet (Wallet 1) endpoints
            -- ...


text:
Can a function be passed in as an endpoint argument?
Can a function be passed in as an endpoint argument?
IOW,how can I instantiate a function for FromJSON?


text:
What is achieved by invoking endpoint for wallet in the emulator?
As per entire code below, give always mandates that Wallet 2 be given:
thePkh :: PubKeyHash
thePkh = pubKeyHash $ walletPubKey $ Wallet 2

theVal :: Value
theVal = ADA.toValue (ADA.Lovelace 3_000_000)

give :: Contract () PaySchema Text ()
give = do
    let param = PayParam thePkh theVal
    let tx = mustPayToTheScript () theVal
    ledgerTx <- submitTxConstraints (typedValidator param) tx

So why must I also invoke the grab endpoint for Wallet 2 (trace12)? What changes if instead it's invoked for Wallet 3 (trace13)?
trace12 #######################################
...
Final balances
Wallet 1:
    {, ""}: 96999990
Wallet 2:
    {, ""}: 102996448
Wallet 3:
    {, ""}: 100000000
Wallet 4:
    {, ""}: 100000000
Wallet 5:
    {, ""}: 100000000
Wallet 6:
    {, ""}: 100000000
Wallet 7:
    {, ""}: 100000000
Wallet 8:
    {, ""}: 100000000
Wallet 9:
    {, ""}: 100000000
Wallet 10:
    {, ""}: 100000000

Note that if Wallet 3 instead is invoked for grab, then the result is different:
trace13 #######################################
...
Final balances
Wallet 1:
    {, ""}: 96999990
Wallet 2:
    {, ""}: 100000000
Wallet 3:
    {, ""}: 100000000
Wallet 4:
    {, ""}: 100000000
Wallet 5:
    {, ""}: 100000000
Wallet 6:
    {, ""}: 100000000
Wallet 7:
    {, ""}: 100000000
Wallet 8:
    {, ""}: 100000000
Wallet 9:
    {, ""}: 100000000
Wallet 10:
    {, ""}: 100000000
Script 3f3c25dfdfad56d6f08d6d3e8bec53ab14d1950be944bc0ed26957c6:
    {, ""}: 3000000

Why is that? And what does it mean to invoke an endpoint for a wallet altogether?
{-# LANGUAGE DataKinds                  #-}
{-# LANGUAGE DeriveAnyClass             #-}
{-# LANGUAGE DeriveGeneric              #-}
{-# LANGUAGE FlexibleContexts           #-}
{-# LANGUAGE NoImplicitPrelude          #-}
{-# LANGUAGE OverloadedStrings          #-}
{-# LANGUAGE ScopedTypeVariables        #-}
{-# LANGUAGE TemplateHaskell            #-}
{-# LANGUAGE TypeApplications           #-}
{-# LANGUAGE TypeFamilies               #-}
{-# LANGUAGE TypeOperators              #-}
{-# LANGUAGE MultiParamTypeClasses      #-}
{-# LANGUAGE DerivingStrategies         #-}
{-# LANGUAGE NumericUnderscores         #-}
{-# LANGUAGE TupleSections              #-}
{-# OPTIONS_GHC -fno-warn-unused-imports #-}

module ASK (trace12, trace13 ) where
import           Control.Monad        hiding (fmap)
import           Data.Map            as Map
import           Data.Monoid               as Mnd ( (<>), Monoid(mconcat) )
import           Data.Text            (Text, unpack)
import           Data.Void            (Void)
import           GHC.Generics         (Generic)
import qualified Prelude              as H--askell

import           Plutus.Contract
import qualified Plutus.Trace.Emulator as Emu
import           PlutusTx             (Data (..))
import qualified PlutusTx
import           PlutusTx.Prelude     hiding (Semigroup(..), unless)
import           Ledger               hiding (singleton)
import           Ledger.Constraints   as Constraints
import qualified Ledger.Typed.Scripts as Scripts
import           Ledger.Value         (Value(Value), geq)
import           Wallet.Emulator.Wallet  (Wallet(Wallet), walletPubKey)
import qualified Plutus.V1.Ledger.Ada as ADA
import qualified Control.Monad.Freer.Extras as Extras

data PayParam = PayParam
    { _pkh :: PubKeyHash
    , _val :: Value
    } deriving H.Show

PlutusTx.makeLift ''PayParam

{-# INLINABLE mkValidator #-}
mkValidator :: PayParam -> () -> () -> ScriptContext -> Bool
mkValidator param () () ctx =
    traceIfFalse "beneficiary's signature missing" signedByBeneficiary
        where
            info :: TxInfo
            info = scriptContextTxInfo ctx

            signedByBeneficiary :: Bool
            signedByBeneficiary = txSignedBy info $ _pkh param

data Lock
instance Scripts.ValidatorTypes Lock where
    type instance DatumType Lock = ()
    type instance RedeemerType Lock = ()

typedValidator :: PayParam -> Scripts.TypedValidator Lock
typedValidator param = Scripts.mkTypedValidator @Lock
    ($$(PlutusTx.compile [|| mkValidator ||]) `PlutusTx.applyCode` PlutusTx.liftCode param)
    $$(PlutusTx.compile [|| wrap ||])
  where
    wrap = Scripts.wrapValidator @() @()

{-# INLINABLE validator #-}
validator :: PayParam -> Validator
validator = Scripts.validatorScript . typedValidator

{-# INLINABLE valHash #-}
valHash :: PayParam -> Ledger.ValidatorHash
valHash = Scripts.validatorHash . typedValidator

{-# INLINABLE scrAddress #-}
scrAddress :: PayParam -> Ledger.Address
scrAddress = scriptAddress  . validator

--------------------------

{-# INLINABLE thePkh #-}
thePkh :: PubKeyHash
thePkh = pubKeyHash $ walletPubKey $ Wallet 2

{-# INLINABLE theVal #-}
theVal :: Value
theVal = ADA.toValue (ADA.Lovelace 3_000_000)

give :: Contract () PaySchema Text ()
give = do
    let param = PayParam thePkh theVal

    let tx = mustPayToTheScript () theVal
    ledgerTx <- submitTxConstraints (typedValidator param) tx

    -- also works fine
    -- let tx = mustPayToOtherScript (valHash param) unitDatum theVal
    -- ledgerTx <- submitTx tx

    void $ awaitTxConfirmed $ txId ledgerTx
    logInfo @H.String "\ngive"

grab :: Contract () PaySchema Text ()
grab = do
    let param = PayParam thePkh theVal

    utxos <- utxoAt $ scrAddress param
    let lookups = Constraints.unspentOutputs utxos <>
                  Constraints.otherScript (validator param) <>
                  Constraints.typedValidatorLookups (typedValidator param)

    let orefs = fst <$> Map.toList utxos

    let tx :: TxConstraints () ()
        tx = PlutusTx.Prelude.mconcat [mustSpendScriptOutput oref unitRedeemer | oref <- orefs]

    ledgerTx <- submitTxConstraintsWith @Lock lookups tx
    awaitTxConfirmed $ txId ledgerTx
    logInfo @H.String "\ngrab"

type PaySchema =
    Endpoint "give" ()
        .\/
    Endpoint "grab" ()

endpoints :: Contract () PaySchema Text ()
endpoints =
    forever
        $ handleError logError
        $ awaitPromise
        $ give' `select` grab'
            where
                give' = endpoint @"give" $ const give
                grab' = endpoint @"grab" $ const grab

trace12 :: H.IO ()
trace12 = Emu.runEmulatorTraceIO $ do
    h1 <- Emu.activateContractWallet (Wallet 1) endpoints
    h2 <- Emu.activateContractWallet (Wallet 2) endpoints
    void $ Emu.waitNSlots 5
    Emu.callEndpoint @"give" h1 ()
    void $ Emu.waitUntilSlot 10
    Emu.callEndpoint @"grab" h2 ()
    void $ Emu.waitUntilSlot 15

trace13 :: H.IO ()
trace13 = Emu.runEmulatorTraceIO $ do
    h1 <- Emu.activateContractWallet (Wallet 1) endpoints
    h3 <- Emu.activateContractWallet (Wallet 3) endpoints
    void $ Emu.waitNSlots 5
    Emu.callEndpoint @"give" h1 ()
    void $ Emu.waitUntilSlot 10
    Emu.callEndpoint @"grab" h3 ()
    void $ Emu.waitUntilSlot 15

plutus commit: plutus-starter-devcontainer/v1.0.7

So why must I also invoke the grab endpoint for Wallet 2 (trace12)? What
changes if instead it's invoked for Wallet 3 (trace13)?

You must invoke it in order to receive funds that are locked in the contract (via give endpoint).
If you invoke grab endpoint on Wallet3, you would no receive anything from the script, because wallet3 is not beneficiary of this vesting contract. You can see that in the logs you posted for trace12 where wallet2 has more ada than in the beginning (102996448) and for trace13 where wallet3 has default initial amount of ADA 100000000, but there are funds locked on Vesting script

Script 3f3c25dfdfad56d6f08d6d3e8bec53ab14d1950be944bc0ed26957c6:
{, ""}: 3000000

which can only be unlocked/claimed (grab-ed) by wallet2 who is beneficiary of contract (defined as param thePkh in give endpoint)

Why is that? And what does it mean to invoke an endpoint for a wallet altogether?

I've explained why above. And for what does it mean to invoke endpoint for a wallet. It just means that you call that contract's offchain endpoint, which creates transaction for that contract/script with specific params and constraints, signed with that wallet's private key.


text:
Plutus Auction use-case
Regarding plutus-apps Auction use-case plutus-use-cases/src/Plutus/Contracts/Auction.hs , both auctionSeller and auctionBuyer need to specify the same exact params, or else each buyer could change the auction deadline!  What exactly stops the buyer contract from doing so?

In a way, you are (but aren't) correct since auctionSeller and auctionBuyer could be used to arbitrarily declare params. However, these functions don't run on-chain, they are client-side code for preparing the structure to be submitted for placing a bid.
The on-chain validation is in the "auctionTransition" function which accepts the bid, or payout. Both these inputs don't even accept a deadline or token type value so it isn't possible for them to change the state in that way. Otherwise, the token and deadline are immutable, so they cannot be changed.

Well as you said it is off-chain. If you feed it incorrect information, all you do is allow yourself to build an order which will be denied by the on-chain component, or disallow yourself from building otherwise correct information.

Welcome to Cardano SE! As a new user be sure to take the [Tour].


text:
PPP Cohort 3 Lecture 1 (English Auction): Why does the buyer get the `minLovelace` (2 ADA) in the end even though the seller payed it initially?
In my example (same as in the lecture) the wallet 1 starts the auction and wallet 3 wins it.
As the contract always has to have some ADA as Lars explains it looks like Wallet 1 pays 2 ADA to the contract in slot 1 to satisfy this rule as it has 2 ADA less (minus fees) in the UTxO. See:

But in the end Wallet 3 who wins the auction gets this 2 ADA.
I guess those 2 ADA have to be there to cover some fees in some special cases.
But why does Wallet 3 and not Wallet 1 gets the 2 ADA in the end?

Due to my low rep score, I cannot comment in Mitchell Turner's answer, so I answer here instead :)
As Mitchell said, all UTxOs must have the minLovelace amount of ADA attached to it. I just want to add a couple points to it

The amount of minLovelace (in the EnglishAuction) is hardcoded by Lars to 2 ADA - https://github.com/input-output-hk/plutus-pioneer-program/blob/main/code/week01/src/Week01/EnglishAuction.hs#L54

When Wallet1 closes the Auction, token T is sent to Wallet3 -> so the 2 ADA stored alongside token T is send to Wallet3 as well (See this https://github.com/input-output-hk/plutus-pioneer-program/blob/main/code/week01/src/Week01/EnglishAuction.hs#L323)

This min-ada-value requirement will set size bound to both max number of UTxO and max UTxO size. Main reason is: A ledger without a size bound is vulnerable to being populated by so much data that users will unable to process it (or run a node) with machines meeting the recommended specifications for running a node.

min-ada-value is adjusted and calculated values depending on size of UTxO (note: 1 UTxO can contains multiple different types of Tokens including ADA)

You can see this for more information https://docs.cardano.org/native-tokens/minimum-ada-value-requirement

If the address is not spendable by the user sending the tokens, the ada sent alongside the tokens no longer belongs to the sender

Before transferring custom tokens, users may choose to use off-chain communication to negotiate who supplies the ada to cover the min-ada-value in the output made by the transferring transaction

As the contract always has to have some ADA

All UTxOs must have the minLovelace amount of ADA attached to it. That includes UTxOs at script addresses and in wallets. A transaction couldn't output the T token to Wallet 3 without including the minLovelace ADA (both are included in the same UTxO).
This is so bad actors don't just mint tons of new UTxOs and bloat the network. There is a maximum number of UTxOs that can exists since ADA is capped.

Isn't that what fees are for?

Fees are to pay the network for validating your transaction.

Oh, you mean to prevent bloating of the chain? Fees are great to prevent spamming the network, but it's not sufficient to prevent someone from doing permanent damage to the chain. Every time someone spins up a new node, they need to validate every transaction in the history of the chain. Without a minLovelace amount, someone could  mint 1,000,000,000 tokens, each with their own output. That would take up a lot of storage on the node machine. Sure, that would be an expensive transaction, but it would permanently bloat the chain. minLovelace protects against that attack vector.

I understand that fees are also for paying the platform. But I don't understand why it needs fees and the additional mechanism you mention to prevent that someone spams the network. I thought it is rather a collateral. If someone forces to send an invalid transaction then this collateral would be used. See https://docs.cardano.org/plutus/collateral-mechanism

The minLovelace mechanism isn't the collateral. That is, again, separate. The collateral is related to transaction validation on Cardano being deterministic, which is awesome, but requires the safety measures mentioned in the link you included.


text:
I want to mint an NFT using a JSON file using plu-ts, but I dont know how and where to start
I want to mint an NFT using a JSON file using plu-ts, but I don't know how and where to start.
Do I need to create a Node? OR Do I need to write it in Haskel? I have read and performed everything from the official documentation of the plu-ts but it has been confusing for me. If anyone can help me out here I'll be very thankful. Even a video would help.

plu-ts maintainer here, really happy to see you are using the tool!
If I understand correctly you are trying to mint an NFT using a native script, and you are trying to construct the transaction with the offchain part of plu-ts
I see this post is 5 months old, and the tool has evolved a lot since then, and with it the documentation.
I'll leave here the link to the latest docs for convenience.
to include a minting script in the transaction (independently if it is plutus or native script) you can specify it in the mint property of buildSync
you can see it expects a script, in your case a native script.
you can construct a Script instance specifying it is a "NativeScript", followed by your json source; here is an example
const myNativeScript = new Script(
    "NativeScript",
    {
        type: "before",
        slot: 10_000_00
    }
);

if you still have issues I encourage you to join the Harmonic Labs discord server, where me or other fellow developers will be happy to help you out

Really appreciate your reply. I'll give it a try

Why plutus? It sounds like a native script is perfect for your use case. https://developers.cardano.org/docs/native-tokens/minting/


text:
Is posible to do Batch minting of NFT with each NFT having different image?
Since the metadata is attached to a Tx not to the NFT, and is unique per transaction, there can not be such a thing as a Batch minting of NFT with each one having different metadata for example "image", is it?
I need to mint like 10 000ks NFTs, so i think my NFTs will all share same,  image, and all i can change is the name and policy for doing them unique NFTs. Am I right?
EDIT: In fact it is not possible even that they satisfy  the 721-Standar https://cips.cardano.org/cips/cip25/, is it?

Yes, it's possible. You can mint multiple NFTs using different metadata, all this in the same transaction. Here is an example of how you should structure your metadata
Take a look on this: How to mint multiple NFT assets in the same transaction?
But you have the restriction of the max transaction size, you can't go over that limit. Depending of your metadata, you'll be able to mint 35-45 NFTs in the same transaction.

Will this structure of metadata show specifically for every asset the image in the web wallets?

Yes, because the image displayed is based on the token name and the token name is defined in your metadata.


text:
How to generate the address of a plutus script using Cardano Serialization Lib?
I am sending some smart contracts using the Cardano Serialization Lib and the nami wallet for signing, everything works fine, but I am not able to get the script address of a Plutus Script. I have managed it out  using cardano-cli command 'address build'. But I think there most be some equivalent in Cardano Serialization Lib, is it posible? I tried with the method Address.from_bytes() using the hex-decoded CBOR from the plutus script but it says it is not the right kind of CBOR.

Here is a javascript snippet that uses the cardano-serialization-lib to go from CBORHex to addr_test...
const {
  ScriptHash,
  NetworkInfo,
  EnterpriseAddress,
  StakeCredential
} = require("@emurgo/cardano-serialization-lib-nodejs")

...

const addrFromHash = (hash) => {
  const scripthash = ScriptHash.from_bytes(Buffer.from(hash,"hex"));
  const cred = StakeCredential.from_scripthash(scripthash);
  const networkId = NetworkInfo.testnet().network_id();
  const baseAddr = EnterpriseAddress.new(networkId, cred);
  const addr = baseAddr.to_address();
  const addrBech32 = addr.to_bech32();
  return addrBech32;
}

Plutus-Core script bytes are wrapped twice in a CBOR bytearray.
Use the following steps to calculate the script address:

unwrap one layer of CBOR
prepend a byte representing the PlutusScript version: 0x01 for PlutusScriptV1, 0x02 for PlutusScriptV2
calculate the 28-byte (224-bit) blake2b digest to get the payment part of the address
form the full script address using CIP19 (so for script addresses without a staking part simply prepend 0x70 to the digest)
encode the script address bytes using bech32 ("addr_test" prefix for testnet, "addr" prefix for mainnet)

The pseudo code of these steps would look as follows:
encodeBech32("addr_test", prepend(hashBlake2b224(prepend(unwrapCborBytes(hexToBytes(cborHex)), 0x01)), 0x70))

As an example consider the commonly used AlwaysSucceeds script. It has the following hexadecimal representation: "4e4d01000033222220051200120011".

Unwrapping one layer of CBOR bytearray would give: "4d01000033222220051200120011".
Prepend 0x01: "014d01000033222220051200120011"
Blake2b 28-byte digest: "67f33146617a5e61936081db3b2117cbf59bd2123748f58ac9678656"
Prepend 0x70: "7067f33146617a5e61936081db3b2117cbf59bd2123748f58ac9678656"
Bech32 encoding of testnet address: "addr_test1wpnlxv2xv9a9ucvnvzqakwepzl9ltx7jzgm53av2e9ncv4sysemm8"

Don't ask me why Plutus-Core scripts are wrapped twice in CBOR, and then unwrapped once to calculate the address. Some smart guys somewhere must have a good reason.
If you'd like to do these calculations in Javascript without some complicated Rust/Haskell dependencies check out the Helios Lang library. The library is UNLICENSEd so you can copy the relevant functionality as you please.

Script addresses are basically just addresses that uses the key hash instead of payment key hash, see the CIP19: Cardano Addresses.
However, the cardano-serialization-lib does not support fee estimation for these, but Alessandro from Nami has a patch for that.


text:
Is Camel Case notation required for the Asset Name of an NFT?
Hello i just have noticed that i can mint NFTs with the Cardano serialization Lib with out using Camel Case notation: I can have string spaces as well a special characters.
I have read in the CIP-25 nothing that does not let me do that
https://cips.cardano.org/cips/cip25/
But using Cardano-Cli I see it is not posible. Anybody knows anything about it?

Any limitations are artificial limitations in conversion. On the blockchain it's all hex and current master branch of node the CLI expects all inputs to be hex which should remove the limitation entirely.

I aks because i minted some NFTs  and CardanoScan does not show me the human readable Name


text:
How to mint a NFT with a policy of Multiple key-hash with Nami Wallet and Cardano Serialization Lib
I am building a daap and i want the user to be able to mint their app-tokens but the policy of the token must include the signature of the app wallet as well, for this I did the policy with the following code: where appKeyHash and clientKeyHash are the respective hashes for client and app addresses
const nativeScripts = Loader.Cardano.NativeScripts.new();
  const script = Loader.Cardano.ScriptPubkey.new(clientKeyHash);
  const nativeScript = Loader.Cardano.NativeScript.new_script_pubkey(script);
  const appScript = Loader.Cardano.ScriptPubkey.new(appKeyHash);
  const appNativeScript =
    Loader.Cardano.NativeScript.new_script_pubkey(appScript);

  const lockScript = Loader.Cardano.NativeScript.new_timelock_expiry(
    Loader.Cardano.TimelockExpiry.new(ttl)
  );
  nativeScripts.add(nativeScript);
  nativeScripts.add(appNativeScript);
  nativeScripts.add(lockScript);

  const finalScript = Loader.Cardano.NativeScript.new_script_all(
    Loader.Cardano.ScriptAll.new(nativeScripts)
  );
  const policyId = Buffer.from(
    Loader.Cardano.ScriptHash.from_bytes(
      finalScript.hash().to_bytes()
    ).to_bytes(),
    "hex"
  ).toString("hex");

Then I do all the transaction fee calculation and use Nami wallet to partial-sign the Tx (in the client side). Then I send to my backend the partial-signed transaction, and I add one vkeywitness using the private key of the app and Cardano-Serialization-Lib with the following code:
 const tx = CardanoWasm.Transaction.from_bytes(Buffer.from(txString, "hex"));
const body = tx.body();
const txHash = CardanoWasm.hash_transaction(body);
const txWitnesses = tx.witness_set();
const txVkeys = txWitnesses.vkeys();
const txScripts = txWitnesses.native_scripts();

const addWitnesses = CardanoWasm.TransactionWitnessSet.new();
const vkeyWitnesses = CardanoWasm.Vkeywitnesses.new();

const vkeyWitness = CardanoWasm.make_vkey_witness(txHash, prvKey);
vkeyWitnesses.add(vkeyWitness);
addWitnesses.set_vkeys(vkeyWitnesses);
const addVkeys = addWitnesses.vkeys();
const addScripts = addWitnesses.native_scripts();

const totalVkeys = CardanoWasm.Vkeywitnesses.new();
const totalScripts = CardanoWasm.NativeScripts.new();
if (txVkeys) {
  for (let i = 0; i < txVkeys.len(); i++) {
    totalVkeys.add(txVkeys.get(i));
  }
}
if (txScripts) {
  for (let i = 0; i < txScripts.len(); i++) {
    totalScripts.add(txScripts.get(i));
  }
}
if (addVkeys) {
  for (let i = 0; i < addVkeys.len(); i++) {
    totalVkeys.add(addVkeys.get(i));
  }
}
if (addScripts) {
  for (let i = 0; i < addScripts.len(); i++) {
    totalScripts.add(addScripts.get(i));
  }
}
const totalWitnesses = CardanoWasm.TransactionWitnessSet.new();
totalWitnesses.set_vkeys(totalVkeys);
totalWitnesses.set_native_scripts(totalScripts);
const signedTx = CardanoWasm.Transaction.new(
  tx.body(),
  totalWitnesses,
  tx.auxiliary_data()
);

Where tx is the hex-CBOR transaction i get from my front end (with the front-end witnessvkey already attached)
But when i try to send it i get the following error :
"transaction submit error ShelleyTxValidationError ShelleyBasedEraAlonzo (ApplyTxError [UtxowFailure (WrappedShelleyEraFailure (ScriptWitnessNotValidatingUTXOW (fromList [ScriptHash \"afae51e0836484a4196a3ef11018ab78990008df6459e70f7db6cfb4\"]))),UtxowFailure (WrappedShelleyEraFailure (UtxoFailure (FeeTooSmallUTxO (Coin 187325) (Coin 187193))))])"

The first error its because i am not correctly validating the transaction, the seccond is because the fees go up a little because I added one extra signature. I am not worried about the seccond error, what i do not underestand is
why is happening the first error:
WrappedShelleyEraFailure (ScriptWitnessNotValidatingUTXOW (fromList [ScriptHash \"afae51e0836484a4196a3ef11018ab78990008df6459e70f7db6cfb4\"])))

Even if i signed the Tx with the correponding privakekeys ?

Can you share the body of minting nft. I am also facing this issue. I have done from the cardano-cli but i want to make it within react project and want to use nami wallet for minting that user can do from his wallet. If its possible or you can help in this?

After days of searching I finally found my mistake: I was tryng to do the signing from backend, so I needed to generate the prvKey for this I followed the instructions provided in Cardano Serialization Lib, my code was
const Bip32PrivateKey =
  "xprv1wrgj3q60pxt5uq094h6f9nj00jx4hrwddgqrnv632a86llc94egpkn77l9mg9ewham96309yj6yv4zdsdr05flv6xsntjgcgj3pfp59ef589a87gen99t4ru5jhnfm4ar0tvlry4guz6l95tnjcjtnf4jv3rf52k";
const prvKeyBip32 = CardanoWasm.Bip32PrivateKey.from_bech32(Bip32PrivateKey);

function harden(num) {
  return 0x80000000 + num;
}

const rootKey = CardanoWasm.Bip32PrivateKey.from_bech32(Bip32PrivateKey);
const accountKey = rootKey
  .derive(harden(1852)) // purpose
  .derive(harden(1815)) // coin type
  .derive(harden(0)); // account #0

const utxoPubKey = accountKey
  .derive(0) // external
  .derive(0)
  .to_public();

const stakeKey = accountKey
  .derive(2) // chimeric
  .derive(0)
  .to_public();

const baseAddr = CardanoWasm.BaseAddress.new(
  CardanoWasm.NetworkInfo.testnet().network_id(),
  CardanoWasm.StakeCredential.from_keyhash(utxoPubKey.to_raw_key().hash()),
  CardanoWasm.StakeCredential.from_keyhash(stakeKey.to_raw_key().hash())
);

const prvKey = rootKey.to_raw_key();

And I was trying to sign with prvKey, for a UTXO in baseAddr, that did not work, but if O do
const prvKey = accountKey
  .derive(0)
  .derive(0)
  .to_raw_key();

Then I can sign and submit the tx for UTXOs in the baseAddr.

There seems to be a bug on @emurgo/cardano-serialization-lib end related to the issue that you are facing, submitted here

Thank  you andy! but i am afraid that that bug seems to be related with the fees and not with the signing. I tried to find the issue in my code, running a simpler Tx and sending using Blockfrost. but that did not for the same issue, so i think i am doing something wrong in the signing. Could  you please share the code that you use to sign? In the reported bug you show above  the only issue is the fees, so validation is working fine! Or maybe the fact that I am signing with a private key i got from my 24 words recovery phrase.

There might be an issue with the policy id generated in your first code block.
The hash function on NativeScript should take a namespace parameter (see here https://github.com/Emurgo/cardano-serialization-lib/blob/3e5dc377829d1ba46348713196b35476d8604bd9/rust/pkg/cardano_serialization_lib.js.flow#L2699),
that is prepended when calculating the hash (see here https://github.com/Emurgo/cardano-serialization-lib/blob/da6eba20a5ffab2eeae1b1823c26ee67b1426f42/rust/src/lib.rs#L1629)
Try adding the zero like this:
const nativeScript = CardanoWasm.NativeScript.new_script_all(CardanoWasm.ScriptAll.new(nativeScripts))

const policyId = Buffer.from(nativeScript.hash(0).to_bytes()).toString('hex');

instead of this part:
const finalScript = Loader.Cardano.NativeScript.new_script_all(
  Loader.Cardano.ScriptAll.new(nativeScripts)
);
const policyId = Buffer.from(
  Loader.Cardano.ScriptHash.from_bytes(
    finalScript.hash().to_bytes()
  ).to_bytes(),
  "hex"
).toString("hex");

No I dont think so. If I quit one address and left only one and sign with nami ot works.. the problem is related to the signing off-line with cardano serialization lib... I can not do it ! I tried with a simpler tx and is giving me the same error

Hm then maybe the error might not be in the code posted here, but in-between, where you 1) create the transaction in the frontend, 2) cbor / hex encode it for sending to the backend and then 3) decode the payload there.
Maybe you could just verify the whole thing works by testing it only in the frontend first incl. the cbor + hex encoding / decoding etc.
Maybe something like this:

const signedTx = CardanoWasm.Transaction.new(...); const txhex = toHex(cbor.encode(signedTx.to_bytes())); const payload = { txhex }; // -> This payload would be sent to the backend, but now test in frontend const hexDecode = cbor.decode(fromHex(payload.txhex)); const txFromBytes = CardanoWasm.Transaction.from_bytes(hexDecode); let witnessSet = txFromBytes.witness_set(); let witnesses = ws.vkeys(); witnesses.add(scriptWitness); witnessSet.set_vkeys(witnesses); witnessSet.set_native_scripts(nativeScripts); // ...

This is not a particularly trivial task, as we faced it today! I can't tell exactly what is off about your code, but it's possibly something very minor. I've noticed that the JS -> WASM handover can cause some weird type confusion for example if you pass a TimelockExpiry object into txBuilder.set_ttl it will actually set it to 0. It's very easy to make mistakes!
I can however offer an example that we tested and is working, based off some existing code we had as well as andycandy's example on the Github Issue. You can find the Gist here (hopefully it will help you figure out what is wrong with your code!):
https://gist.github.com/lovalabs/83d08796ab9ff65cbf188fbca8d03343
Note that we're in the process of releasing a minting SDK for cardano-serialization-lib that will be wrap around these low-level details and make minting assets much easier. Since the version of csl this is based off is still in beta, we're waiting for it to be stable before releasing.
EDIT:
After some further testing I've discovered that there may be a bug in the TransactionBuilder implementation of build() vs build_tx() which could be the reason for your error. When I do this:
const tx = txBuilder.build_tx()

I don't get a ScriptWitnessNotValidatingUTXOW error. But if I do this:
const txBody = txBuilder.build()
const tx = S.Transaction.new(
        txBody,
        txWitnessSet,
        auxiliaryData
)

Then I do get a ScriptWitnessNotValidatingUTXOW error. Will investigate further before raising an issue on Github though perhaps you could confirm this.

Thank you so much i dont see the method txBuilder.build_tx(), i think as you said the bug could be there... What version are you using?

I got to see that i added the vkey correctly ...  but it does not match with the one in the transaction that i sent. I change all my code to only do a simple transaction. and yet i cant do it. I do not know what is the problem


text:
Meaning of Index of Redeemer in Serialization Lib 10.4
What is the meaning of the index in the redeemer ?
redeemer = [ tag: redeemer_tag, index: uint, data: plutus_data, ex_units: ex_units

for context see:
https://github.com/input-output-hk/cardano-ledger/blob/master/eras/alonzo/test-suite/cddl-files/alonzo.cddl
I think in Serialization version 9 it used to be the index of the inputs. There was even a method for getting the index of the input in the class Transaction Builder. But now in 10.4 this method is not longer available and in fact for the experiments i have done so far the index of the redeemer needed for the transaction to be validated by the node seems not to be the same as the index of the input in the transaction, so I have not a method for computing the index that i should attach to the redeemer.

did you figure this out .?

Yes, order them by alphanumeric... Y Not by the order they are added

I was digging in this topic because I struggled with some transactions. I was reading the CDLL, the serialization lib, docs, etc.. but I couldn't find anything about the meaning of this index.
After some research in the cardano node source code, I found that the index is referred to the TxIn but those must be ordered alphabetical.
Here is some code from the cardano-node:
    scriptWitnessesTxIns
      :: [(TxIn, BuildTxWith BuildTx (Witness WitCtxTxIn era))]
      -> [(ScriptWitnessIndex, AnyScriptWitness era)]
    scriptWitnessesTxIns txins =
        [ (ScriptWitnessIndexTxIn ix, AnyScriptWitness witness)
          -- The tx ins are indexed in the map order by txid
        | (ix, (_, BuildTxWith (ScriptWitness _ witness)))
            <- zip [0..] (orderTxIns txins)
        ]

My problem was that I was using this index according to the add order with the add_plutus_script_input and add_input method.
I hope it helps.

What tool are you using to make the transactions?

I'm using the Cardano serialization lib and a own version of the cardano-js-sdk from IOHK


text:
What is the value of ADA locked in a Native token?
I was wondering, if ADA locked  in an native asset is equally valuable? For me it is like if somebody put a draw on a ticket but there are other implications:  it can give trouble when making transactions because it adds to the transactions size. Should we accept a payment of 500 ADA that have native assets be as valuable as one without Native Assets? Can we stake ADA along with native assets... or this locked value can not be staked?
EDIT: I mean min ADA needed for moving this ADA together with the native assets.
EDIT: For example you are asking for 500 ADA as payment for some work, but they send you 500 ADA with 200 NFT, if those NFT have not value in any marketplace, would this payment be equally valuable as a payment with only 500 ADA?

Are you referring to the minimum ADA value attached to each UTxO?

Yes I will update

ADA locked in an asset is equally valuable only insofar as you trust the underlying logic of the script address that keeps it locked. Assuming the smart contract is bulletproof, then yes - it is reasonable to say that a 500-ADA token is worth the same as 500 ADA.
Staking however is a bit more complicated. Currently, there is no way to stake anything other than raw ADA on L1. This does not mean that other tokens won't be stake-able in the future (see my answer here on the matter). Once new staking structures are set up on sidechains/hdyra heads, and eventually maybe even on L1, you'd be able to stake any token to any node willing to accept such a token as a form of stake.
On a different note, clever use of pointer addresses may make it possible to maintain staking rights over native-asset locked-values. For example, I could set up a script address that guards the 500 ADA with a pointer component that gives the receiver of the asset staking rights to the guarded ADA. Although, I'd imagine this could get cumbersome and difficult to trade.

What about if the locked asset has a undesirable IPFS hash... so every time you open your Wallet you see a disgusting image? like a ticket with a ugly message written in? also the Native Assets make cumbersome to make the transactions perse

Also every transaction that happens carring native assets is more vulnerable to get: outPut to Big error, as well as pay more fees, because the Tx Size is bigger. And makes harder to find any native asset needed in your Wallet, and if you have a big quantity of NFTs in a single UTXO, this UTXOs is harder to be used by the above remarks

Ada isn't locked in a native asset. The native asset requires an associated amount of ada held in a utxo at a minimum. In the case above of 500 Ada + 1 token, a transaction can be created with two outputs, one of 497 Ada and one of 2 ada with a fee of 1 Ada (high fee, using it for simplicity. In reality, it will be smaller). You can also combine assets from multiple utxos into a single one to have a smaller minutxo required to hold the assets to reclaim some of the Ada if someone sends you a token + 1.5 ada for exmaple.

" The native asset requires an associated amount of ADA held in a utxo at a minimum" that's what i mean with locked.