stricahq / typhonjs Goto Github PK
View Code? Open in Web Editor NEWPure javascript Cardano wallet library
License: Apache License 2.0
Pure javascript Cardano wallet library
License: Apache License 2.0
What about GitHub actions for test, lint, build, and publish module?
https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs
Hello.
I am now developering cardano dApps.
And I implement the wallet integration on my app using wallets like typhon and eternl and nami.
But I found that typhon's getBalance api takes long time to fetch data compared to other wallets' api. (I mean Nami, and Eternl)
Is something wrong on my side?
It would be helpful to limit algorithm of UTXOs selection by maximum transaction size maxTxSize
to produce only valid transactions with many inputs.
Using cardano serilization lib , i get wallet balance like
const getBalance = async () => { const balance = await window.cardano.selectedWallet.getBalance(); const value = C.Value.from_bytes(fromHex(balance)); const lovelace = parseInt(value.coin().to_str()); return lovelace; };
I want to switching to typhonjs.
what's the right way to get Value.from_bytes in TyphonJs or a sample function to deserialise wallet balance? @ashisherc
import typhonJs from '@stricahq/typhonjs';
import bip32ed25519 from '@stricahq/bip32ed25519';
import { Encoder } from '@stricahq/cbors';
import { mnemonicToEntropy } from 'bip39';
import cip08 from '@stricahq/cip08';
import BigNumber from "bignumber.js";
const { Bip32PrivateKey } = bip32ed25519;
const { CoseSign1, createSigStructure } = cip08;
const protocolParams = {
minFeeA: new BigNumber(44),
minFeeB: new BigNumber(155381),
stakeKeyDeposit: new BigNumber(2000000),
lovelacePerUtxoWord: new BigNumber(34482),
collateralPercent: new BigNumber(150),
priceSteps: new BigNumber(0.0577),
priceMem: new BigNumber(0.0000721),
languageView: {
PlutusScriptV1: {
"sha2_256-memory-arguments": 4,
"equalsString-cpu-arguments-constant": 1000,
"cekDelayCost-exBudgetMemory": 100,
"lessThanEqualsByteString-cpu-arguments-intercept": 103599,
"divideInteger-memory-arguments-minimum": 1,
"appendByteString-cpu-arguments-slope": 621,
"blake2b-cpu-arguments-slope": 29175,
"iData-cpu-arguments": 150000,
"encodeUtf8-cpu-arguments-slope": 1000,
"unBData-cpu-arguments": 150000,
"multiplyInteger-cpu-arguments-intercept": 61516,
"cekConstCost-exBudgetMemory": 100,
"nullList-cpu-arguments": 150000,
"equalsString-cpu-arguments-intercept": 150000,
"trace-cpu-arguments": 150000,
"mkNilData-memory-arguments": 32,
"lengthOfByteString-cpu-arguments": 150000,
"cekBuiltinCost-exBudgetCPU": 29773,
"bData-cpu-arguments": 150000,
"subtractInteger-cpu-arguments-slope": 0,
"unIData-cpu-arguments": 150000,
"consByteString-memory-arguments-intercept": 0,
"divideInteger-memory-arguments-slope": 1,
"divideInteger-cpu-arguments-model-arguments-slope": 118,
"listData-cpu-arguments": 150000,
"headList-cpu-arguments": 150000,
"chooseData-memory-arguments": 32,
"equalsInteger-cpu-arguments-intercept": 136542,
"sha3_256-cpu-arguments-slope": 82363,
"sliceByteString-cpu-arguments-slope": 5000,
"unMapData-cpu-arguments": 150000,
"lessThanInteger-cpu-arguments-intercept": 179690,
"mkCons-cpu-arguments": 150000,
"appendString-memory-arguments-intercept": 0,
"modInteger-cpu-arguments-model-arguments-slope": 118,
"ifThenElse-cpu-arguments": 1,
"mkNilPairData-cpu-arguments": 150000,
"lessThanEqualsInteger-cpu-arguments-intercept": 145276,
"addInteger-memory-arguments-slope": 1,
"chooseList-memory-arguments": 32,
"constrData-memory-arguments": 32,
"decodeUtf8-cpu-arguments-intercept": 150000,
"equalsData-memory-arguments": 1,
"subtractInteger-memory-arguments-slope": 1,
"appendByteString-memory-arguments-intercept": 0,
"lengthOfByteString-memory-arguments": 4,
"headList-memory-arguments": 32,
"listData-memory-arguments": 32,
"consByteString-cpu-arguments-intercept": 150000,
"unIData-memory-arguments": 32,
"remainderInteger-memory-arguments-minimum": 1,
"bData-memory-arguments": 32,
"lessThanByteString-cpu-arguments-slope": 248,
"encodeUtf8-memory-arguments-intercept": 0,
"cekStartupCost-exBudgetCPU": 100,
"multiplyInteger-memory-arguments-intercept": 0,
"unListData-memory-arguments": 32,
"remainderInteger-cpu-arguments-model-arguments-slope": 118,
"cekVarCost-exBudgetCPU": 29773,
"remainderInteger-memory-arguments-slope": 1,
"cekForceCost-exBudgetCPU": 29773,
"sha2_256-cpu-arguments-slope": 29175,
"equalsInteger-memory-arguments": 1,
"indexByteString-memory-arguments": 1,
"addInteger-memory-arguments-intercept": 1,
"chooseUnit-cpu-arguments": 150000,
"sndPair-cpu-arguments": 150000,
"cekLamCost-exBudgetCPU": 29773,
"fstPair-cpu-arguments": 150000,
"quotientInteger-memory-arguments-minimum": 1,
"decodeUtf8-cpu-arguments-slope": 1000,
"lessThanInteger-memory-arguments": 1,
"lessThanEqualsInteger-cpu-arguments-slope": 1366,
"fstPair-memory-arguments": 32,
"modInteger-memory-arguments-intercept": 0,
"unConstrData-cpu-arguments": 150000,
"lessThanEqualsInteger-memory-arguments": 1,
"chooseUnit-memory-arguments": 32,
"sndPair-memory-arguments": 32,
"addInteger-cpu-arguments-intercept": 197209,
"decodeUtf8-memory-arguments-slope": 8,
"equalsData-cpu-arguments-intercept": 150000,
"mapData-cpu-arguments": 150000,
"mkPairData-cpu-arguments": 150000,
"quotientInteger-cpu-arguments-constant": 148000,
"consByteString-memory-arguments-slope": 1,
"cekVarCost-exBudgetMemory": 100,
"indexByteString-cpu-arguments": 150000,
"unListData-cpu-arguments": 150000,
"equalsInteger-cpu-arguments-slope": 1326,
"cekStartupCost-exBudgetMemory": 100,
"subtractInteger-cpu-arguments-intercept": 197209,
"divideInteger-cpu-arguments-model-arguments-intercept": 425507,
"divideInteger-memory-arguments-intercept": 0,
"cekForceCost-exBudgetMemory": 100,
"blake2b-cpu-arguments-intercept": 2477736,
"remainderInteger-cpu-arguments-constant": 148000,
"tailList-cpu-arguments": 150000,
"encodeUtf8-cpu-arguments-intercept": 150000,
"equalsString-cpu-arguments-slope": 1000,
"lessThanByteString-memory-arguments": 1,
"multiplyInteger-cpu-arguments-slope": 11218,
"appendByteString-cpu-arguments-intercept": 396231,
"lessThanEqualsByteString-cpu-arguments-slope": 248,
"modInteger-memory-arguments-slope": 1,
"addInteger-cpu-arguments-slope": 0,
"equalsData-cpu-arguments-slope": 10000,
"decodeUtf8-memory-arguments-intercept": 0,
"chooseList-cpu-arguments": 150000,
"constrData-cpu-arguments": 150000,
"equalsByteString-memory-arguments": 1,
"cekApplyCost-exBudgetCPU": 29773,
"quotientInteger-memory-arguments-slope": 1,
"verifySignature-cpu-arguments-intercept": 3345831,
"unMapData-memory-arguments": 32,
"mkCons-memory-arguments": 32,
"sliceByteString-memory-arguments-slope": 1,
"sha3_256-memory-arguments": 4,
"ifThenElse-memory-arguments": 1,
"mkNilPairData-memory-arguments": 32,
"equalsByteString-cpu-arguments-slope": 247,
"appendString-cpu-arguments-intercept": 150000,
"quotientInteger-cpu-arguments-model-arguments-slope": 118,
"cekApplyCost-exBudgetMemory": 100,
"equalsString-memory-arguments": 1,
"multiplyInteger-memory-arguments-slope": 1,
"cekBuiltinCost-exBudgetMemory": 100,
"remainderInteger-memory-arguments-intercept": 0,
"sha2_256-cpu-arguments-intercept": 2477736,
"remainderInteger-cpu-arguments-model-arguments-intercept": 425507,
"lessThanEqualsByteString-memory-arguments": 1,
"tailList-memory-arguments": 32,
"mkNilData-cpu-arguments": 150000,
"chooseData-cpu-arguments": 150000,
"unBData-memory-arguments": 32,
"blake2b-memory-arguments": 4,
"iData-memory-arguments": 32,
"nullList-memory-arguments": 32,
"cekDelayCost-exBudgetCPU": 29773,
"subtractInteger-memory-arguments-intercept": 1,
"lessThanByteString-cpu-arguments-intercept": 103599,
"consByteString-cpu-arguments-slope": 1000,
"appendByteString-memory-arguments-slope": 1,
"trace-memory-arguments": 32,
"divideInteger-cpu-arguments-constant": 148000,
"cekConstCost-exBudgetCPU": 29773,
"encodeUtf8-memory-arguments-slope": 8,
"quotientInteger-cpu-arguments-model-arguments-intercept": 425507,
"mapData-memory-arguments": 32,
"appendString-cpu-arguments-slope": 1000,
"modInteger-cpu-arguments-constant": 148000,
"verifySignature-cpu-arguments-slope": 1,
"unConstrData-memory-arguments": 32,
"quotientInteger-memory-arguments-intercept": 0,
"equalsByteString-cpu-arguments-constant": 150000,
"sliceByteString-memory-arguments-intercept": 0,
"mkPairData-memory-arguments": 32,
"equalsByteString-cpu-arguments-intercept": 112536,
"appendString-memory-arguments-slope": 1,
"lessThanInteger-cpu-arguments-slope": 497,
"modInteger-cpu-arguments-model-arguments-intercept": 425507,
"modInteger-memory-arguments-minimum": 1,
"sha3_256-cpu-arguments-intercept": 0,
"verifySignature-memory-arguments": 1,
"cekLamCost-exBudgetMemory": 100,
"sliceByteString-cpu-arguments-intercept": 150000
},
},
}
const words = 'squirrel razor tank unusual notable exhaust weird cherry cage rigid tattoo luggage filter bean pepper cream option cause media deputy cluster mixture exotic access';
const entropy = mnemonicToEntropy(words);
const rootKey = await Bip32PrivateKey.fromEntropy(Buffer.from(entropy, "hex"));
const HARDENED = 2147483648
const accountKey = rootKey
.derive(1852 + HARDENED) // purpose
.derive(1815 + HARDENED) // coin type
.derive(0 + HARDENED) // account index
.derive(0) // chain
.derive(0) // payment key index // Change this to generate other addresses
.toPrivateKey();
const stakeKey = rootKey
.derive(1852 + HARDENED) // purpose
.derive(1815 + HARDENED) // coin type
.derive(0 + HARDENED) // account index
.derive(2) // chain
.derive(0) // payment key index
.toPrivateKey();
const paymentCred0 = {
hash: accountKey.toPublicKey().hash().toString("hex"),
type: typhonJs.types.HashType.ADDRESS,
};
const paymentCred1 = {
hash: stakeKey.toPublicKey().hash().toString("hex"),
type: typhonJs.types.HashType.ADDRESS,
};
const payAddress = new typhonJs.address.BaseAddress(
typhonJs.types.NetworkId.MAINNET,
paymentCred0,
paymentCred1
);
// Got the info from koios api but it needed a few transformations so I hard-coded it here for simplicity's sake
const inputs = [
{
txId: 'aa6e3c206a746d54f01c1a5784af38c6ffde22d31df1cb1df23966a82caad6e7',
index: 0,
amount: new BigNumber(3000000),
tokens: [],
address: payAddress
},
{
txId: "2f4d55ff9676ebe3d5d1289d7abdede35e030a4eb5d553145f2cb8c7a24587b8",
index: 0,
amount: new BigNumber(5000000),
tokens: [],
address: payAddress
}
]
// Test wallet address on mainnet
const outputs = [
{
amount: new BigNumber(1200000),
address: typhonJs.utils.getAddressFromBech32('addr1qyfcdgkt8jzx58uncjhjrea5zl5xjhpuyygtpfzjqrsycaefmps0ynd4j00zed247hmtzdkhjqs6c9myph4dtcwuz3vsst3qjv'),
tokens: []
}
]
// Generate the payment transaction
const tx = new typhonJs.Transaction({ protocolParams }).paymentTransaction({
inputs: inputs,
outputs: outputs,
changeAddress: payAddress,
ttl: 700000
})
const txHash = tx.getTransactionHash();
const requiredSignatures = tx.getRequiredWitnesses();
// `accountPrivateKey` derive using @stricahq/bip32ed25519
for (const [, bipPath] of requiredSignatures) {
const privateKey = rootKey.derive(0).derive(0).toPrivateKey();
const witness = {
publicKey: privateKey.toPublicKey().toBytes(),
signature: privateKey.sign(txHash),
};
tx.addWitness(witness);
}
console.log(tx)
// THIS IS WHERE IT GETS MESSED UP I BELIEVE
let txCbor = Encoder.encode(tx).toString("hex")
const data = {
addressBuffer: Buffer.from(
paymentCred0.hash,
"hex"
),
publicKeyBuffer: Buffer.from(
payAddress.addressHex,
"hex"
),
signature: Buffer.from(txCbor, "hex"),
};
const protectedMap = new Map();
// Set protected headers as per CIP08
// Set Algorthm used by Cardano keys
protectedMap.set(1, -8);
// Set PublicKey
protectedMap.set(4, data.publicKeyBuffer);
// Set Address
protectedMap.set("address", data.addressBuffer);
const coseSign1Builder = new CoseSign1({
protectedMap,
unProtectedMap: new Map(),
payload: Buffer.from(""),
hashPayload: false,
});
const coseSign1 = coseSign1Builder.buildMessage(data.signature);
// console.log(txCbor)
console.log(coseSign1.toString("hex"))
// console.log(payAddress.addressBytes)
console.log(tx) outputs:
Transaction {
inputs: [
{
txId: 'aa6e3c206a746d54f01c1a5784af38c6ffde22d31df1cb1df23966a82caad6e7',
index: 0,
amount: [BigNumber],
tokens: [],
address: [BaseAddress]
}
],
outputs: [
{ amount: [BigNumber], address: [BaseAddress], tokens: [] },
{ address: [BaseAddress], amount: [BigNumber], tokens: [] }
],
certificates: [],
withdrawals: [],
requiredWitnesses: Map(1) {
'3b64f00fc61bc8abe86830e3a04b711d5aa322b9e7020240e087857e' => undefined
},
requiredNativeScriptWitnesses: Map(0) {},
fee: BigNumber { s: 1, e: 5, c: [ 168141 ] },
witnesses: [
{
publicKey: <Buffer 15 08 40 4d 21 9c 65 f5 34 f0 f9 69 c4 10 54 06 b4 73 5e 6a e4 da a3 69 4b 3c 20 72 b4 5d 94 46>,
signature: <Buffer 86 0b dd 3c 9b de ff 86 05 e1 0a 78 59 2d 8c 88 c9 1d c6 0b 81 ac 37 a0 f8 e3 47 96 af d8 03 19 1e 14 1c fe ec ab 94 4c b3 81 16 33 e1 d3 b2 cf 16 73 ... 14 more bytes>
}
],
plutusScriptMap: Map(0) {},
nativeScriptList: [],
collaterals: [],
requiredSigners: Map(0) {},
plutusDataList: [],
_isPlutusTransaction: false,
mints: [],
_protocolParams: {
minFeeA: BigNumber { s: 1, e: 1, c: [Array] },
minFeeB: BigNumber { s: 1, e: 5, c: [Array] },
stakeKeyDeposit: BigNumber { s: 1, e: 6, c: [Array] },
lovelacePerUtxoWord: BigNumber { s: 1, e: 4, c: [Array] },
collateralPercent: BigNumber { s: 1, e: 2, c: [Array] },
priceSteps: BigNumber { s: 1, e: -2, c: [Array] },
priceMem: BigNumber { s: 1, e: -5, c: [Array] },
languageView: { PlutusScriptV1: [Object] }
},
ttl: 700000
}
Hey, I'm trying to prepare a transaction to be able to send it to submit-api but I'm a bit lost in what I need to do at the end, could you point me in the right direction? (yes I know the seed is supposed to be hidden but I don't mind it)
Thank you
This structure is not accepted:
import { encode } from 'cborg';
import {utils} from "@strictahq/typhonjs"
const pkh = Buffer.from(await getPubKeyHash());
const pkhCBORed = Buffer.from(encode(pkh));
utils.createPlutusDataCbor({
"fields": [
{
"fields": [ pkhCBORed ],
"constructor": 0
}
],
"constructor": 0
})
or with the bytes tag and the CBOR as a string (as it is accepted in cardano-cli)
The idea behind is make library consumer to not depend on Bignumber.js itself. This may be done by accepting plain JS Numbers (or even strings) in protocol params values and UTXOs.
BigNumber(BigNumber()) = BigNumber
BigNumber(Number) = BigNumber
BigNumber(String) = BigNumber
This can be implemented by wrapping any value in a BigNumber
constructor inside a library.
Related:
const finalTx = {
"type": "Tx AlonzoEra",
"description": "",
"cborHex": txFinal.payload
}
const apiAddress = "https://cardano-mainnet.blockfrost.io/api/v0/tx/submit"
async function postTx() {
try {
const response = await axios.post(apiAddress, finalTx), {
headers: {
'Content-Type': 'application/cbor',
'project_id': 'myApiKey'
}
});
console.log(response);
} catch (error) {
console.error(error);
}
}
postTx()
If I save finalTx contents to tx.signed on cardano-node server, I can succesfully send it via cardano-cli, but sending it via HTTP/S requires me to transform it. I would like to not add another dependency so I was hoping you could share how to transform it using your packages? Tried a bunch of stuff before posting.
Thanks
Hi, what do you think about to accept hash as a Buffer in Credential
s (HashCredential
| ScriptCredential
) and not like a string
?
Current behaviour:
// utxoPubKey and stakeKey are from @stricahq/bip32ed25519
new BaseAddress(types.NetworkId.MAINNET, {
hash: utxoPubKey.toPublicKey().hash().toString('hex'),
type: types.HashType.ADDRESS,
}, {
hash: stakeKey.toPublicKey().hash().toString('hex'),
type: types.HashType.ADDRESS,
});
Preposed behaviour:
new BaseAddress(types.NetworkId.MAINNET, {
// without .toString('hex')
hash: utxoPubKey.toPublicKey().hash(),
type: types.HashType.ADDRESS,
}, {
hash: stakeKey.toPublicKey().hash(),
type: types.HashType.ADDRESS,
});
Since the Vasil HF, per the official docs:
the minUTxO formula is now calculated using original bytes instead of lovelacePerUTxOWord. For more details, see CIP-55.
As of typhonjs v1.2.7, the calculateMinUtxoAmount()
in utils
is still using the old formula. This now needs to be updated.
How the hexAddress address is generated?
Protocol parameter lovelacePerUtxoWord
should be coinsPerUtxoWord
according to graphql schema:
Hello,
Since you are working on the next major release, it would be very useful to migrate to native BigInt
from BigNumber
.
It is widely accepted https://caniuse.com/bigint
Many crypto libraries has been migrate to native BigInt
in past year.
error output:
BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.
If you want to include a polyfill, you need to:
- add a fallback 'resolve.fallback: { "stream": require.resolve("stream-browserify") }'
- install 'stream-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
resolve.fallback: { "stream": false }
It would be helpful to be able to decode the raw transaction.
So I was successful in minting a NFT with this package with just "pubKeyHash" but when I also add "all" and "invalidBefore" to try and make a time-locked policyId and submit the transaction I get the following errors:
"transaction submit error ShelleyTxValidationError ShelleyBasedEraAlonzo (ApplyTxError [UtxowFailure (WrappedShelleyEraFailure (ScriptWitnessNotValidatingUTXOW (fromList [ScriptHash \\"bf31919f8550764b5299a1ddb4d53265c5124b45d8e751eef36ac891\\"])))])"
This is the nativeScript I use to get the policyId and submit the transaction:
nativeScript: {
"all":
[
{ "pubKeyHash": "2f3f2d0a2c0c0d9f0a1abb46f08be8a8f05fb941222ef03705a49a83" },
{ "invalidBefore": 70998357 }
]
}
If I use just the following to generate policy and set the required variables I can mint no problem but it's not time-locked.
nativeScript: {
"pubKeyHash": "2f3f2d0a2c0c0d9f0a1abb46f08be8a8f05fb941222ef03705a49a83"
}
Google searches say that I should use --invalid-hereafter with the same slot or before the one used in the invalidBefore in the CLI so I added the same slot number to TTL. Am I doing something wrong?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.