issues with BCMR support
Closed this issue · 14 comments
While adding BCMR support to my Cashtokens Webwallet I found a few issues and areas for improvement for the library. My project uses vanilla JS.
The previous issue #166 was handled very professionally with all issues resolved so thanks again for that!
-
BCMR.getTokenInfo(tokenId)
does not get the tokenInfo from the identities array as it should
(see example-bcmr - No option to add additional outputs to
wallet.tokenGenesis
this means no op_return info can be added to use authchain resolution and the authchain output can not be separately controlled. - hash256 (single?) needs to be exposed to hash the BCMR and add it to the opreturn
I have not tested BCMR.addMetadataRegistryAuthChain
yet
Also but unrelated to BCMR I found that
- wallet.getMaxAmountToSend()` does not work correctly for wallet with cashtokens
Hey Mathieu @mr-zwets
I have tested getMaxAmountToSend with an address with following utxos:
[
{
txid: '0decf61b7d493dbc0691c5db370f00fdc2df49bca6cfc855654cab75c4746a75',
vout: 0,
satoshis: 5000,
height: 0,
token: undefined
},
{
txid: '0decf61b7d493dbc0691c5db370f00fdc2df49bca6cfc855654cab75c4746a75',
vout: 1,
satoshis: 1000,
height: 0,
token: {
amount: 25,
tokenId: '4fabc9375983a8192d6316ebd8a2ed97efe41362c4cc0b25954858e5db95c755',
capability: undefined,
commitment: undefined
}
}
]
It reports BalanceResponse { bch: 0.0000478, sat: 4780, usd: 0 }
Which is perfectly reasonable number for me. It will not take into account any token utxos and their satoshi value.
hash256 (single?) needs to be exposed to hash the BCMR and add it to the opreturn
sha256
and Mainnet.sha256
are available and point to the same object. Use sha256.hash()
to hash anything. do binToHex()
to convert the result to hex string
Thanks for resolving the issues! I marked 3/4 as solved!
I tried testing it in the web wallet some more and getMaxAmountToSend does not work once there is any tokenUtxos
Please drop here a chipnet address on which I can test this
see for example bchtest:zzf5fexgnw59t70hm36fe6tkyuqck5pwdczmrq3m46
Create a new wallet, got 0.101 tbch from the chipnet faucet, created an NFT which brings the webwallet ballance to 10098165 satoshis.
Now I try send max with getMaxAmountToSend
and it gives 10098165 satoshis.
This results in the error:
Error: Amount required was not met, 10098667 satoshis needed, 10098526 satoshis available
.
So clearly the max amount to send is wrong.
Also ran into a problem constructing a correct BCMR opreturn output.
the format is OP_RETURN <'BCMR'> <hash> [<https_url>]
My current code is:
const bcmr = await reponse.json();
const hashContent = binToHex(Mainnet.sha256.hash(bcmr));
const chunks = ["BCMR", hashContent, url];
opreturnData = OpReturnData.fromArray(chunks);
But this interprets hashContent
as a UTF8 string instead of a hexadecimal.
So I'd like to know how to combine UTF8 strings and hexadecimals in one opreturn.
Or if i can just give the raw hex for the opreturn data is can use 0x6a0442434d52 + hashContent + hex(url)
Re: last question - binToHex produces you a hex string. So you get exactly what you instruct it to do. If you look at our tests you will see:
const contentHash_v1 = sha256
.hash(utf8ToBin(JSON.stringify(registry_v1, null, 2)))
.reverse();
...
let chunks = [
"BCMR",
contentHash_v1,
"https://mainnet.cash/.well-known/bitcoin-cash-metadata-registry_v1.json",
];
where contentHash_v1
is binary data 32 bytes long
Note that the hash is in reversed layout, as written in chip: encoded in OP_SHA256 byte order
https://github.com/bitjson/chip-bcmr#https-publication-outputs
Thank you!! this was super helpful! Had not taken a look at the code of the tests before.
Succeeded in making an onchain publication output for raw.githubusercontent.com/mr-zwets/example_bcmr/main/example_bcmr.json
https://chipnet.chaingraph.cash/tx/ddec4b40f4eccc239899092bdd1888a1f8cf0ad52585f56d71648d753acc9fea
However I also ran into an issue where if I wanted to include the https:// prefix and the opreturn data would get over 228 hexadecimal character in length i would get an error
Error: the transaction was rejected by network rules.
scriptpubkey (code 64)
so it seems there is some problem when the urls get too long?
- Note, that according to chip, your url should read something like
https://mr-zwets.com/.well-known/bitcoin-cash-metadata-registry.json
(which can be a redirect to your github hosted one)
const bcmr = await reponse.json();
const hashContent = binToHex(Mainnet.sha256.hash(bcmr));
This hashes the response object and not the text content of remote file. Either stringify your json object or use response.text()
My bad! I didn't understand why the stingify was necessary, going with response.text() instead of .json()!
Will look into the 'well known uri' standard, because I don't understand why this is mandatory...
made a publication output at token gensis on chipnet
https://chipnet.chaingraph.cash/tx/0090123ce181289927317ee6c209d66bf5934ed389f555da7715b46e843a24ed
However when I try
const authChain = await BCMR.addMetadataRegistryAuthChain({
transactionHash: "51094fb26daa7c9804cc7938716cd5b8d50d5c3df3a38c90d03931ce4e904e23",
followToHead: true
});
I get
Uncaught (in promise) TypeError: e is undefined
buildAuthChain https://cdn.mainnet.cash/mainnet-1.0.12.js:2
addMetadataRegistryAuthChain https://cdn.mainnet.cash/mainnet-1.0.12.js:2
Request for additional tokendata: for example in my wallet I'd like to display general info on tokens
for fungible tokens: how many were created in the genesis transaction and at what date
for NFTs: total supply, creation date & if a minting token still exists
fyi, you can easily fetch minting (or mutable) tokens by using chaingraph, here's an example query:
query {
output(
where: {
token_category: {
_eq: "\\xca66c43764e1b46fc00fd632a569d68654056e1eb8ce44c630760891921c53e4"
}
_or: [
{ nonfungible_token_capability: { _eq: "minting" } }
{ nonfungible_token_capability: { _eq: "mutable" } }
]
_not: { spent_by: {} }
transaction: {
block_inclusions: {
block: { accepted_by: { node: { name: { _eq: "bchn-chipnet" } } } }
}
}
}
) {
token_category
nonfungible_token_capability
spent_by {
transaction {
hash
}
}
locking_bytecode
output_index
transaction_hash
value_satoshis
}
}