@ledgerhq/coin-cardano
Advanced tools
Comparing version 0.2.2-nightly.0 to 0.2.2
# @ledgerhq/coin-cardano | ||
## 0.2.2-nightly.0 | ||
## 0.2.2 | ||
### Patch Changes | ||
- Updated dependencies [[`c83af75`](https://github.com/LedgerHQ/ledger-live/commit/c83af756fb388043c9f5a3862cae1231ec99a02c)]: | ||
- @ledgerhq/types-cryptoassets@7.16.0-nightly.0 | ||
- @ledgerhq/cryptoassets@13.6.0-nightly.0 | ||
- @ledgerhq/types-live@6.52.0-nightly.0 | ||
- @ledgerhq/coin-framework@0.18.2-nightly.0 | ||
- [#7978](https://github.com/LedgerHQ/ledger-live/pull/7978) [`77adfc3`](https://github.com/LedgerHQ/ledger-live/commit/77adfc33d4fd7d8f39329f23a36a55029331feb0) Thanks [@hedi-edelbloute](https://github.com/hedi-edelbloute)! - Cardano fees warning + fix high fees issue | ||
## 0.2.2-hotfix.0 | ||
### Patch Changes | ||
- [#7978](https://github.com/LedgerHQ/ledger-live/pull/7978) [`77adfc3`](https://github.com/LedgerHQ/ledger-live/commit/77adfc33d4fd7d8f39329f23a36a55029331feb0) Thanks [@hedi-edelbloute](https://github.com/hedi-edelbloute)! - Cardano fees warning + fix high fees issue | ||
## 0.2.1 | ||
@@ -14,0 +16,0 @@ |
@@ -5,5 +5,7 @@ import { SignerContext } from "@ledgerhq/coin-framework/signer"; | ||
import { CardanoSigner } from "../signer"; | ||
import { CoinConfig } from "@ledgerhq/coin-framework/lib/config"; | ||
import { CardanoCoinConfig } from "../config"; | ||
export declare function buildCurrencyBridge(signerContext: SignerContext<CardanoSigner>): CurrencyBridge; | ||
export declare function buildAccountBridge(signerContext: SignerContext<CardanoSigner>): AccountBridge<Transaction, CardanoAccount, TransactionStatus>; | ||
export declare function createBridges(signerContext: SignerContext<CardanoSigner>): { | ||
export declare function createBridges(signerContext: SignerContext<CardanoSigner>, coinConfig: CoinConfig<CardanoCoinConfig>): { | ||
currencyBridge: CurrencyBridge; | ||
@@ -10,0 +12,0 @@ accountBridge: AccountBridge<Transaction, CardanoAccount, import("@ledgerhq/types-live").TransactionStatusCommon, import("@ledgerhq/types-live").AccountRaw>; |
@@ -22,2 +22,3 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
import resolver from "../hw-getAddress"; | ||
import cardanoCoinConfig from "../config"; | ||
export function buildCurrencyBridge(signerContext) { | ||
@@ -56,3 +57,4 @@ const getAddress = resolver(signerContext); | ||
} | ||
export function createBridges(signerContext) { | ||
export function createBridges(signerContext, coinConfig) { | ||
cardanoCoinConfig.setCoinConfig(coinConfig); | ||
return { | ||
@@ -59,0 +61,0 @@ currencyBridge: buildCurrencyBridge(signerContext), |
@@ -13,6 +13,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
import { RewardAddress } from "@stricahq/typhonjs/dist/address"; | ||
import { getAccountStakeCredential, getBaseAddress, getTTL, mergeTokens, isTestnet } from "./logic"; | ||
import { getAccountStakeCredential, getBaseAddress, getTTL, mergeTokens, isTestnet, isProtocolParamsValid, } from "./logic"; | ||
import { decodeTokenAssetId, decodeTokenCurrencyId, getTokenAssetId } from "./buildSubAccounts"; | ||
import { getNetworkParameters } from "./networks"; | ||
import { CARDANO_MAX_SUPPLY } from "./constants"; | ||
import { CardanoInvalidProtoParams } from "./errors"; | ||
function getTyphonInputFromUtxo(utxo) { | ||
@@ -273,3 +274,6 @@ const address = TyphonUtils.getAddressFromHex(Buffer.from(utxo.address, "hex")); | ||
const cardanoResources = account.cardanoResources; | ||
const protocolParams = cardanoResources.protocolParams; | ||
const { protocolParams } = transaction; | ||
if (!protocolParams || !isProtocolParamsValid(protocolParams)) { | ||
throw new CardanoInvalidProtoParams(); | ||
} | ||
const typhonTx = new TyphonTransaction({ | ||
@@ -276,0 +280,0 @@ protocolParams: { |
@@ -22,2 +22,14 @@ /** | ||
}>; | ||
/** | ||
* Cardano warning/error for high fees | ||
*/ | ||
export declare const CardanoFeeHigh: import("@ledgerhq/errors/lib/helpers").LedgerErrorConstructor<{ | ||
[key: string]: unknown; | ||
}>; | ||
export declare const CardanoFeeTooHigh: import("@ledgerhq/errors/lib/helpers").LedgerErrorConstructor<{ | ||
[key: string]: unknown; | ||
}>; | ||
export declare const CardanoInvalidProtoParams: import("@ledgerhq/errors/lib/helpers").LedgerErrorConstructor<{ | ||
[key: string]: unknown; | ||
}>; | ||
//# sourceMappingURL=errors.d.ts.map |
@@ -15,2 +15,8 @@ import { createCustomErrorClass } from "@ledgerhq/errors"; | ||
export const CardanoInvalidPoolId = createCustomErrorClass("CardanoInvalidPoolId"); | ||
/** | ||
* Cardano warning/error for high fees | ||
*/ | ||
export const CardanoFeeHigh = createCustomErrorClass("CardanoFeeHigh"); | ||
export const CardanoFeeTooHigh = createCustomErrorClass("CardanoFeeTooHigh"); | ||
export const CardanoInvalidProtoParams = createCustomErrorClass("CardanoInvalidProtoParams"); | ||
//# sourceMappingURL=errors.js.map |
@@ -16,2 +16,3 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
import { buildTransaction } from "./buildTransaction"; | ||
import { prepareTransaction } from "./prepareTransaction"; | ||
/** | ||
@@ -31,3 +32,3 @@ * Returns the maximum possible amount for transaction | ||
const dummyRecipient = "addr1qyqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqv2t5am"; | ||
const t = Object.assign(Object.assign(Object.assign({}, createTransaction(account)), transaction), { recipient: dummyRecipient, | ||
let t = Object.assign(Object.assign(Object.assign({}, createTransaction(account)), transaction), { recipient: dummyRecipient, | ||
// amount field will not be used to build a transaction when useAllAmount is true | ||
@@ -37,2 +38,3 @@ amount: new BigNumber(0), useAllAmount: true }); | ||
try { | ||
t = yield prepareTransaction(account, t); | ||
typhonTransaction = yield buildTransaction(mainAccount, t); | ||
@@ -39,0 +41,0 @@ } |
@@ -18,4 +18,5 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
import { getNetworkParameters } from "./networks"; | ||
import { CardanoInvalidPoolId, CardanoStakeKeyDepositError, CardanoMinAmountError, CardanoNotEnoughFunds, } from "./errors"; | ||
import { CardanoInvalidPoolId, CardanoStakeKeyDepositError, CardanoMinAmountError, CardanoNotEnoughFunds, CardanoFeeTooHigh, CardanoFeeHigh, } from "./errors"; | ||
import { CARDANO_MAX_SUPPLY } from "./constants"; | ||
import coinConfig from "./config"; | ||
export const getTransactionStatus = (account, transaction) => __awaiter(void 0, void 0, void 0, function* () { | ||
@@ -37,10 +38,11 @@ if (account.pendingOperations.length > 0) { | ||
} | ||
let txStatus; | ||
if (transaction.mode === "send") { | ||
return getSendTransactionStatus(account, transaction); | ||
txStatus = yield getSendTransactionStatus(account, transaction); | ||
} | ||
else if (transaction.mode === "delegate") { | ||
return getDelegateTransactionStatus(account, transaction); | ||
txStatus = yield getDelegateTransactionStatus(account, transaction); | ||
} | ||
else if (transaction.mode === "undelegate") { | ||
return getUndelegateTransactionStatus(account, transaction); | ||
txStatus = yield getUndelegateTransactionStatus(account, transaction); | ||
} | ||
@@ -50,2 +52,11 @@ else { | ||
} | ||
const MAX_FEES_WARN = coinConfig.getCoinConfig().maxFeesWarning; | ||
const MAX_FEES_THROW = coinConfig.getCoinConfig().maxFeesError; | ||
if (txStatus.estimatedFees.gt(MAX_FEES_THROW)) { | ||
throw new CardanoFeeTooHigh(); | ||
} | ||
else if (txStatus.estimatedFees.gt(MAX_FEES_WARN)) { | ||
txStatus.warnings.feeTooHigh = new CardanoFeeHigh(); | ||
} | ||
return txStatus; | ||
}); | ||
@@ -52,0 +63,0 @@ function getSendTransactionStatus(account, transaction) { |
import { types as TyphonTypes, address as TyphonAddress } from "@stricahq/typhonjs"; | ||
import { CardanoAccount, BipPath, PaymentChain, PaymentCredential, StakeChain, StakeCredential, Token } from "./types"; | ||
import { CardanoAccount, BipPath, PaymentChain, PaymentCredential, StakeChain, StakeCredential, Token, ProtocolParams } from "./types"; | ||
import { Bip32PublicKey } from "@stricahq/bip32ed25519"; | ||
@@ -88,2 +88,4 @@ import BigNumber from "bignumber.js"; | ||
export declare function getBech32PoolId(poolId: string, networkName: string): string; | ||
export declare function isValidNumString(value: unknown): boolean; | ||
export declare function isProtocolParamsValid(pp: ProtocolParams): boolean; | ||
//# sourceMappingURL=logic.d.ts.map |
@@ -236,2 +236,26 @@ import { CARDANO_COIN_TYPE, CARDANO_PURPOSE, MEMO_LABEL, STAKING_ADDRESS_INDEX, TTL_GAP, } from "./constants"; | ||
} | ||
export function isValidNumString(value) { | ||
if (typeof value !== "string" && typeof value !== "number") | ||
return false; | ||
if (isNaN(Number(value))) | ||
return false; | ||
if (new BigNumber(value).isNaN()) | ||
return false; | ||
return true; | ||
} | ||
export function isProtocolParamsValid(pp) { | ||
const paramsRequiredCheck = [ | ||
pp.minFeeA, | ||
pp.minFeeB, | ||
pp.stakeKeyDeposit, | ||
pp.lovelacePerUtxoWord, | ||
pp.collateralPercent, | ||
pp.priceSteps, | ||
pp.priceMem, | ||
pp.maxTxSize, | ||
pp.maxValueSize, | ||
pp.utxoCostPerByte, | ||
]; | ||
return paramsRequiredCheck.every(isValidNumString); | ||
} | ||
//# sourceMappingURL=logic.js.map |
import BigNumber from "bignumber.js"; | ||
import { canStake, isAlreadyStaking } from "./logic"; | ||
import { canStake, isAlreadyStaking, isValidNumString } from "./logic"; | ||
describe("canStake", () => { | ||
@@ -35,2 +35,17 @@ it("should return false when acc has no funds", () => { | ||
}); | ||
describe("isValidNumString", () => { | ||
it("should return false for invalid number", () => { | ||
expect(isValidNumString("")).toEqual(false); | ||
expect(isValidNumString(undefined)).toEqual(false); | ||
expect(isValidNumString(null)).toEqual(false); | ||
expect(isValidNumString({})).toEqual(false); | ||
expect(isValidNumString([])).toEqual(false); | ||
}); | ||
it("should return true for valid number", () => { | ||
expect(isValidNumString(123)).toEqual(true); | ||
expect(isValidNumString(123.321)).toEqual(true); | ||
expect(isValidNumString("123")).toEqual(true); | ||
expect(isValidNumString("123.321")).toEqual(true); | ||
}); | ||
}); | ||
//# sourceMappingURL=logic.unit.test.js.map |
@@ -14,2 +14,3 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
import { buildTransaction } from "./buildTransaction"; | ||
import { fetchNetworkInfo } from "./api/getNetworkInfo"; | ||
/** | ||
@@ -23,2 +24,8 @@ * Prepare transaction before checking status | ||
let patch = {}; | ||
if (!transaction.protocolParams) { | ||
const networkInfo = yield fetchNetworkInfo(account.currency); | ||
transaction = defaultUpdateTransaction(transaction, { | ||
protocolParams: networkInfo.protocolParams, | ||
}); | ||
} | ||
try { | ||
@@ -25,0 +32,0 @@ const cardanoTransaction = yield buildTransaction(account, transaction); |
@@ -17,2 +17,3 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
import typhonSerializer from "./typhonSerializer"; | ||
import { CardanoInvalidProtoParams } from "./errors"; | ||
/** | ||
@@ -28,2 +29,5 @@ * Sign Transaction with Ledger hardware | ||
} | ||
if (!transaction.protocolParams) { | ||
throw new CardanoInvalidProtoParams(); | ||
} | ||
const unsignedTransaction = yield buildTransaction(account, transaction); | ||
@@ -30,0 +34,0 @@ const signerTransaction = typhonSerializer(unsignedTransaction, account.index); |
@@ -22,3 +22,3 @@ import { BigNumber } from "bignumber.js"; | ||
const common = fromTransactionCommonRaw(tr); | ||
return Object.assign(Object.assign({}, common), { family: tr.family, mode: tr.mode, fees: tr.fees ? new BigNumber(tr.fees) : undefined, memo: tr.memo, poolId: tr.poolId }); | ||
return Object.assign(Object.assign({}, common), { family: tr.family, mode: tr.mode, fees: tr.fees ? new BigNumber(tr.fees) : undefined, memo: tr.memo, poolId: tr.poolId, protocolParams: tr.protocolParams }); | ||
}; | ||
@@ -28,3 +28,3 @@ export const toTransactionRaw = (t) => { | ||
const common = toTransactionCommonRaw(t); | ||
return Object.assign(Object.assign({}, common), { family: t.family, mode: t.mode, fees: ((_a = t.fees) === null || _a === void 0 ? void 0 : _a.toString()) || undefined, memo: t.memo, poolId: t.poolId }); | ||
return Object.assign(Object.assign({}, common), { family: t.family, mode: t.mode, fees: ((_a = t.fees) === null || _a === void 0 ? void 0 : _a.toString()) || undefined, memo: t.memo, poolId: t.poolId, protocolParams: t.protocolParams }); | ||
}; | ||
@@ -31,0 +31,0 @@ export default { |
@@ -149,2 +149,3 @@ import type { BigNumber } from "bignumber.js"; | ||
poolId: string | undefined; | ||
protocolParams?: ProtocolParams; | ||
}; | ||
@@ -160,2 +161,3 @@ /** | ||
poolId: string | undefined; | ||
protocolParams?: ProtocolParams; | ||
}; | ||
@@ -162,0 +164,0 @@ export type CardanoLikeNetworkParameters = { |
@@ -5,5 +5,7 @@ import { SignerContext } from "@ledgerhq/coin-framework/signer"; | ||
import { CardanoSigner } from "../signer"; | ||
import { CoinConfig } from "@ledgerhq/coin-framework/lib/config"; | ||
import { CardanoCoinConfig } from "../config"; | ||
export declare function buildCurrencyBridge(signerContext: SignerContext<CardanoSigner>): CurrencyBridge; | ||
export declare function buildAccountBridge(signerContext: SignerContext<CardanoSigner>): AccountBridge<Transaction, CardanoAccount, TransactionStatus>; | ||
export declare function createBridges(signerContext: SignerContext<CardanoSigner>): { | ||
export declare function createBridges(signerContext: SignerContext<CardanoSigner>, coinConfig: CoinConfig<CardanoCoinConfig>): { | ||
currencyBridge: CurrencyBridge; | ||
@@ -10,0 +12,0 @@ accountBridge: AccountBridge<Transaction, CardanoAccount, import("@ledgerhq/types-live").TransactionStatusCommon, import("@ledgerhq/types-live").AccountRaw>; |
@@ -28,2 +28,3 @@ "use strict"; | ||
const hw_getAddress_1 = __importDefault(require("../hw-getAddress")); | ||
const config_1 = __importDefault(require("../config")); | ||
function buildCurrencyBridge(signerContext) { | ||
@@ -64,3 +65,4 @@ const getAddress = (0, hw_getAddress_1.default)(signerContext); | ||
exports.buildAccountBridge = buildAccountBridge; | ||
function createBridges(signerContext) { | ||
function createBridges(signerContext, coinConfig) { | ||
config_1.default.setCoinConfig(coinConfig); | ||
return { | ||
@@ -67,0 +69,0 @@ currencyBridge: buildCurrencyBridge(signerContext), |
@@ -23,2 +23,3 @@ "use strict"; | ||
const constants_1 = require("./constants"); | ||
const errors_1 = require("./errors"); | ||
function getTyphonInputFromUtxo(utxo) { | ||
@@ -279,3 +280,6 @@ const address = typhonjs_1.utils.getAddressFromHex(Buffer.from(utxo.address, "hex")); | ||
const cardanoResources = account.cardanoResources; | ||
const protocolParams = cardanoResources.protocolParams; | ||
const { protocolParams } = transaction; | ||
if (!protocolParams || !(0, logic_1.isProtocolParamsValid)(protocolParams)) { | ||
throw new errors_1.CardanoInvalidProtoParams(); | ||
} | ||
const typhonTx = new typhonjs_1.Transaction({ | ||
@@ -282,0 +286,0 @@ protocolParams: { |
@@ -22,2 +22,14 @@ /** | ||
}>; | ||
/** | ||
* Cardano warning/error for high fees | ||
*/ | ||
export declare const CardanoFeeHigh: import("@ledgerhq/errors/lib/helpers").LedgerErrorConstructor<{ | ||
[key: string]: unknown; | ||
}>; | ||
export declare const CardanoFeeTooHigh: import("@ledgerhq/errors/lib/helpers").LedgerErrorConstructor<{ | ||
[key: string]: unknown; | ||
}>; | ||
export declare const CardanoInvalidProtoParams: import("@ledgerhq/errors/lib/helpers").LedgerErrorConstructor<{ | ||
[key: string]: unknown; | ||
}>; | ||
//# sourceMappingURL=errors.d.ts.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.CardanoInvalidPoolId = exports.CardanoNotEnoughFunds = exports.CardanoStakeKeyDepositError = exports.CardanoMinAmountError = void 0; | ||
exports.CardanoInvalidProtoParams = exports.CardanoFeeTooHigh = exports.CardanoFeeHigh = exports.CardanoInvalidPoolId = exports.CardanoNotEnoughFunds = exports.CardanoStakeKeyDepositError = exports.CardanoMinAmountError = void 0; | ||
const errors_1 = require("@ledgerhq/errors"); | ||
@@ -18,2 +18,8 @@ /** | ||
exports.CardanoInvalidPoolId = (0, errors_1.createCustomErrorClass)("CardanoInvalidPoolId"); | ||
/** | ||
* Cardano warning/error for high fees | ||
*/ | ||
exports.CardanoFeeHigh = (0, errors_1.createCustomErrorClass)("CardanoFeeHigh"); | ||
exports.CardanoFeeTooHigh = (0, errors_1.createCustomErrorClass)("CardanoFeeTooHigh"); | ||
exports.CardanoInvalidProtoParams = (0, errors_1.createCustomErrorClass)("CardanoInvalidProtoParams"); | ||
//# sourceMappingURL=errors.js.map |
@@ -19,2 +19,3 @@ "use strict"; | ||
const buildTransaction_1 = require("./buildTransaction"); | ||
const prepareTransaction_1 = require("./prepareTransaction"); | ||
/** | ||
@@ -34,3 +35,3 @@ * Returns the maximum possible amount for transaction | ||
const dummyRecipient = "addr1qyqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqv2t5am"; | ||
const t = Object.assign(Object.assign(Object.assign({}, (0, createTransaction_1.createTransaction)(account)), transaction), { recipient: dummyRecipient, | ||
let t = Object.assign(Object.assign(Object.assign({}, (0, createTransaction_1.createTransaction)(account)), transaction), { recipient: dummyRecipient, | ||
// amount field will not be used to build a transaction when useAllAmount is true | ||
@@ -40,2 +41,3 @@ amount: new bignumber_js_1.BigNumber(0), useAllAmount: true }); | ||
try { | ||
t = yield (0, prepareTransaction_1.prepareTransaction)(account, t); | ||
typhonTransaction = yield (0, buildTransaction_1.buildTransaction)(mainAccount, t); | ||
@@ -42,0 +44,0 @@ } |
@@ -11,2 +11,5 @@ "use strict"; | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -24,2 +27,3 @@ exports.getTransactionStatus = void 0; | ||
const constants_1 = require("./constants"); | ||
const config_1 = __importDefault(require("./config")); | ||
const getTransactionStatus = (account, transaction) => __awaiter(void 0, void 0, void 0, function* () { | ||
@@ -41,10 +45,11 @@ if (account.pendingOperations.length > 0) { | ||
} | ||
let txStatus; | ||
if (transaction.mode === "send") { | ||
return getSendTransactionStatus(account, transaction); | ||
txStatus = yield getSendTransactionStatus(account, transaction); | ||
} | ||
else if (transaction.mode === "delegate") { | ||
return getDelegateTransactionStatus(account, transaction); | ||
txStatus = yield getDelegateTransactionStatus(account, transaction); | ||
} | ||
else if (transaction.mode === "undelegate") { | ||
return getUndelegateTransactionStatus(account, transaction); | ||
txStatus = yield getUndelegateTransactionStatus(account, transaction); | ||
} | ||
@@ -54,2 +59,11 @@ else { | ||
} | ||
const MAX_FEES_WARN = config_1.default.getCoinConfig().maxFeesWarning; | ||
const MAX_FEES_THROW = config_1.default.getCoinConfig().maxFeesError; | ||
if (txStatus.estimatedFees.gt(MAX_FEES_THROW)) { | ||
throw new errors_2.CardanoFeeTooHigh(); | ||
} | ||
else if (txStatus.estimatedFees.gt(MAX_FEES_WARN)) { | ||
txStatus.warnings.feeTooHigh = new errors_2.CardanoFeeHigh(); | ||
} | ||
return txStatus; | ||
}); | ||
@@ -56,0 +70,0 @@ exports.getTransactionStatus = getTransactionStatus; |
import { types as TyphonTypes, address as TyphonAddress } from "@stricahq/typhonjs"; | ||
import { CardanoAccount, BipPath, PaymentChain, PaymentCredential, StakeChain, StakeCredential, Token } from "./types"; | ||
import { CardanoAccount, BipPath, PaymentChain, PaymentCredential, StakeChain, StakeCredential, Token, ProtocolParams } from "./types"; | ||
import { Bip32PublicKey } from "@stricahq/bip32ed25519"; | ||
@@ -88,2 +88,4 @@ import BigNumber from "bignumber.js"; | ||
export declare function getBech32PoolId(poolId: string, networkName: string): string; | ||
export declare function isValidNumString(value: unknown): boolean; | ||
export declare function isProtocolParamsValid(pp: ProtocolParams): boolean; | ||
//# sourceMappingURL=logic.d.ts.map |
@@ -6,3 +6,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.getBech32PoolId = exports.decodeTokenName = exports.isHexString = exports.getMemoFromTx = exports.getAccountChange = exports.isTestnet = exports.getOperationType = exports.getAccountStakeCredential = exports.getTokenDiff = exports.mergeTokens = exports.getEpoch = exports.getTTL = exports.getAbsoluteSlot = exports.isValidAddress = exports.getBaseAddress = exports.getCredentialKey = exports.getExtendedPublicKeyFromHex = exports.getBipPathString = exports.getBipPath = exports.isAlreadyStaking = exports.canStake = exports.getBipPathFromString = void 0; | ||
exports.isProtocolParamsValid = exports.isValidNumString = exports.getBech32PoolId = exports.decodeTokenName = exports.isHexString = exports.getMemoFromTx = exports.getAccountChange = exports.isTestnet = exports.getOperationType = exports.getAccountStakeCredential = exports.getTokenDiff = exports.mergeTokens = exports.getEpoch = exports.getTTL = exports.getAbsoluteSlot = exports.isValidAddress = exports.getBaseAddress = exports.getCredentialKey = exports.getExtendedPublicKeyFromHex = exports.getBipPathString = exports.getBipPath = exports.isAlreadyStaking = exports.canStake = exports.getBipPathFromString = void 0; | ||
const constants_1 = require("./constants"); | ||
@@ -265,2 +265,28 @@ const typhonjs_1 = require("@stricahq/typhonjs"); | ||
exports.getBech32PoolId = getBech32PoolId; | ||
function isValidNumString(value) { | ||
if (typeof value !== "string" && typeof value !== "number") | ||
return false; | ||
if (isNaN(Number(value))) | ||
return false; | ||
if (new bignumber_js_1.default(value).isNaN()) | ||
return false; | ||
return true; | ||
} | ||
exports.isValidNumString = isValidNumString; | ||
function isProtocolParamsValid(pp) { | ||
const paramsRequiredCheck = [ | ||
pp.minFeeA, | ||
pp.minFeeB, | ||
pp.stakeKeyDeposit, | ||
pp.lovelacePerUtxoWord, | ||
pp.collateralPercent, | ||
pp.priceSteps, | ||
pp.priceMem, | ||
pp.maxTxSize, | ||
pp.maxValueSize, | ||
pp.utxoCostPerByte, | ||
]; | ||
return paramsRequiredCheck.every(isValidNumString); | ||
} | ||
exports.isProtocolParamsValid = isProtocolParamsValid; | ||
//# sourceMappingURL=logic.js.map |
@@ -40,2 +40,17 @@ "use strict"; | ||
}); | ||
describe("isValidNumString", () => { | ||
it("should return false for invalid number", () => { | ||
expect((0, logic_1.isValidNumString)("")).toEqual(false); | ||
expect((0, logic_1.isValidNumString)(undefined)).toEqual(false); | ||
expect((0, logic_1.isValidNumString)(null)).toEqual(false); | ||
expect((0, logic_1.isValidNumString)({})).toEqual(false); | ||
expect((0, logic_1.isValidNumString)([])).toEqual(false); | ||
}); | ||
it("should return true for valid number", () => { | ||
expect((0, logic_1.isValidNumString)(123)).toEqual(true); | ||
expect((0, logic_1.isValidNumString)(123.321)).toEqual(true); | ||
expect((0, logic_1.isValidNumString)("123")).toEqual(true); | ||
expect((0, logic_1.isValidNumString)("123.321")).toEqual(true); | ||
}); | ||
}); | ||
//# sourceMappingURL=logic.unit.test.js.map |
@@ -17,2 +17,3 @@ "use strict"; | ||
const buildTransaction_1 = require("./buildTransaction"); | ||
const getNetworkInfo_1 = require("./api/getNetworkInfo"); | ||
/** | ||
@@ -26,2 +27,8 @@ * Prepare transaction before checking status | ||
let patch = {}; | ||
if (!transaction.protocolParams) { | ||
const networkInfo = yield (0, getNetworkInfo_1.fetchNetworkInfo)(account.currency); | ||
transaction = (0, jsHelpers_1.defaultUpdateTransaction)(transaction, { | ||
protocolParams: networkInfo.protocolParams, | ||
}); | ||
} | ||
try { | ||
@@ -28,0 +35,0 @@ const cardanoTransaction = yield (0, buildTransaction_1.buildTransaction)(account, transaction); |
@@ -23,2 +23,3 @@ "use strict"; | ||
const typhonSerializer_1 = __importDefault(require("./typhonSerializer")); | ||
const errors_2 = require("./errors"); | ||
/** | ||
@@ -34,2 +35,5 @@ * Sign Transaction with Ledger hardware | ||
} | ||
if (!transaction.protocolParams) { | ||
throw new errors_2.CardanoInvalidProtoParams(); | ||
} | ||
const unsignedTransaction = yield (0, buildTransaction_1.buildTransaction)(account, transaction); | ||
@@ -36,0 +40,0 @@ const signerTransaction = (0, typhonSerializer_1.default)(unsignedTransaction, account.index); |
@@ -26,3 +26,3 @@ "use strict"; | ||
const common = (0, serialization_1.fromTransactionCommonRaw)(tr); | ||
return Object.assign(Object.assign({}, common), { family: tr.family, mode: tr.mode, fees: tr.fees ? new bignumber_js_1.BigNumber(tr.fees) : undefined, memo: tr.memo, poolId: tr.poolId }); | ||
return Object.assign(Object.assign({}, common), { family: tr.family, mode: tr.mode, fees: tr.fees ? new bignumber_js_1.BigNumber(tr.fees) : undefined, memo: tr.memo, poolId: tr.poolId, protocolParams: tr.protocolParams }); | ||
}; | ||
@@ -33,3 +33,3 @@ exports.fromTransactionRaw = fromTransactionRaw; | ||
const common = (0, serialization_1.toTransactionCommonRaw)(t); | ||
return Object.assign(Object.assign({}, common), { family: t.family, mode: t.mode, fees: ((_a = t.fees) === null || _a === void 0 ? void 0 : _a.toString()) || undefined, memo: t.memo, poolId: t.poolId }); | ||
return Object.assign(Object.assign({}, common), { family: t.family, mode: t.mode, fees: ((_a = t.fees) === null || _a === void 0 ? void 0 : _a.toString()) || undefined, memo: t.memo, poolId: t.poolId, protocolParams: t.protocolParams }); | ||
}; | ||
@@ -36,0 +36,0 @@ exports.toTransactionRaw = toTransactionRaw; |
@@ -149,2 +149,3 @@ import type { BigNumber } from "bignumber.js"; | ||
poolId: string | undefined; | ||
protocolParams?: ProtocolParams; | ||
}; | ||
@@ -160,2 +161,3 @@ /** | ||
poolId: string | undefined; | ||
protocolParams?: ProtocolParams; | ||
}; | ||
@@ -162,0 +164,0 @@ export type CardanoLikeNetworkParameters = { |
{ | ||
"name": "@ledgerhq/coin-cardano", | ||
"version": "0.2.2-nightly.0", | ||
"version": "0.2.2", | ||
"description": "Ledger Cardano Coin integration", | ||
@@ -62,4 +62,4 @@ "keywords": [ | ||
"rxjs": "^7.8.1", | ||
"@ledgerhq/coin-framework": "^0.18.2-nightly.0", | ||
"@ledgerhq/cryptoassets": "^13.6.0-nightly.0", | ||
"@ledgerhq/coin-framework": "^0.18.1", | ||
"@ledgerhq/cryptoassets": "^13.5.0", | ||
"@ledgerhq/devices": "^8.4.4", | ||
@@ -70,4 +70,4 @@ "@ledgerhq/errors": "^6.19.1", | ||
"@ledgerhq/logs": "^6.12.0", | ||
"@ledgerhq/types-cryptoassets": "^7.16.0-nightly.0", | ||
"@ledgerhq/types-live": "^6.52.0-nightly.0" | ||
"@ledgerhq/types-cryptoassets": "^7.15.2", | ||
"@ledgerhq/types-live": "^6.51.1" | ||
}, | ||
@@ -74,0 +74,0 @@ "devDependencies": { |
@@ -22,2 +22,4 @@ import { | ||
import resolver from "../hw-getAddress"; | ||
import { CoinConfig } from "@ledgerhq/coin-framework/lib/config"; | ||
import cardanoCoinConfig, { CardanoCoinConfig } from "../config"; | ||
@@ -65,3 +67,7 @@ export function buildCurrencyBridge(signerContext: SignerContext<CardanoSigner>): CurrencyBridge { | ||
export function createBridges(signerContext: SignerContext<CardanoSigner>) { | ||
export function createBridges( | ||
signerContext: SignerContext<CardanoSigner>, | ||
coinConfig: CoinConfig<CardanoCoinConfig>, | ||
) { | ||
cardanoCoinConfig.setCoinConfig(coinConfig); | ||
return { | ||
@@ -68,0 +74,0 @@ currencyBridge: buildCurrencyBridge(signerContext), |
@@ -9,3 +9,10 @@ import { | ||
import { RewardAddress } from "@stricahq/typhonjs/dist/address"; | ||
import { getAccountStakeCredential, getBaseAddress, getTTL, mergeTokens, isTestnet } from "./logic"; | ||
import { | ||
getAccountStakeCredential, | ||
getBaseAddress, | ||
getTTL, | ||
mergeTokens, | ||
isTestnet, | ||
isProtocolParamsValid, | ||
} from "./logic"; | ||
import { decodeTokenAssetId, decodeTokenCurrencyId, getTokenAssetId } from "./buildSubAccounts"; | ||
@@ -22,2 +29,3 @@ import { getNetworkParameters } from "./networks"; | ||
import { CARDANO_MAX_SUPPLY } from "./constants"; | ||
import { CardanoInvalidProtoParams } from "./errors"; | ||
@@ -370,4 +378,8 @@ function getTyphonInputFromUtxo(utxo: CardanoOutput): TyphonTypes.Input { | ||
const cardanoResources = account.cardanoResources as CardanoResources; | ||
const protocolParams = cardanoResources.protocolParams; | ||
const { protocolParams } = transaction; | ||
if (!protocolParams || !isProtocolParamsValid(protocolParams)) { | ||
throw new CardanoInvalidProtoParams(); | ||
} | ||
const typhonTx = new TyphonTransaction({ | ||
@@ -374,0 +386,0 @@ protocolParams: { |
@@ -19,1 +19,9 @@ import { createCustomErrorClass } from "@ledgerhq/errors"; | ||
export const CardanoInvalidPoolId = createCustomErrorClass("CardanoInvalidPoolId"); | ||
/** | ||
* Cardano warning/error for high fees | ||
*/ | ||
export const CardanoFeeHigh = createCustomErrorClass("CardanoFeeHigh"); | ||
export const CardanoFeeTooHigh = createCustomErrorClass("CardanoFeeTooHigh"); | ||
export const CardanoInvalidProtoParams = createCustomErrorClass("CardanoInvalidProtoParams"); |
@@ -13,2 +13,3 @@ import { | ||
import { buildTransaction } from "./buildTransaction"; | ||
import { prepareTransaction } from "./prepareTransaction"; | ||
@@ -36,3 +37,3 @@ /** | ||
"addr1qyqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqv2t5am"; | ||
const t: Transaction = { | ||
let t: Transaction = { | ||
...createTransaction(account), | ||
@@ -47,2 +48,3 @@ ...transaction, | ||
try { | ||
t = await prepareTransaction(account, t); | ||
typhonTransaction = await buildTransaction(mainAccount, t); | ||
@@ -49,0 +51,0 @@ } catch (error) { |
@@ -22,2 +22,4 @@ import { | ||
CardanoNotEnoughFunds, | ||
CardanoFeeTooHigh, | ||
CardanoFeeHigh, | ||
} from "./errors"; | ||
@@ -32,2 +34,3 @@ import type { | ||
import { CARDANO_MAX_SUPPLY } from "./constants"; | ||
import coinConfig from "./config"; | ||
@@ -56,11 +59,24 @@ export const getTransactionStatus: AccountBridge< | ||
let txStatus: TransactionStatus; | ||
if (transaction.mode === "send") { | ||
return getSendTransactionStatus(account, transaction); | ||
txStatus = await getSendTransactionStatus(account, transaction); | ||
} else if (transaction.mode === "delegate") { | ||
return getDelegateTransactionStatus(account, transaction); | ||
txStatus = await getDelegateTransactionStatus(account, transaction); | ||
} else if (transaction.mode === "undelegate") { | ||
return getUndelegateTransactionStatus(account, transaction); | ||
txStatus = await getUndelegateTransactionStatus(account, transaction); | ||
} else { | ||
throw new Error("Invalid transaction mode"); | ||
} | ||
const MAX_FEES_WARN = coinConfig.getCoinConfig().maxFeesWarning; | ||
const MAX_FEES_THROW = coinConfig.getCoinConfig().maxFeesError; | ||
if (txStatus.estimatedFees.gt(MAX_FEES_THROW)) { | ||
throw new CardanoFeeTooHigh(); | ||
} else if (txStatus.estimatedFees.gt(MAX_FEES_WARN)) { | ||
txStatus.warnings.feeTooHigh = new CardanoFeeHigh(); | ||
} | ||
return txStatus; | ||
}; | ||
@@ -67,0 +83,0 @@ |
@@ -23,2 +23,3 @@ import { | ||
Token, | ||
ProtocolParams, | ||
} from "./types"; | ||
@@ -332,1 +333,24 @@ import { Bip32PublicKey } from "@stricahq/bip32ed25519"; | ||
} | ||
export function isValidNumString(value: unknown): boolean { | ||
if (typeof value !== "string" && typeof value !== "number") return false; | ||
if (isNaN(Number(value))) return false; | ||
if (new BigNumber(value).isNaN()) return false; | ||
return true; | ||
} | ||
export function isProtocolParamsValid(pp: ProtocolParams): boolean { | ||
const paramsRequiredCheck = [ | ||
pp.minFeeA, | ||
pp.minFeeB, | ||
pp.stakeKeyDeposit, | ||
pp.lovelacePerUtxoWord, | ||
pp.collateralPercent, | ||
pp.priceSteps, | ||
pp.priceMem, | ||
pp.maxTxSize, | ||
pp.maxValueSize, | ||
pp.utxoCostPerByte, | ||
]; | ||
return paramsRequiredCheck.every(isValidNumString); | ||
} |
import BigNumber from "bignumber.js"; | ||
import { canStake, isAlreadyStaking } from "./logic"; | ||
import { canStake, isAlreadyStaking, isValidNumString } from "./logic"; | ||
import { CardanoAccount } from "./types"; | ||
@@ -40,1 +40,18 @@ | ||
}); | ||
describe("isValidNumString", () => { | ||
it("should return false for invalid number", () => { | ||
expect(isValidNumString("")).toEqual(false); | ||
expect(isValidNumString(undefined)).toEqual(false); | ||
expect(isValidNumString(null)).toEqual(false); | ||
expect(isValidNumString({})).toEqual(false); | ||
expect(isValidNumString([])).toEqual(false); | ||
}); | ||
it("should return true for valid number", () => { | ||
expect(isValidNumString(123)).toEqual(true); | ||
expect(isValidNumString(123.321)).toEqual(true); | ||
expect(isValidNumString("123")).toEqual(true); | ||
expect(isValidNumString("123.321")).toEqual(true); | ||
}); | ||
}); |
@@ -8,2 +8,3 @@ import { BigNumber } from "bignumber.js"; | ||
import { AccountBridge } from "@ledgerhq/types-live"; | ||
import { fetchNetworkInfo } from "./api/getNetworkInfo"; | ||
@@ -21,2 +22,10 @@ /** | ||
let patch = {}; | ||
if (!transaction.protocolParams) { | ||
const networkInfo = await fetchNetworkInfo(account.currency); | ||
transaction = defaultUpdateTransaction(transaction, { | ||
protocolParams: networkInfo.protocolParams, | ||
}); | ||
} | ||
try { | ||
@@ -23,0 +32,0 @@ const cardanoTransaction = await buildTransaction(account, transaction); |
@@ -14,2 +14,3 @@ import { Observable } from "rxjs"; | ||
import typhonSerializer from "./typhonSerializer"; | ||
import { CardanoInvalidProtoParams } from "./errors"; | ||
@@ -32,2 +33,6 @@ /** | ||
if (!transaction.protocolParams) { | ||
throw new CardanoInvalidProtoParams(); | ||
} | ||
const unsignedTransaction = await buildTransaction(account, transaction); | ||
@@ -34,0 +39,0 @@ const signerTransaction = typhonSerializer(unsignedTransaction, account.index); |
@@ -44,2 +44,3 @@ import type { Transaction, TransactionRaw } from "./types"; | ||
poolId: tr.poolId, | ||
protocolParams: tr.protocolParams, | ||
}; | ||
@@ -57,2 +58,3 @@ }; | ||
poolId: t.poolId, | ||
protocolParams: t.protocolParams, | ||
}; | ||
@@ -59,0 +61,0 @@ }; |
@@ -180,2 +180,3 @@ import type { BigNumber } from "bignumber.js"; | ||
poolId: string | undefined; | ||
protocolParams?: ProtocolParams; | ||
// add here all transaction-specific fields if you implement other modes than "send" | ||
@@ -193,2 +194,3 @@ }; | ||
poolId: string | undefined; | ||
protocolParams?: ProtocolParams; | ||
// also the transaction fields as raw JSON data | ||
@@ -195,0 +197,0 @@ }; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
816873
386
12786