diff --git a/packages/module/package.json b/packages/module/package.json index c9001de2a..b5a18e68c 100644 --- a/packages/module/package.json +++ b/packages/module/package.json @@ -3,7 +3,7 @@ "description": "Rapidly build Web3 apps on the Cardano Blockchain.", "homepage": "https://meshjs.dev", "author": "MeshJS", - "version": "1.5.16", + "version": "1.6.0-alpha.4", "license": "Apache-2.0", "type": "module", "repository": { @@ -44,8 +44,7 @@ } }, "browser": { - "@emurgo/cardano-message-signing-nodejs": "@emurgo/cardano-message-signing-browser", - "@emurgo/cardano-serialization-lib-nodejs": "@emurgo/cardano-serialization-lib-browser" + "@emurgo/cardano-message-signing-nodejs": "@emurgo/cardano-message-signing-browser" }, "exports": { ".": { @@ -70,9 +69,8 @@ "dependencies": { "@emurgo/cardano-message-signing-browser": "1.0.1", "@emurgo/cardano-message-signing-nodejs": "1.0.1", - "@emurgo/cardano-serialization-lib-browser": "11.5.0", - "@emurgo/cardano-serialization-lib-nodejs": "11.5.0", "@emurgo/cip14-js": "3.0.1", + "@meshsdk/mesh-csl": "^0.0.5", "axios": "1.6.3", "bip39": "3.0.4", "json-bigint": "^1.0.0", diff --git a/packages/module/src/common/constants.ts b/packages/module/src/common/constants.ts index e1d2e6e1f..49d22c417 100644 --- a/packages/module/src/common/constants.ts +++ b/packages/module/src/common/constants.ts @@ -1,6 +1,6 @@ import { csl } from '@mesh/core'; import type { Costmdls } from '@mesh/core'; -import type { Budget, Era, Network, Protocol } from './types'; +import type { Budget, Era, Network, Protocol } from '../types'; export const DEFAULT_REDEEMER_BUDGET: Budget = { mem: 7_000_000, @@ -46,12 +46,10 @@ export const REDEEMER_TAGS = { SPEND: csl.RedeemerTag.new_spend(), }; -export const SUPPORTED_CLOCKS: Record = { +export const SUPPORTED_CLOCKS: Record< + Network, + [epoch: string, slot: string, systemStart: string, epochLength: string] +> = { testnet: ['74', '1598400', '1595967616', '432000'], preview: ['183', '15811222', '1682467200', '86400'], preprod: ['65', '26438400', '1682121600', '432000'], @@ -230,7 +228,7 @@ export const SUPPORTED_COST_MODELS: Record = { 'unMapData-memory-arguments': 32, 'verifyEd25519Signature-cpu-arguments-intercept': 57996947, 'verifyEd25519Signature-cpu-arguments-slope': 18975, - 'verifyEd25519Signature-memory-arguments': 10 + 'verifyEd25519Signature-memory-arguments': 10, }).forEach((cost, operation) => v1CostModel.set(operation, csl.Int.new_i32(cost)) ); @@ -411,7 +409,7 @@ export const SUPPORTED_COST_MODELS: Record = { 'verifyEd25519Signature-memory-arguments': 10, 'verifySchnorrSecp256k1Signature-cpu-arguments-intercept': 38887044, 'verifySchnorrSecp256k1Signature-cpu-arguments-slope': 32947, - 'verifySchnorrSecp256k1Signature-memory-arguments': 10 + 'verifySchnorrSecp256k1Signature-memory-arguments': 10, }).forEach((cost, operation) => v2CostModel.set(operation, csl.Int.new_i32(cost)) ); @@ -424,7 +422,8 @@ export const SUPPORTED_COST_MODELS: Record = { }; export const SUPPORTED_LANGUAGE_VIEWS: Record< - Era, Partial> + Era, + Partial> > = { ALONZO: { V1: 'a141005901d59f1a000302590001011a00060bc719026d00011a000249f01903e800011a000249f018201a0025cea81971f70419744d186419744d186419744d186419744d186419744d186419744d18641864186419744d18641a000249f018201a000249f018201a000249f018201a000249f01903e800011a000249f018201a000249f01903e800081a000242201a00067e2318760001011a000249f01903e800081a000249f01a0001b79818f7011a000249f0192710011a0002155e19052e011903e81a000249f01903e8011a000249f018201a000249f018201a000249f0182001011a000249f0011a000249f0041a000194af18f8011a000194af18f8011a0002377c190556011a0002bdea1901f1011a000249f018201a000249f018201a000249f018201a000249f018201a000249f018201a000249f018201a000242201a00067e23187600010119f04c192bd200011a000249f018201a000242201a00067e2318760001011a000242201a00067e2318760001011a0025cea81971f704001a000141bb041a000249f019138800011a000249f018201a000302590001011a000249f018201a000249f018201a000249f018201a000249f018201a000249f018201a000249f018201a000249f018201a00330da70101ff', @@ -436,8 +435,10 @@ export const SUPPORTED_LANGUAGE_VIEWS: Record< }; export const SUPPORTED_HANDLES: Record = { - [csl.NetworkInfo.testnet().network_id()]: '8d18d786e92776c824607fd8e193ec535c79dc61ea2405ddf3b09fe3', - [csl.NetworkInfo.mainnet().network_id()]: 'f0ff48bbb7bbe9d59a40f1ce90e9e9d0ff5002ec48f232b49ca0fb9a', + [csl.NetworkInfo.testnet().network_id()]: + '8d18d786e92776c824607fd8e193ec535c79dc61ea2405ddf3b09fe3', + [csl.NetworkInfo.mainnet().network_id()]: + 'f0ff48bbb7bbe9d59a40f1ce90e9e9d0ff5002ec48f232b49ca0fb9a', }; export const SUPPORTED_OGMIOS_LINKS: Record = { @@ -467,11 +468,15 @@ export const SUPPORTED_TOKENS = { HOSKY: 'a0028f350aaabe0545fdcb56b039bfb08e4bb4d8c4d7c3c7d481c235484f534b59', YUMMI: '078eafce5cd7edafdf63900edef2c1ea759e77f30ca81d6bbdeec92479756d6d69', C3: '8e51398904a5d3fc129fbf4f1589701de23c7824d5c90fdb9490e15a434841524c4933', - GIMBAL: '2b0a04a7b60132b1805b296c7fcb3b217ff14413991bf76f72663c3067696d62616c', - SUNDAE: '9a9693a9a37912a5097918f97918d15240c92ab729a0b7c4aa144d7753554e444145', - GREENS: '4623ab311b7d982d8d26fcbe1a9439ca56661aafcdcd8d8a0ef31fd6475245454e53', + GIMBAL: + '2b0a04a7b60132b1805b296c7fcb3b217ff14413991bf76f72663c3067696d62616c', + SUNDAE: + '9a9693a9a37912a5097918f97918d15240c92ab729a0b7c4aa144d7753554e444145', + GREENS: + '4623ab311b7d982d8d26fcbe1a9439ca56661aafcdcd8d8a0ef31fd6475245454e53', GENS: 'dda5fdb1002f7389b33e036b6afee82a8189becb6cba852e8b79b4fb0014df1047454e53', - SOCIETY: '25f0fc240e91bd95dcdaebd2ba7713fc5168ac77234a3d79449fc20c534f4349455459', + SOCIETY: + '25f0fc240e91bd95dcdaebd2ba7713fc5168ac77234a3d79449fc20c534f4349455459', DJED: '8db269c3ec630e06ae29f74bc39edd1f87c819f1056206e879a1cd61446a65644d6963726f555344', SHEN: '8db269c3ec630e06ae29f74bc39edd1f87c819f1056206e879a1cd615368656e4d6963726f555344', WMT: '1d7f33bd23d85e1a25d87d86fac4f199c3197a2f7afeb662a0f34e1e776f726c646d6f62696c65746f6b656e', @@ -479,5 +484,14 @@ export const SUPPORTED_TOKENS = { }; export const SUPPORTED_WALLETS = [ - 'begin', 'eternl', 'flint', 'lace', 'nami', 'nufi', 'gerowallet', 'typhoncip30', 'vespr', 'yoroi' + 'begin', + 'eternl', + 'flint', + 'lace', + 'nami', + 'nufi', + 'gerowallet', + 'typhoncip30', + 'vespr', + 'yoroi', ]; diff --git a/packages/module/src/common/contracts/evaluator.ts b/packages/module/src/common/contracts/evaluator.ts index 843a2ecd3..aa389b52b 100644 --- a/packages/module/src/common/contracts/evaluator.ts +++ b/packages/module/src/common/contracts/evaluator.ts @@ -1,4 +1,4 @@ -import { Action } from '@mesh/common/types'; +import { Action } from '@mesh/types'; export interface IEvaluator { evaluateTx(tx: string): Promise[]>; diff --git a/packages/module/src/common/contracts/fetcher.ts b/packages/module/src/common/contracts/fetcher.ts index 4eab04c5b..a41d2025b 100644 --- a/packages/module/src/common/contracts/fetcher.ts +++ b/packages/module/src/common/contracts/fetcher.ts @@ -6,7 +6,7 @@ import type { Protocol, TransactionInfo, UTxO, -} from '@mesh/common/types'; +} from '@mesh/types'; /** * Fetcher interface defines end points to query blockchain data. diff --git a/packages/module/src/common/contracts/signer.ts b/packages/module/src/common/contracts/signer.ts index 7a99ad707..d4dd18eda 100644 --- a/packages/module/src/common/contracts/signer.ts +++ b/packages/module/src/common/contracts/signer.ts @@ -1,4 +1,4 @@ -import { DataSignature } from '@mesh/common/types'; +import { DataSignature } from '@mesh/types'; export interface ISigner { signData(address: string, payload: string): SometimesPromise; diff --git a/packages/module/src/common/data/index.ts b/packages/module/src/common/data/index.ts new file mode 100644 index 000000000..9c8f01c13 --- /dev/null +++ b/packages/module/src/common/data/index.ts @@ -0,0 +1,2 @@ +export * from './mesh'; +export * from './plutus'; diff --git a/packages/module/src/common/data/mesh.ts b/packages/module/src/common/data/mesh.ts new file mode 100644 index 000000000..37455a7f0 --- /dev/null +++ b/packages/module/src/common/data/mesh.ts @@ -0,0 +1,43 @@ +import { Data } from '@mesh/types'; + +export const mConStr = ( + alternative: number, + fields: T +): Data => ({ + alternative, + fields, +}); + +export const mConStr0 = (fields: T): Data => ({ + alternative: 0, + fields, +}); + +export const mConStr1 = (fields: T): Data => ({ + alternative: 1, + fields, +}); + +export const mConStr2 = (fields: T): Data => ({ + alternative: 2, + fields, +}); + +export const mMaybeStakingHash = (stakeCredential: string): Data => { + if (stakeCredential === '') { + return mConStr1<[]>([]); + } + return mConStr0([mConStr0([mConStr0([stakeCredential])])]); +}; + +export const mPubKeyAddress = (bytes: string, stakeCredential?: string): Data => + mConStr0([ + { alternative: 0, fields: [bytes] }, + mMaybeStakingHash(stakeCredential || ''), + ]); + +export const mScriptAddress = (bytes: string, stakeCredential?: string): Data => + mConStr0([ + { alternative: 1, fields: [bytes] }, + mMaybeStakingHash(stakeCredential || ''), + ]); diff --git a/packages/module/src/common/data/plutus.spec.ts b/packages/module/src/common/data/plutus.spec.ts new file mode 100644 index 000000000..3d0ed0027 --- /dev/null +++ b/packages/module/src/common/data/plutus.spec.ts @@ -0,0 +1,121 @@ +import { Asset } from '@meshsdk/core'; +import { + value, + Value, + dict, + BuiltinByteString, + Integer, + builtinByteString, + integer, + Dict, + parsePlutusValueToAssets, +} from './'; + +describe('Plutus data type', () => { + describe('Value', () => { + test('Simple ADA Value', () => { + const val: Asset[] = [{ unit: 'lovelace', quantity: '1000000' }]; + const datum: Value = value(val); + + const nameMap = dict([ + [builtinByteString(''), integer(1000000)], + ]); + const valMap = dict>([ + [builtinByteString(''), nameMap], + ]); + expect(JSON.stringify(datum)).toBe(JSON.stringify(valMap)); + }); + test('Simple token Value', () => { + const val: Asset[] = [ + { + unit: 'baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc8170074657374696e676e657777616c2e616461', + quantity: '345', + }, + ]; + const datum: Value = value(val); + + const nameMap = dict([ + [builtinByteString('74657374696e676e657777616c2e616461'), integer(345)], + ]); + const valMap = dict>([ + [ + builtinByteString( + 'baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc81700' + ), + nameMap, + ], + ]); + expect(JSON.stringify(datum)).toBe(JSON.stringify(valMap)); + }); + test('Complex Value', () => { + const val: Asset[] = [ + { unit: 'lovelace', quantity: '1000000' }, + { + unit: 'baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc8170074657374696e676e657777616c2e616461', + quantity: '345', + }, + { + unit: 'baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc817001234', + quantity: '567', + }, + ]; + const datum: Value = value(val); + + const nameMap = dict([ + [builtinByteString('1234'), integer(567)], + [builtinByteString('74657374696e676e657777616c2e616461'), integer(345)], + ]); + const valMap = dict>([ + [ + builtinByteString(''), + dict([[builtinByteString(''), integer(1000000)]]), + ], + [ + builtinByteString( + 'baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc81700' + ), + nameMap, + ], + ]); + expect(JSON.stringify(datum)).toBe(JSON.stringify(valMap)); + }); + }); +}); + +describe('Value', () => { + test('Simple ADA Value', () => { + const val: Asset[] = [{ unit: 'lovelace', quantity: '1000000' }]; + const plutusValue: Value = value(val); + const assets: Asset[] = parsePlutusValueToAssets(plutusValue); + + expect(JSON.stringify(val)).toBe(JSON.stringify(assets)); + }); + test('Simple token Value', () => { + const val: Asset[] = [ + { + unit: 'baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc8170074657374696e676e657777616c2e616461', + quantity: '345', + }, + ]; + const plutusValue: Value = value(val); + const assets: Asset[] = parsePlutusValueToAssets(plutusValue); + + expect(JSON.stringify(val)).toBe(JSON.stringify(assets)); + }); + test('Complex Value', () => { + const val: Asset[] = [ + { unit: 'lovelace', quantity: '1000000' }, + { + unit: 'baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc817001234', + quantity: '567', + }, + { + unit: 'baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc8170074657374696e676e657777616c2e616461', + quantity: '345', + }, + ]; + const plutusValue: Value = value(val); + const assets: Asset[] = parsePlutusValueToAssets(plutusValue); + expect(JSON.stringify(val)).toBe(JSON.stringify(assets)); + }); +}); diff --git a/packages/module/src/common/data/plutus.ts b/packages/module/src/common/data/plutus.ts new file mode 100644 index 000000000..abc53ec3b --- /dev/null +++ b/packages/module/src/common/data/plutus.ts @@ -0,0 +1,151 @@ +import { Asset } from '@mesh/types'; + +export type ConStr = { constructor: N; fields: T }; +export type ConStr0 = ConStr<0, T>; +export type ConStr1 = ConStr<1, T>; +export type ConStr2 = ConStr<2, T>; +export type Bool = ConStr0<[]> | ConStr1<[]>; +export type BuiltinByteString = { bytes: string }; +export type Integer = { int: number }; +export type List = { list: PlutusData[] }; +export type ValidatorHash = BuiltinByteString; +export type PaymentPubKeyHash = BuiltinByteString; +export type PubKeyHash = PaymentPubKeyHash; +export type POSIXTime = Integer; +export type CurrencySymbol = BuiltinByteString; +export type TokenName = BuiltinByteString; +export type MaybeStakingHash = + | ConStr1<[]> + | ConStr0<[ConStr0<[ConStr0<[BuiltinByteString]>]>]>; +export type PubKeyAddress = ConStr0<[ConStr0<[PubKeyHash]>, MaybeStakingHash]>; +export type ScriptAddress = ConStr0< + [ConStr1<[ValidatorHash]>, MaybeStakingHash] +>; +export type AssetClass = ConStr0<[CurrencySymbol, TokenName]>; +export type TxOutRef = ConStr0<[ConStr0<[BuiltinByteString]>, Integer]>; +export type AssocMapItem = { k: K; v: V }; +export type DictItem = { k: K; v: V }; +export type AssocMap = { map: AssocMapItem[] }; +export type Dict = { map: DictItem[] }; +export type Tuple = ConStr0<[K, V]>; +export type Value = AssocMap>; +export type PlutusData = + | BuiltinByteString + | Integer + | MaybeStakingHash + | PubKeyAddress + | ScriptAddress + | AssetClass + | PaymentPubKeyHash + | PubKeyHash + | POSIXTime + | TxOutRef; + +export const conStr = (constructor: N, fields: T): ConStr => ({ + constructor, + fields, +}); +export const conStr0 = (fields: T): ConStr0 => conStr<0, T>(0, fields); +export const conStr1 = (fields: T): ConStr1 => conStr<1, T>(1, fields); +export const conStr2 = (fields: T): ConStr2 => conStr<2, T>(2, fields); +export const bool = (b: boolean): Bool => + b ? conStr1<[]>([]) : conStr0<[]>([]); +export const builtinByteString = (bytes: string): BuiltinByteString => ({ + bytes, +}); +export const integer = (int: number): Integer => ({ int }); +export const list = (pList: PlutusData[]): List => ({ list: pList }); +export const currencySymbol = (bytes: string): CurrencySymbol => + builtinByteString(bytes); +export const tokenName = (bytes: string): TokenName => builtinByteString(bytes); +export const maybeStakingHash = (stakeCredential: string): MaybeStakingHash => { + if (stakeCredential === '') { + return conStr1<[]>([]); + } + return conStr0<[ConStr0<[ConStr0<[BuiltinByteString]>]>]>([ + conStr0([conStr0([builtinByteString(stakeCredential)])]), + ]); +}; +export const pubKeyAddress = ( + bytes: string, + stakeCredential?: string +): PubKeyAddress => + conStr0([ + conStr0([builtinByteString(bytes)]), + maybeStakingHash(stakeCredential || ''), + ]); +export const scriptAddress = ( + bytes: string, + stakeCredential?: string +): ScriptAddress => + conStr0([ + conStr1([builtinByteString(bytes)]), + maybeStakingHash(stakeCredential || ''), + ]); +export const assetClass = (policyId: string, assetName: string): AssetClass => + conStr0([currencySymbol(policyId), tokenName(assetName)]); + +export const txOutRef = (txHash: string, index: number): TxOutRef => + conStr0([conStr0([builtinByteString(txHash)]), integer(index)]); +export const paymentPubKeyHash = (bytes: string): PaymentPubKeyHash => + builtinByteString(bytes); +export const pubKeyHash = (bytes: string): PubKeyHash => + builtinByteString(bytes); +export const posixTime = (int: number): POSIXTime => ({ int }); +export const assocMap = (itemsMap: [K, V][]): AssocMap => ({ + map: itemsMap.map(([k, v]) => ({ k, v })), +}); +export const dict = (itemsMap: [K, V][]): AssocMap => ({ + map: itemsMap.map(([k, v]) => ({ k, v })), +}); +export const tuple = (key: K, value: V): Tuple => + conStr0([key, value]); +export const value = (assets: Asset[]): Value => { + const valueMapToParse: [CurrencySymbol, AssocMap][] = []; + const valueMap: { [key: string]: { [key: string]: number } } = {}; + + assets.forEach((asset) => { + const sanitizedName = asset.unit.replace('lovelace', ''); + const policy = sanitizedName.slice(0, 56) || ''; + const token = sanitizedName.slice(56) || ''; + + if (!valueMap[policy]) { + valueMap[policy] = {}; + } + + if (!valueMap[policy][token]) { + valueMap[policy][token] = Number(asset.quantity); + } else { + valueMap[policy][token] += Number(asset.quantity); + } + }); + + Object.keys(valueMap).forEach((policy) => { + const policyByte = currencySymbol(policy); + const tokens: [TokenName, Integer][] = Object.keys(valueMap[policy]).map( + (name) => [tokenName(name), integer(valueMap[policy][name])] + ); + + const policyMap = assocMap(tokens); + valueMapToParse.push([policyByte, policyMap]); + }); + + return assocMap(valueMapToParse); +}; + +export const parsePlutusValueToAssets = (plutusValue: Value): Asset[] => { + const assets: Asset[] = []; + + plutusValue.map.forEach((policyMap) => { + const policy = policyMap.k.bytes; + policyMap.v.map.forEach((tokenMap) => { + const token = tokenMap.k.bytes; + const quantity = tokenMap.v.int.toString(); + const unsanitizedUnit = policy + token; + const unit = unsanitizedUnit === '' ? 'lovelace' : unsanitizedUnit; + assets.push({ unit, quantity }); + }); + }); + + return assets; +}; diff --git a/packages/module/src/common/helpers/readPlutusData.ts b/packages/module/src/common/helpers/readPlutusData.ts index 37c6fd601..0f2b96e4f 100644 --- a/packages/module/src/common/helpers/readPlutusData.ts +++ b/packages/module/src/common/helpers/readPlutusData.ts @@ -1,7 +1,5 @@ -import { - deserializePlutusData, fromPlutusData, -} from '@mesh/common/utils'; -import type { Data } from '@mesh/common/types'; +import { deserializePlutusData, fromPlutusData } from '@mesh/common/utils'; +import type { Data } from '@mesh/types'; export const readPlutusData = (plutusData: string): Data => { return fromPlutusData(deserializePlutusData(plutusData)); diff --git a/packages/module/src/common/index.ts b/packages/module/src/common/index.ts new file mode 100644 index 000000000..370767922 --- /dev/null +++ b/packages/module/src/common/index.ts @@ -0,0 +1 @@ +export * from './data'; diff --git a/packages/module/src/common/types/Era.ts b/packages/module/src/common/types/Era.ts deleted file mode 100644 index 91f2c824b..000000000 --- a/packages/module/src/common/types/Era.ts +++ /dev/null @@ -1,3 +0,0 @@ -export type Era = - | 'ALONZO' - | 'BABBAGE'; diff --git a/packages/module/src/common/types/PlutusScript.ts b/packages/module/src/common/types/PlutusScript.ts deleted file mode 100644 index f6f7aad1b..000000000 --- a/packages/module/src/common/types/PlutusScript.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { LANGUAGE_VERSIONS } from '../constants'; - -export type PlutusScript = { - version: LanguageVersion; - code: string; -}; - -export type LanguageVersion = - keyof typeof LANGUAGE_VERSIONS; diff --git a/packages/module/src/common/types/Recipient.ts b/packages/module/src/common/types/Recipient.ts deleted file mode 100644 index 24b57f330..000000000 --- a/packages/module/src/common/types/Recipient.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Data } from './Data'; -import { NativeScript } from './NativeScript'; -import { PlutusScript } from './PlutusScript'; - -export type Recipient = string | { - address: string; - datum?: { - value: Data; - inline?: boolean; - }; - script?: PlutusScript | NativeScript; -}; diff --git a/packages/module/src/common/utils/builder.ts b/packages/module/src/common/utils/builder.ts index ac496c99e..e317a9092 100644 --- a/packages/module/src/common/utils/builder.ts +++ b/packages/module/src/common/utils/builder.ts @@ -1,55 +1,68 @@ import { csl } from '@mesh/core'; import { - DEFAULT_PROTOCOL_PARAMETERS, DEFAULT_REDEEMER_BUDGET, LANGUAGE_VERSIONS, + DEFAULT_PROTOCOL_PARAMETERS, + DEFAULT_REDEEMER_BUDGET, + LANGUAGE_VERSIONS, } from '@mesh/common/constants'; import { - fromScriptRef, fromUTF8, toAddress, toBytes, - toPlutusData, toRedeemer, toScriptRef, - toTxUnspentOutput, toUnitInterval, + fromScriptRef, + fromUTF8, + toAddress, + toBytes, + toPlutusData, + toRedeemer, + toScriptRef, + toTxUnspentOutput, + toUnitInterval, } from './converter'; import type { - BaseAddress, Bip32PrivateKey, DataCost, DatumSource, - Ed25519KeyHash, EnterpriseAddress, MintWitness, - PlutusScriptSource, RewardAddress, TransactionBuilder, - TransactionOutputBuilder, TransactionUnspentOutput, TxInputsBuilder, + BaseAddress, + Bip32PrivateKey, + DataCost, + DatumSource, + Ed25519KeyHash, + EnterpriseAddress, + MintWitness, + PlutusScriptSource, + RewardAddress, + TransactionBuilder, + TransactionOutputBuilder, + TransactionUnspentOutput, + TxInputsBuilder, } from '@mesh/core'; -import type { - Action, Data, PlutusScript, Recipient, UTxO, -} from '@mesh/common/types'; +import type { Action, Data, PlutusScript, Recipient, UTxO } from '@mesh/types'; import { - deserializeNativeScript, deserializePlutusScript, + deserializeNativeScript, + deserializePlutusScript, } from './deserializer'; export const buildBaseAddress = ( networkId: number, paymentKeyHash: Ed25519KeyHash, - stakeKeyHash: Ed25519KeyHash, + stakeKeyHash: Ed25519KeyHash ): BaseAddress => { - return csl.BaseAddress.new(networkId, + return csl.BaseAddress.new( + networkId, csl.StakeCredential.from_keyhash(paymentKeyHash), - csl.StakeCredential.from_keyhash(stakeKeyHash), + csl.StakeCredential.from_keyhash(stakeKeyHash) ); }; export const buildBip32PrivateKey = ( - entropy: string, password = '', + entropy: string, + password = '' ): Bip32PrivateKey => { return csl.Bip32PrivateKey.from_bip39_entropy( - toBytes(entropy), toBytes(fromUTF8(password)) + toBytes(entropy), + toBytes(fromUTF8(password)) ); }; -export const buildDataCost = ( - coinsPerByte: string, -): DataCost => { - return csl.DataCost.new_coins_per_byte( - csl.BigNum.from_str(coinsPerByte), - ); +export const buildDataCost = (coinsPerByte: string): DataCost => { + return csl.DataCost.new_coins_per_byte(csl.BigNum.from_str(coinsPerByte)); }; -export const buildDatumSource = ( - datum: Data | UTxO, -): DatumSource => { +export const buildDatumSource = (datum: Data | UTxO): DatumSource => { if (typeof datum !== 'object' || !('input' in datum)) { return csl.DatumSource.new(toPlutusData(datum)); } @@ -60,15 +73,17 @@ export const buildDatumSource = ( } throw new Error( - `No inline datum found in UTxO: ${utxo.input().transaction_id().to_hex()}`, + `No inline datum found in UTxO: ${utxo.input().transaction_id().to_hex()}` ); }; export const buildEnterpriseAddress = ( - networkId: number, paymentKeyHash: Ed25519KeyHash, + networkId: number, + paymentKeyHash: Ed25519KeyHash ): EnterpriseAddress => { - return csl.EnterpriseAddress.new(networkId, - csl.StakeCredential.from_keyhash(paymentKeyHash), + return csl.EnterpriseAddress.new( + networkId, + csl.StakeCredential.from_keyhash(paymentKeyHash) ); }; @@ -79,8 +94,9 @@ export const buildGeneralTxMetadata = (metadata: Record) => { generalTxMetadata.insert( csl.BigNum.from_str(MetadataLabel), csl.encode_json_str_to_metadatum( - JSON.stringify(Metadata), csl.MetadataJsonSchema.NoConversions, - ), + JSON.stringify(Metadata), + csl.MetadataJsonSchema.NoConversions + ) ); }); @@ -89,47 +105,49 @@ export const buildGeneralTxMetadata = (metadata: Record) => { export const buildMintWitness = ( script: string | PlutusScript | UTxO, - redeemer?: Partial, + redeemer?: Partial ): MintWitness => { if (typeof script === 'string') { - return csl.MintWitness.new_native_script( - deserializeNativeScript(script), - ); + return csl.MintWitness.new_native_script(deserializeNativeScript(script)); } if (redeemer === undefined) throw new Error('Minting with plutus requires a redeemer to be defined'); if (redeemer.tag !== 'MINT') - throw new Error('Minting redeemer\'s tag must be defined as \'MINT\''); + throw new Error("Minting redeemer's tag must be defined as 'MINT'"); return csl.MintWitness.new_plutus_script( - buildPlutusScriptSource(script), toRedeemer({ - tag: 'MINT', index: 0, + buildPlutusScriptSource(script), + toRedeemer({ + tag: 'MINT', + index: 0, budget: DEFAULT_REDEEMER_BUDGET, data: { alternative: 0, fields: [], }, ...redeemer, - }), + }) ); }; export const buildRewardAddress = ( - networkId: number, stakeKeyHash: Ed25519KeyHash, + networkId: number, + stakeKeyHash: Ed25519KeyHash ): RewardAddress => { - return csl.RewardAddress.new(networkId, - csl.StakeCredential.from_keyhash(stakeKeyHash), + return csl.RewardAddress.new( + networkId, + csl.StakeCredential.from_keyhash(stakeKeyHash) ); }; export const buildPlutusScriptSource = ( - script: PlutusScript | UTxO, + script: PlutusScript | UTxO ): PlutusScriptSource => { if ('code' in script) { return csl.PlutusScriptSource.new( - deserializePlutusScript(script.code, script.version), + deserializePlutusScript(script.code, script.version) ); } @@ -140,17 +158,23 @@ export const buildPlutusScriptSource = ( if (scriptRef.is_plutus_script()) { const plutusScript = fromScriptRef(scriptRef) as PlutusScript; const scriptHash = deserializePlutusScript( - plutusScript.code, plutusScript.version, + plutusScript.code, + plutusScript.version ).hash(); return csl.PlutusScriptSource.new_ref_input_with_lang_ver( - scriptHash, utxo.input(), LANGUAGE_VERSIONS[plutusScript.version], + scriptHash, + utxo.input(), + LANGUAGE_VERSIONS[plutusScript.version] ); } } throw new Error( - `No plutus script reference found in UTxO: ${utxo.input().transaction_id().to_hex()}`, + `No plutus script reference found in UTxO: ${utxo + .input() + .transaction_id() + .to_hex()}` ); }; @@ -172,7 +196,7 @@ export const buildTimelockStart = (slot: string) => { }; export const buildTxBuilder = ( - parameters = DEFAULT_PROTOCOL_PARAMETERS, + parameters = DEFAULT_PROTOCOL_PARAMETERS ): TransactionBuilder => { const txBuilderConfig = csl.TransactionBuilderConfigBuilder.new() .coins_per_utxo_byte(csl.BigNum.from_str(parameters.coinsPerUTxOSize)) @@ -197,15 +221,13 @@ export const buildTxBuilder = ( return csl.TransactionBuilder.new(txBuilderConfig); }; -export const buildTxInputsBuilder = ( - utxos: unknown[], -): TxInputsBuilder => { +export const buildTxInputsBuilder = (utxos: unknown[]): TxInputsBuilder => { const txInputsBuilder = csl.TxInputsBuilder.new(); utxos .map((utxo) => { return utxo instanceof csl.TransactionUnspentOutput - ? utxo as TransactionUnspentOutput + ? (utxo as TransactionUnspentOutput) : toTxUnspentOutput(utxo as UTxO); }) .forEach((utxo) => { @@ -220,35 +242,36 @@ export const buildTxInputsBuilder = ( }; export const buildTxOutputBuilder = ( - recipient: Recipient, + recipient: Recipient ): TransactionOutputBuilder => { if (typeof recipient === 'string') { - return csl.TransactionOutputBuilder.new() - .with_address(toAddress(recipient)); + return csl.TransactionOutputBuilder.new().with_address( + toAddress(recipient) + ); } - let txOutputBuilder = csl.TransactionOutputBuilder.new() - .with_address(toAddress(recipient.address)); + let txOutputBuilder = csl.TransactionOutputBuilder.new().with_address( + toAddress(recipient.address) + ); if (recipient.datum) { const { value, inline } = recipient.datum; const plutusData = toPlutusData(value); - txOutputBuilder = txOutputBuilder - .with_data_hash(csl.hash_plutus_data(plutusData)); + txOutputBuilder = txOutputBuilder.with_data_hash( + csl.hash_plutus_data(plutusData) + ); if (inline) { - txOutputBuilder = txOutputBuilder - .with_plutus_data(plutusData); + txOutputBuilder = txOutputBuilder.with_plutus_data(plutusData); } } if (recipient.script) { const reference = toScriptRef(recipient.script); - txOutputBuilder = txOutputBuilder - .with_script_ref(reference); + txOutputBuilder = txOutputBuilder.with_script_ref(reference); } return txOutputBuilder; diff --git a/packages/module/src/common/utils/converter.ts b/packages/module/src/common/utils/converter.ts index f4962aa52..301a5e333 100644 --- a/packages/module/src/common/utils/converter.ts +++ b/packages/module/src/common/utils/converter.ts @@ -31,7 +31,7 @@ import type { PoolParams, Relay, UTxO, -} from '@mesh/common/types'; +} from '@mesh/types'; /* -----------------[ Address ]----------------- */ diff --git a/packages/module/src/common/utils/deserializer.ts b/packages/module/src/common/utils/deserializer.ts index 8b6d0d048..333502a11 100644 --- a/packages/module/src/common/utils/deserializer.ts +++ b/packages/module/src/common/utils/deserializer.ts @@ -1,57 +1,61 @@ import { csl } from '@mesh/core'; import { LANGUAGE_VERSIONS } from '@mesh/common/constants'; import { toBytes } from './converter'; -import type { LanguageVersion } from '@mesh/common/types'; +import type { LanguageVersion } from '@mesh/types'; -export const deserializeAddress = (address: string) => csl.Address - .from_bytes(toBytes(address)); +export const deserializeAddress = (address: string) => + csl.Address.from_bytes(toBytes(address)); -export const deserializeBip32PrivateKey = (bip32PrivateKey: string) => csl.Bip32PrivateKey - .from_bytes(toBytes(bip32PrivateKey)); +export const deserializeBip32PrivateKey = (bip32PrivateKey: string) => + csl.Bip32PrivateKey.from_bytes(toBytes(bip32PrivateKey)); -export const deserializeDataHash = (dataHash: string) => csl.DataHash - .from_bytes(toBytes(dataHash)); +export const deserializeDataHash = (dataHash: string) => + csl.DataHash.from_bytes(toBytes(dataHash)); -export const deserializeEd25519KeyHash = (ed25519KeyHash: string) => csl.Ed25519KeyHash - .from_bytes(toBytes(ed25519KeyHash)); +export const deserializeEd25519KeyHash = (ed25519KeyHash: string) => + csl.Ed25519KeyHash.from_bytes(toBytes(ed25519KeyHash)); -export const deserializeEd25519Signature = (ed25519Signature: string) => csl.Ed25519Signature - .from_bytes(toBytes(ed25519Signature)); +export const deserializeEd25519Signature = (ed25519Signature: string) => + csl.Ed25519Signature.from_bytes(toBytes(ed25519Signature)); -export const deserializeNativeScript = (nativeScript: string) => csl.NativeScript - .from_bytes(toBytes(nativeScript)); +export const deserializeNativeScript = (nativeScript: string) => + csl.NativeScript.from_bytes(toBytes(nativeScript)); -export const deserializePublicKey = (publicKey: string) => csl.PublicKey - .from_bytes(toBytes(publicKey)); +export const deserializePublicKey = (publicKey: string) => + csl.PublicKey.from_bytes(toBytes(publicKey)); -export const deserializePlutusData = (plutusData: string) => csl.PlutusData - .from_bytes(toBytes(plutusData)); +export const deserializePlutusData = (plutusData: string) => + csl.PlutusData.from_bytes(toBytes(plutusData)); export const deserializePlutusScript = ( - plutusScript: string, version: LanguageVersion, -) => csl.PlutusScript - .from_bytes_with_version(toBytes(plutusScript), LANGUAGE_VERSIONS[version]); + plutusScript: string, + version: LanguageVersion +) => + csl.PlutusScript.from_bytes_with_version( + toBytes(plutusScript), + LANGUAGE_VERSIONS[version] + ); -export const deserializeScriptRef = (scriptRef: string) => csl.ScriptRef - .from_bytes(toBytes(scriptRef)); +export const deserializeScriptRef = (scriptRef: string) => + csl.ScriptRef.from_bytes(toBytes(scriptRef)); -export const deserializeScriptHash = (scriptHash: string) => csl.ScriptHash - .from_bytes(toBytes(scriptHash)); +export const deserializeScriptHash = (scriptHash: string) => + csl.ScriptHash.from_bytes(toBytes(scriptHash)); -export const deserializeTx = (tx: string) => csl.Transaction - .from_bytes(toBytes(tx)); +export const deserializeTx = (tx: string) => + csl.Transaction.from_bytes(toBytes(tx)); -export const deserializeTxBody = (txBody: string) => csl.TransactionBody - .from_bytes(toBytes(txBody)); +export const deserializeTxBody = (txBody: string) => + csl.TransactionBody.from_bytes(toBytes(txBody)); -export const deserializeTxHash = (txHash: string) => csl.TransactionHash - .from_bytes(toBytes(txHash)); +export const deserializeTxHash = (txHash: string) => + csl.TransactionHash.from_bytes(toBytes(txHash)); -export const deserializeTxUnspentOutput = (txUnspentOutput: string) => csl.TransactionUnspentOutput - .from_bytes(toBytes(txUnspentOutput)); +export const deserializeTxUnspentOutput = (txUnspentOutput: string) => + csl.TransactionUnspentOutput.from_bytes(toBytes(txUnspentOutput)); -export const deserializeTxWitnessSet = (txWitnessSet: string) => csl.TransactionWitnessSet - .from_bytes(toBytes(txWitnessSet)); +export const deserializeTxWitnessSet = (txWitnessSet: string) => + csl.TransactionWitnessSet.from_bytes(toBytes(txWitnessSet)); -export const deserializeValue = (value: string) => csl.Value - .from_bytes(toBytes(value)); +export const deserializeValue = (value: string) => + csl.Value.from_bytes(toBytes(value)); diff --git a/packages/module/src/common/utils/resolver.ts b/packages/module/src/common/utils/resolver.ts index 679a68fef..096fa1444 100644 --- a/packages/module/src/common/utils/resolver.ts +++ b/packages/module/src/common/utils/resolver.ts @@ -1,21 +1,30 @@ import { mnemonicToEntropy } from 'bip39'; import { AssetFingerprint, csl } from '@mesh/core'; import { - SUPPORTED_CLOCKS, DEFAULT_PROTOCOL_PARAMETERS, SUPPORTED_LANGUAGE_VIEWS, + SUPPORTED_CLOCKS, + DEFAULT_PROTOCOL_PARAMETERS, + SUPPORTED_LANGUAGE_VIEWS, } from '@mesh/common/constants'; +import { buildBip32PrivateKey, buildRewardAddress } from './builder'; import { - buildBip32PrivateKey, buildRewardAddress, -} from './builder'; -import { - toAddress, toBaseAddress, toBytes, toEnterpriseAddress, - toNativeScript, toPlutusData, toRewardAddress, toScriptRef, + toAddress, + toBaseAddress, + toBytes, + toEnterpriseAddress, + toNativeScript, + toPlutusData, + toRewardAddress, + toScriptRef, } from './converter'; -import { - deserializePlutusScript, deserializeTx, -} from './deserializer'; +import { deserializePlutusScript, deserializeTx } from './deserializer'; import type { - Data, Era, LanguageVersion, NativeScript, Network, PlutusScript, -} from '@mesh/common/types'; + Data, + Era, + LanguageVersion, + NativeScript, + Network, + PlutusScript, +} from '@mesh/types'; export const resolveDataHash = (data: Data) => { const plutusData = toPlutusData(data); @@ -25,17 +34,17 @@ export const resolveDataHash = (data: Data) => { export const resolveEpochNo = (network: Network, milliseconds = Date.now()) => { if (SUPPORTED_CLOCKS[network]) { - const [ - epoch, _, systemStart, epochLength, - ] = SUPPORTED_CLOCKS[network]; - - return parseInt(csl.BigNum - .from_str(milliseconds.toString()) - .div_floor(csl.BigNum.from_str('1000')) - .checked_sub(csl.BigNum.from_str(systemStart)) - .div_floor(csl.BigNum.from_str(epochLength)) - .checked_add(csl.BigNum.from_str(epoch)) - .to_str(), 10); + const [epoch, _, systemStart, epochLength] = SUPPORTED_CLOCKS[network]; + + return parseInt( + csl.BigNum.from_str(milliseconds.toString()) + .div_floor(csl.BigNum.from_str('1000')) + .checked_sub(csl.BigNum.from_str(systemStart)) + .div_floor(csl.BigNum.from_str(epochLength)) + .checked_add(csl.BigNum.from_str(epoch)) + .to_str(), + 10 + ); } throw new Error(`Couldn't resolve EpochNo for network: ${network}`); @@ -63,20 +72,27 @@ export const resolvePaymentKeyHash = (bech32: string) => { toEnterpriseAddress(bech32)?.payment_cred().to_keyhash(), ].find((kh) => kh !== undefined); - if (paymentKeyHash !== undefined) - return paymentKeyHash.to_hex(); + if (paymentKeyHash !== undefined) return paymentKeyHash.to_hex(); - throw new Error(`Couldn't resolve payment key hash from address: ${bech32}`); + throw new Error( + `Couldn't resolve payment key hash from address: ${bech32}` + ); } catch (error) { - throw new Error(`An error occurred during resolvePaymentKeyHash: ${error}.`); + throw new Error( + `An error occurred during resolvePaymentKeyHash: ${error}.` + ); } }; -export const resolvePlutusScriptAddress = (script: PlutusScript, networkId = 0) => { +export const resolvePlutusScriptAddress = ( + script: PlutusScript, + networkId = 0 +) => { const plutusScript = deserializePlutusScript(script.code, script.version); - const enterpriseAddress = csl.EnterpriseAddress.new(networkId, - csl.StakeCredential.from_scripthash(plutusScript.hash()), + const enterpriseAddress = csl.EnterpriseAddress.new( + networkId, + csl.StakeCredential.from_scripthash(plutusScript.hash()) ); return enterpriseAddress.to_address().to_bech32(); @@ -85,11 +101,9 @@ export const resolvePlutusScriptAddress = (script: PlutusScript, networkId = 0) export const resolvePlutusScriptHash = (bech32: string) => { try { const enterpriseAddress = toEnterpriseAddress(bech32); - const scriptHash = enterpriseAddress?.payment_cred() - .to_scripthash(); + const scriptHash = enterpriseAddress?.payment_cred().to_scripthash(); - if (scriptHash !== undefined) - return scriptHash.to_hex(); + if (scriptHash !== undefined) return scriptHash.to_hex(); throw new Error(`Couldn't resolve script hash from address: ${bech32}`); } catch (error) { @@ -119,8 +133,7 @@ export const resolveSlotNo = (network: Network, milliseconds = Date.now()) => { if (SUPPORTED_CLOCKS[network]) { const [_, slot, systemStart] = SUPPORTED_CLOCKS[network]; - return csl.BigNum - .from_str(milliseconds.toString()) + return csl.BigNum.from_str(milliseconds.toString()) .div_floor(csl.BigNum.from_str('1000')) .checked_sub(csl.BigNum.from_str(systemStart)) .checked_add(csl.BigNum.from_str(slot)) @@ -138,7 +151,8 @@ export const resolveRewardAddress = (bech32: string) => { if (stakeKeyHash !== undefined) return buildRewardAddress(address.network_id(), stakeKeyHash) - .to_address().to_bech32(); + .to_address() + .to_bech32(); throw new Error(`Couldn't resolve reward address from address: ${bech32}`); } catch (error) { @@ -153,8 +167,7 @@ export const resolveStakeKeyHash = (bech32: string) => { toRewardAddress(bech32)?.payment_cred().to_keyhash(), ].find((kh) => kh !== undefined); - if (stakeKeyHash !== undefined) - return stakeKeyHash.to_hex(); + if (stakeKeyHash !== undefined) return stakeKeyHash.to_hex(); throw new Error(`Couldn't resolve stake key hash from address: ${bech32}`); } catch (error) { @@ -165,11 +178,9 @@ export const resolveStakeKeyHash = (bech32: string) => { export const resolveTxFees = ( txSize: number, minFeeA = DEFAULT_PROTOCOL_PARAMETERS.minFeeA, - minFeeB = DEFAULT_PROTOCOL_PARAMETERS.minFeeB, + minFeeB = DEFAULT_PROTOCOL_PARAMETERS.minFeeB ) => { - const fees = BigInt(minFeeA) - * BigInt(txSize) - + BigInt(minFeeB); + const fees = BigInt(minFeeA) * BigInt(txSize) + BigInt(minFeeB); return fees.toString(); }; diff --git a/packages/module/src/core/CIP2.ts b/packages/module/src/core/CIP2.ts index bf8335f35..03c946f47 100644 --- a/packages/module/src/core/CIP2.ts +++ b/packages/module/src/core/CIP2.ts @@ -1,17 +1,16 @@ import { csl } from './CSL'; -import { - DEFAULT_PROTOCOL_PARAMETERS, -} from '@mesh/common/constants'; +import { DEFAULT_PROTOCOL_PARAMETERS } from '@mesh/common/constants'; import { resolveTxFees } from '@mesh/common/utils'; -import type { Protocol, Quantity, Unit, UTxO } from '@mesh/common/types'; +import type { Protocol, Quantity, Unit, UTxO } from '@mesh/types'; export const keepRelevant = ( - requestedOutputSet: Map, initialUTxOSet: UTxO[], - minimumLovelaceRequired = '5000000', + requestedOutputSet: Map, + initialUTxOSet: UTxO[], + minimumLovelaceRequired = '5000000' ) => { - const requestedLovelace = csl.BigNum - .from_str(requestedOutputSet.get('lovelace') ?? '0') - .checked_add(csl.BigNum.from_str(minimumLovelaceRequired)); + const requestedLovelace = csl.BigNum.from_str( + requestedOutputSet.get('lovelace') ?? '0' + ).checked_add(csl.BigNum.from_str(minimumLovelaceRequired)); const multiAsset = initialUTxOSet.filter((utxo) => utxo.output.amount @@ -30,45 +29,43 @@ export const keepRelevant = ( su.input.txHash === iu.input.txHash && su.input.outputIndex === iu.input.outputIndex ); - })) + }) + ) : []; - return [ - ...lovelace, - ...multiAsset, - ]; + return [...lovelace, ...multiAsset]; }; export const largestFirst = ( - lovelace: Quantity, initialUTxOSet: UTxO[], includeTxFees = false, - { maxTxSize, minFeeA, minFeeB } = DEFAULT_PROTOCOL_PARAMETERS, + lovelace: Quantity, + initialUTxOSet: UTxO[], + includeTxFees = false, + { maxTxSize, minFeeA, minFeeB } = DEFAULT_PROTOCOL_PARAMETERS ): UTxO[] => { const sortedUTxOs = initialUTxOSet .filter((utxo) => multiAssetUTxO(utxo) === false) .sort(largestLovelaceQuantity); const maxTxFees = csl.BigNum.from_str( - resolveTxFees(maxTxSize, minFeeA, minFeeB), + resolveTxFees(maxTxSize, minFeeA, minFeeB) ); const quantity = includeTxFees ? csl.BigNum.from_str(lovelace).checked_add(maxTxFees).to_str() : lovelace; - const requestedOutputSet = new Map([ - ['lovelace', quantity], - ]); + const requestedOutputSet = new Map([['lovelace', quantity]]); - const selection = selectValue( - sortedUTxOs, requestedOutputSet, - ); + const selection = selectValue(sortedUTxOs, requestedOutputSet); return selection; }; export const largestFirstMultiAsset = ( - requestedOutputSet: Map, initialUTxOSet: UTxO[], - includeTxFees = false, parameters = DEFAULT_PROTOCOL_PARAMETERS, + requestedOutputSet: Map, + initialUTxOSet: UTxO[], + includeTxFees = false, + parameters = DEFAULT_PROTOCOL_PARAMETERS ): UTxO[] => { const sortedMultiAssetUTxOs = initialUTxOSet .filter(multiAssetUTxO) @@ -83,48 +80,51 @@ export const largestFirstMultiAsset = ( requestedOutputSet.set('lovelace', quantity); - const selection = selectValue( - sortedMultiAssetUTxOs, - requestedOutputSet, - ); + const selection = selectValue(sortedMultiAssetUTxOs, requestedOutputSet); return selection; }; const enoughValueHasBeenSelected = ( - selection: UTxO[], assets: Map, + selection: UTxO[], + assets: Map ): boolean => { - return Array - .from( - assets, (asset) => ({ unit: asset[0], quantity: csl.BigNum.from_str(asset[1]) }), - ) - .every((asset) => { - return selection + return Array.from(assets, (asset) => ({ + unit: asset[0], + quantity: csl.BigNum.from_str(asset[1]), + })).every((asset) => { + return ( + selection .filter((utxo) => { - return utxo.output.amount - .find((a) => a.unit === asset.unit) !== undefined; + return ( + utxo.output.amount.find((a) => a.unit === asset.unit) !== undefined + ); }) .reduce((selectedQuantity, utxo) => { - const utxoQuantity = utxo.output.amount - .reduce( - (quantity, a) => quantity.checked_add(csl.BigNum.from_str(asset.unit === a.unit ? a.quantity : '0')), - csl.BigNum.from_str('0'), - ); + const utxoQuantity = utxo.output.amount.reduce( + (quantity, a) => + quantity.checked_add( + csl.BigNum.from_str(asset.unit === a.unit ? a.quantity : '0') + ), + csl.BigNum.from_str('0') + ); return selectedQuantity.checked_add(utxoQuantity); - }, csl.BigNum.from_str('0')).less_than(asset.quantity) === false; - }); + }, csl.BigNum.from_str('0')) + .less_than(asset.quantity) === false + ); + }); }; -const largestLovelaceQuantity = ( - utxoA: UTxO, utxoB: UTxO, -): number => { +const largestLovelaceQuantity = (utxoA: UTxO, utxoB: UTxO): number => { const aLovelaceQuantity = csl.BigNum.from_str( - utxoA.output.amount.find((asset) => asset.unit === 'lovelace')?.quantity ?? '0', + utxoA.output.amount.find((asset) => asset.unit === 'lovelace')?.quantity ?? + '0' ); const bLovelaceQuantity = csl.BigNum.from_str( - utxoB.output.amount.find((asset) => asset.unit === 'lovelace')?.quantity ?? '0', + utxoB.output.amount.find((asset) => asset.unit === 'lovelace')?.quantity ?? + '0' ); return bLovelaceQuantity.compare(aLovelaceQuantity); @@ -133,20 +133,16 @@ const largestLovelaceQuantity = ( const maxTxFees = (parameters: Protocol) => { const { maxTxSize, minFeeA, minFeeB } = parameters; - return csl.BigNum.from_str( - resolveTxFees(maxTxSize, minFeeA, minFeeB), - ); + return csl.BigNum.from_str(resolveTxFees(maxTxSize, minFeeA, minFeeB)); }; -const multiAssetUTxO = ( - utxo: UTxO, -): boolean => utxo.output.amount.length > 1; +const multiAssetUTxO = (utxo: UTxO): boolean => utxo.output.amount.length > 1; const selectedLovelaceQuantity = (multiAsset: UTxO[]) => { return multiAsset.reduce((sum, utxo) => { - const lovelace = utxo.output.amount.find( - (asset) => asset.unit === 'lovelace' - )?.quantity ?? '0'; + const lovelace = + utxo.output.amount.find((asset) => asset.unit === 'lovelace')?.quantity ?? + '0'; return sum.checked_add(csl.BigNum.from_str(lovelace)); }, csl.BigNum.from_str('0')); @@ -155,13 +151,9 @@ const selectedLovelaceQuantity = (multiAsset: UTxO[]) => { const remainingLovelace = (quantity: Quantity, initialUTxOSet: UTxO[]) => { const sortedUTxOs = initialUTxOSet.sort(largestLovelaceQuantity); - const requestedOutputSet = new Map([ - ['lovelace', quantity], - ]); + const requestedOutputSet = new Map([['lovelace', quantity]]); - const selection = selectValue( - sortedUTxOs, requestedOutputSet, - ); + const selection = selectValue(sortedUTxOs, requestedOutputSet); return selection; }; @@ -169,33 +161,32 @@ const remainingLovelace = (quantity: Quantity, initialUTxOSet: UTxO[]) => { const selectValue = ( inputUTxO: UTxO[], outputSet: Map, - selection: UTxO[] = [], + selection: UTxO[] = [] ): UTxO[] => { if ( - inputUTxO.length === 0 - || enoughValueHasBeenSelected(selection, outputSet) + inputUTxO.length === 0 || + enoughValueHasBeenSelected(selection, outputSet) ) { return selection; } if (valueCanBeSelected(inputUTxO[0], outputSet)) { - return selectValue( - inputUTxO.slice(1), outputSet, - [...selection, inputUTxO[0]], - ); + return selectValue(inputUTxO.slice(1), outputSet, [ + ...selection, + inputUTxO[0], + ]); } - return selectValue( - inputUTxO.slice(1), - outputSet, selection, - ); + return selectValue(inputUTxO.slice(1), outputSet, selection); }; const valueCanBeSelected = ( - utxo: UTxO, assets: Map, + utxo: UTxO, + assets: Map ): boolean => { return Array.from(assets.keys()).some((unit) => { - return utxo.output.amount - .find((asset) => asset.unit === unit) !== undefined; + return ( + utxo.output.amount.find((asset) => asset.unit === unit) !== undefined + ); }); }; diff --git a/packages/module/src/core/CIP8.ts b/packages/module/src/core/CIP8.ts index 4ce0bd7c6..f2e635dd4 100644 --- a/packages/module/src/core/CIP8.ts +++ b/packages/module/src/core/CIP8.ts @@ -1,18 +1,32 @@ import { - AlgorithmId, BigNum, COSESign1Builder, - COSESign1, CBORValue, COSEKey, HeaderMap, - Headers, Int, KeyType, Label, ProtectedHeaderMap, + AlgorithmId, + BigNum, + COSESign1Builder, + COSESign1, + CBORValue, + COSEKey, + HeaderMap, + Headers, + Int, + KeyType, + Label, + ProtectedHeaderMap, } from '@emurgo/cardano-message-signing-nodejs'; import { - deserializeAddress, deserializeEd25519Signature, - deserializePublicKey, fromBytes, fromUTF8, - resolveStakeKeyHash, toBytes, + deserializeAddress, + deserializeEd25519Signature, + deserializePublicKey, + fromBytes, + fromUTF8, + resolveStakeKeyHash, + toBytes, } from '@mesh/common/utils'; -import type { DataSignature } from '@mesh/common/types'; +import type { DataSignature } from '@mesh/types'; import type { Address, PrivateKey, PublicKey } from '@mesh/core'; export const signMessage = ( - message: Message, signer: Signer, + message: Message, + signer: Signer ): { coseKey: string; coseSign1: string } => { const coseKey = createCOSEKey(signer); const coseSign1 = createCOSESign1(message, signer); @@ -24,8 +38,9 @@ export const signMessage = ( }; export const checkSignature = ( - message: string, signer: string, - { key, signature }: DataSignature, + message: string, + signer: string, + { key, signature }: DataSignature ) => { const coseKey = COSEKey.from_bytes(toBytes(key)); const coseSign1 = COSESign1.from_bytes(toBytes(signature)); @@ -37,34 +52,35 @@ export const checkSignature = ( if (signer?.length > 0) { const protectedHeaders = coseSign1 - .headers().protected() + .headers() + .protected() .deserialized_headers(); const signerAddress = protectedHeaders - .header(Label.new_text('address'))?.as_bytes(); + .header(Label.new_text('address')) + ?.as_bytes(); if (signerAddress === undefined) { - throw new Error('Couldn\'t find a signer address in signature'); + throw new Error("Couldn't find a signer address in signature"); } const signerKey = coseKey - .header( - Label.new_int(Int.new_negative(BigNum.from_str('2'))), - )?.as_bytes(); + .header(Label.new_int(Int.new_negative(BigNum.from_str('2')))) + ?.as_bytes(); if (signerKey === undefined) { - throw new Error('Couldn\'t find a signer key in signature'); + throw new Error("Couldn't find a signer key in signature"); } const address = deserializeAddress(fromBytes(signerAddress)); const publicKey = deserializePublicKey(fromBytes(signerKey)); if (checkAddress(signer, address, publicKey) === false) { - throw new Error('Couldn\'t check signature because of address mismatch'); + throw new Error("Couldn't check signature because of address mismatch"); } const ed25519Signature = deserializeEd25519Signature( - fromBytes(coseSign1.signature()), + fromBytes(coseSign1.signature()) ); const data = coseSign1.signed_data().to_bytes(); @@ -77,10 +93,9 @@ export const checkSignature = ( const checkAddress = ( signer: string, address: Address, - publicKey: PublicKey, + publicKey: PublicKey ) => { - if (signer !== address.to_bech32()) - return false; + if (signer !== address.to_bech32()) return false; try { const keyHash = resolveStakeKeyHash(signer); @@ -91,22 +106,18 @@ const checkAddress = ( }; const createCOSEKey = (signer: Signer) => { - const coseKey = COSEKey.new( - Label.from_key_type(KeyType.OKP), - ); + const coseKey = COSEKey.new(Label.from_key_type(KeyType.OKP)); - coseKey.set_algorithm_id( - Label.from_algorithm_id(AlgorithmId.EdDSA), - ); + coseKey.set_algorithm_id(Label.from_algorithm_id(AlgorithmId.EdDSA)); coseKey.set_header( Label.new_int(Int.new_negative(BigNum.from_str('1'))), - CBORValue.new_int(Int.new_i32(6)), + CBORValue.new_int(Int.new_i32(6)) ); coseKey.set_header( Label.new_int(Int.new_negative(BigNum.from_str('2'))), - CBORValue.new_bytes(signer.key.to_public().as_bytes()), + CBORValue.new_bytes(signer.key.to_public().as_bytes()) ); return coseKey; @@ -116,28 +127,26 @@ const createCOSESign1 = (message: Message, signer: Signer) => { const protectedHeaders = HeaderMap.new(); const unprotectedHeaders = HeaderMap.new(); - protectedHeaders.set_algorithm_id( - Label.from_algorithm_id(AlgorithmId.EdDSA), - ); + protectedHeaders.set_algorithm_id(Label.from_algorithm_id(AlgorithmId.EdDSA)); protectedHeaders.set_header( Label.new_text('address'), - CBORValue.new_bytes(signer.address.to_bytes()), + CBORValue.new_bytes(signer.address.to_bytes()) ); const headers = Headers.new( ProtectedHeaderMap.new(protectedHeaders), - unprotectedHeaders, + unprotectedHeaders ); const coseSign1Builder = COSESign1Builder.new( - headers, toBytes(message.payload), false, + headers, + toBytes(message.payload), + false ); if (message.externalAAD !== undefined) { - coseSign1Builder.set_external_aad( - toBytes(message.externalAAD), - ); + coseSign1Builder.set_external_aad(toBytes(message.externalAAD)); } const dataToSign = coseSign1Builder.make_data_to_sign(); diff --git a/packages/module/src/core/CPS0009.ts b/packages/module/src/core/CPS0009.ts index cc03c8f06..210f58e25 100644 --- a/packages/module/src/core/CPS0009.ts +++ b/packages/module/src/core/CPS0009.ts @@ -1,4 +1,4 @@ -import type { Quantity, UTxO, Unit } from '@mesh/common/types'; +import type { Quantity, UTxO, Unit } from '@mesh/types'; export const selectUtxos = ( inputs: UTxO[], diff --git a/packages/module/src/core/CSL.ts b/packages/module/src/core/CSL.ts index 6f8d8572d..7e71ccd16 100644 --- a/packages/module/src/core/CSL.ts +++ b/packages/module/src/core/CSL.ts @@ -1,6 +1,6 @@ -import { csl } from '.'; +import { csl } from '@meshsdk/mesh-csl'; -export * as csl from '@emurgo/cardano-serialization-lib-nodejs'; +export { csl, applyParamsToScript } from '@meshsdk/mesh-csl'; export type Address = InstanceType; export type AssetName = InstanceType; @@ -35,11 +35,15 @@ export type Ed25519Signature = InstanceType; export type EnterpriseAddress = InstanceType; export type ExUnitPrices = InstanceType; export type ExUnits = InstanceType; -export type GeneralTransactionMetadata = InstanceType; +export type GeneralTransactionMetadata = InstanceType< + typeof csl.GeneralTransactionMetadata +>; export type GenesisDelegateHash = InstanceType; export type GenesisHash = InstanceType; export type GenesisHashes = InstanceType; -export type GenesisKeyDelegation = InstanceType; +export type GenesisKeyDelegation = InstanceType< + typeof csl.GenesisKeyDelegation +>; export type Header = InstanceType; export type HeaderBody = InstanceType; export type Int = InstanceType; @@ -49,9 +53,13 @@ export type KESSignature = InstanceType; export type KESVKey = InstanceType; export type Language = InstanceType; export type Languages = InstanceType; -export type LegacyDaedalusPrivateKey = InstanceType; +export type LegacyDaedalusPrivateKey = InstanceType< + typeof csl.LegacyDaedalusPrivateKey +>; export type LinearFee = InstanceType; -export type MIRToStakeCredentials = InstanceType; +export type MIRToStakeCredentials = InstanceType< + typeof csl.MIRToStakeCredentials +>; export type MetadataList = InstanceType; export type MetadataMap = InstanceType; export type Mint = InstanceType; @@ -59,8 +67,12 @@ export type MintAssets = InstanceType; export type MintBuilder = InstanceType; export type MintWitness = InstanceType; export type MintsAssets = InstanceType; -export type MoveInstantaneousReward = InstanceType; -export type MoveInstantaneousRewardsCert = InstanceType; +export type MoveInstantaneousReward = InstanceType< + typeof csl.MoveInstantaneousReward +>; +export type MoveInstantaneousRewardsCert = InstanceType< + typeof csl.MoveInstantaneousRewardsCert +>; export type MultiAsset = InstanceType; export type MultiHostName = InstanceType; export type NativeScript = InstanceType; @@ -85,7 +97,9 @@ export type PoolParams = InstanceType; export type PoolRegistration = InstanceType; export type PoolRetirement = InstanceType; export type PrivateKey = InstanceType; -export type ProposedProtocolParameterUpdates = InstanceType; +export type ProposedProtocolParameterUpdates = InstanceType< + typeof csl.ProposedProtocolParameterUpdates +>; export type ProtocolParamUpdate = InstanceType; export type ProtocolVersion = InstanceType; export type PublicKey = InstanceType; @@ -118,21 +132,41 @@ export type Transaction = InstanceType; export type TransactionBodies = InstanceType; export type TransactionBody = InstanceType; export type TransactionBuilder = InstanceType; -export type TransactionBuilderConfig = InstanceType; -export type TransactionBuilderConfigBuilder = InstanceType; +export type TransactionBuilderConfig = InstanceType< + typeof csl.TransactionBuilderConfig +>; +export type TransactionBuilderConfigBuilder = InstanceType< + typeof csl.TransactionBuilderConfigBuilder +>; export type TransactionHash = InstanceType; export type TransactionInput = InstanceType; export type TransactionInputs = InstanceType; -export type TransactionMetadatum = InstanceType; -export type TransactionMetadatumLabels = InstanceType; +export type TransactionMetadatum = InstanceType< + typeof csl.TransactionMetadatum +>; +export type TransactionMetadatumLabels = InstanceType< + typeof csl.TransactionMetadatumLabels +>; export type TransactionOutput = InstanceType; -export type TransactionOutputAmountBuilder = InstanceType; -export type TransactionOutputBuilder = InstanceType; +export type TransactionOutputAmountBuilder = InstanceType< + typeof csl.TransactionOutputAmountBuilder +>; +export type TransactionOutputBuilder = InstanceType< + typeof csl.TransactionOutputBuilder +>; export type TransactionOutputs = InstanceType; -export type TransactionUnspentOutput = InstanceType; -export type TransactionUnspentOutputs = InstanceType; -export type TransactionWitnessSet = InstanceType; -export type TransactionWitnessSets = InstanceType; +export type TransactionUnspentOutput = InstanceType< + typeof csl.TransactionUnspentOutput +>; +export type TransactionUnspentOutputs = InstanceType< + typeof csl.TransactionUnspentOutputs +>; +export type TransactionWitnessSet = InstanceType< + typeof csl.TransactionWitnessSet +>; +export type TransactionWitnessSets = InstanceType< + typeof csl.TransactionWitnessSets +>; export type TxBuilderConstants = InstanceType; export type TxInputsBuilder = InstanceType; export type URL = InstanceType; diff --git a/packages/module/src/index.ts b/packages/module/src/index.ts index 450c2d8ac..c9c674d98 100644 --- a/packages/module/src/index.ts +++ b/packages/module/src/index.ts @@ -1,5 +1,5 @@ export * from './common/contracts'; -export * from './common/types'; +export * from './common/data'; export { generateNonce, readPlutusData } from './common/helpers'; export * from './common/utils/resolver'; export * from './common/utils/parser'; @@ -9,3 +9,4 @@ export * from './providers'; export * from './scripts'; export * from './transaction'; export * from './wallet'; +export * from './types'; diff --git a/packages/module/src/providers/blockfrost.provider.ts b/packages/module/src/providers/blockfrost.provider.ts index d8e8e5b00..4f027ddf7 100644 --- a/packages/module/src/providers/blockfrost.provider.ts +++ b/packages/module/src/providers/blockfrost.provider.ts @@ -19,7 +19,7 @@ import type { Protocol, TransactionInfo, UTxO, -} from '@mesh/common/types'; +} from '@mesh/types'; /** * [Blockfrost](https://blockfrost.io/) provides restful APIs which allows your app to access information stored on the blockchain. diff --git a/packages/module/src/providers/koios.provider.ts b/packages/module/src/providers/koios.provider.ts index 06ab56f47..43313bab5 100644 --- a/packages/module/src/providers/koios.provider.ts +++ b/packages/module/src/providers/koios.provider.ts @@ -21,7 +21,7 @@ import type { Protocol, TransactionInfo, UTxO, -} from '@mesh/common/types'; +} from '@mesh/types'; export class KoiosProvider implements IFetcher, IListener, ISubmitter { private readonly _axiosInstance: AxiosInstance; diff --git a/packages/module/src/providers/maestro.provider.ts b/packages/module/src/providers/maestro.provider.ts index 2abead3db..b38e4d5d2 100644 --- a/packages/module/src/providers/maestro.provider.ts +++ b/packages/module/src/providers/maestro.provider.ts @@ -18,7 +18,7 @@ import type { Protocol, TransactionInfo, UTxO, -} from '@mesh/common/types'; +} from '@mesh/types'; import { csl } from '@mesh/core'; export type MaestroSupportedNetworks = 'Mainnet' | 'Preprod' | 'Preview'; @@ -31,12 +31,11 @@ export interface MaestroConfig { export class MaestroProvider implements IFetcher, ISubmitter, IEvaluator { private readonly _axiosInstance: AxiosInstance; - private readonly _amountsAsStrings = - { - headers: { - "amounts-as-strings": "true" - } - } + private readonly _amountsAsStrings = { + headers: { + 'amounts-as-strings': 'true', + }, + }; submitUrl: string; @@ -83,7 +82,8 @@ export class MaestroProvider implements IFetcher, ISubmitter, IEvaluator { try { const { data: timestampedData, status } = await this._axiosInstance.get( - `accounts/${rewardAddress}`, this._amountsAsStrings + `accounts/${rewardAddress}`, + this._amountsAsStrings ); if (status === 200) { @@ -119,7 +119,8 @@ export class MaestroProvider implements IFetcher, ISubmitter, IEvaluator { ): Promise => { const appendCursorString = cursor === null ? '' : `&cursor=${cursor}`; const { data: timestampedData, status } = await this._axiosInstance.get( - `${queryPredicate}/utxos?count=100${appendAssetString}${appendCursorString}`, this._amountsAsStrings + `${queryPredicate}/utxos?count=100${appendAssetString}${appendCursorString}`, + this._amountsAsStrings ); if (status === 200) { const data = timestampedData.data; @@ -151,7 +152,8 @@ export class MaestroProvider implements IFetcher, ISubmitter, IEvaluator { ): Promise<{ address: string; quantity: string }[]> => { const appendCursorString = cursor === null ? '' : `&cursor=${cursor}`; const { data: timestampedData, status } = await this._axiosInstance.get( - `assets/${policyId}${assetName}/addresses?count=100${appendCursorString}`, this._amountsAsStrings + `assets/${policyId}${assetName}/addresses?count=100${appendCursorString}`, + this._amountsAsStrings ); if (status === 200) { const data = timestampedData.data; @@ -205,7 +207,8 @@ export class MaestroProvider implements IFetcher, ISubmitter, IEvaluator { async fetchBlockInfo(hash: string): Promise { try { const { data: timestampedData, status } = await this._axiosInstance.get( - `blocks/${hash}`, this._amountsAsStrings + `blocks/${hash}`, + this._amountsAsStrings ); if (status === 200) { @@ -241,7 +244,8 @@ export class MaestroProvider implements IFetcher, ISubmitter, IEvaluator { ): Promise<{ assets: Asset[]; next: string | number | null }> { try { const { data: timestampedData, status } = await this._axiosInstance.get( - `policy/${policyId}/assets?count=100${cursor ? `&cursor=${cursor}` : '' + `policy/${policyId}/assets?count=100${ + cursor ? `&cursor=${cursor}` : '' }` ); @@ -370,7 +374,8 @@ export class MaestroProvider implements IFetcher, ISubmitter, IEvaluator { async fetchUTxOs(hash: string): Promise { try { const { data: timestampedData, status } = await this._axiosInstance.get( - `transactions/${hash}`, this._amountsAsStrings + `transactions/${hash}`, + this._amountsAsStrings ); if (status === 200) { const msOutputs = timestampedData.data.outputs as MaestroUTxO[]; @@ -449,9 +454,9 @@ export class MaestroProvider implements IFetcher, ISubmitter, IEvaluator { utxo.reference_script.type === 'native' ? utxo.reference_script.json : { - code: utxo.reference_script.bytes, - version: utxo.reference_script.type.replace('plutusv', 'V'), - }; + code: utxo.reference_script.bytes, + version: utxo.reference_script.type.replace('plutusv', 'V'), + }; return toScriptRef(script).to_hex(); } else return undefined; }; diff --git a/packages/module/src/providers/ogmios.provider.ts b/packages/module/src/providers/ogmios.provider.ts index 9cb2ca4c0..bfc9ebb86 100644 --- a/packages/module/src/providers/ogmios.provider.ts +++ b/packages/module/src/providers/ogmios.provider.ts @@ -1,59 +1,64 @@ import { SUPPORTED_OGMIOS_LINKS } from '@mesh/common/constants'; import { IEvaluator, ISubmitter } from '@mesh/common/contracts'; -import { Action, isNetwork, Network } from '@mesh/common/types'; +import { Action, isNetwork, Network } from '@mesh/types'; export class OgmiosProvider implements IEvaluator, ISubmitter { private readonly _baseUrl: string; constructor(baseUrl: string); constructor(network: Network); - + constructor(...args: unknown[]) { this._baseUrl = isNetwork(args[0]) ? SUPPORTED_OGMIOS_LINKS[args[0]] - : args[0] as string; + : (args[0] as string); } async evaluateTx(tx: string): Promise[]> { const client = await this.open(); - + this.send(client, 'EvaluateTx', { evaluate: tx, }); return new Promise((resolve, reject) => { - client.addEventListener('message', (response: MessageEvent) => { - try { - const { result } = JSON.parse(response.data); - - if (result.EvaluationResult) { - resolve( - Object.keys(result.EvaluationResult).map((key) => - >{ - index: parseInt(key.split(':')[1], 10), - tag: key.split(':')[0].toUpperCase(), - budget: { - mem: result.EvaluationResult[key].memory, - steps: result.EvaluationResult[key].steps, - }, - } - ) - ); - } else { - reject(result.EvaluationFailure); + client.addEventListener( + 'message', + (response: MessageEvent) => { + try { + const { result } = JSON.parse(response.data); + + if (result.EvaluationResult) { + resolve( + Object.keys(result.EvaluationResult).map( + (key) => + >{ + index: parseInt(key.split(':')[1], 10), + tag: key.split(':')[0].toUpperCase(), + budget: { + mem: result.EvaluationResult[key].memory, + steps: result.EvaluationResult[key].steps, + }, + } + ) + ); + } else { + reject(result.EvaluationFailure); + } + + client.close(); + } catch (error) { + reject(error); } - - client.close(); - } catch (error) { - reject(error); - } - }, { once: true }); + }, + { once: true } + ); }); } async onNextTx(callback: (tx: unknown) => void): Promise<() => void> { const client = await this.open(); - + this.send(client, 'AwaitAcquire', {}); client.addEventListener('message', (response: MessageEvent) => { @@ -75,27 +80,31 @@ export class OgmiosProvider implements IEvaluator, ISubmitter { async submitTx(tx: string): Promise { const client = await this.open(); - + this.send(client, 'SubmitTx', { submit: tx, }); return new Promise((resolve, reject) => { - client.addEventListener('message', (response: MessageEvent) => { - try { - const { result } = JSON.parse(response.data); - - if (result.SubmitSuccess) { - resolve(result.SubmitSuccess.txId); - } else { - reject(result.SubmitFail); + client.addEventListener( + 'message', + (response: MessageEvent) => { + try { + const { result } = JSON.parse(response.data); + + if (result.SubmitSuccess) { + resolve(result.SubmitSuccess.txId); + } else { + reject(result.SubmitFail); + } + + client.close(); + } catch (error) { + reject(error); } - - client.close(); - } catch (error) { - reject(error); - } - }, { once: true }); + }, + { once: true } + ); }); } @@ -115,7 +124,8 @@ export class OgmiosProvider implements IEvaluator, ISubmitter { version: '1.0', type: 'jsonwsp/request', servicename: 'ogmios', - methodname, args, + methodname, + args, }) ); } diff --git a/packages/module/src/providers/tango.provider.ts b/packages/module/src/providers/tango.provider.ts index e95d0cad3..019e2cfe0 100644 --- a/packages/module/src/providers/tango.provider.ts +++ b/packages/module/src/providers/tango.provider.ts @@ -26,7 +26,7 @@ import type { Protocol, TransactionInfo, UTxO, -} from '@mesh/common/types'; +} from '@mesh/types'; export class TangoProvider implements IEvaluator, IFetcher, IListener, ISubmitter diff --git a/packages/module/src/scripts/forge.script.ts b/packages/module/src/scripts/forge.script.ts index 4278632f2..3a1f6860d 100644 --- a/packages/module/src/scripts/forge.script.ts +++ b/packages/module/src/scripts/forge.script.ts @@ -1,27 +1,26 @@ import { csl } from '@mesh/core'; import { - buildScriptPubkey, deserializeEd25519KeyHash, - resolvePaymentKeyHash, toNativeScript, + buildScriptPubkey, + deserializeEd25519KeyHash, + resolvePaymentKeyHash, + toNativeScript, } from '@mesh/common/utils'; -import type { NativeScript } from '@mesh/common/types'; +import type { NativeScript } from '@mesh/types'; export class ForgeScript { static withOneSignature(address: string): string { - const keyHash = deserializeEd25519KeyHash( - resolvePaymentKeyHash(address), - ); + const keyHash = deserializeEd25519KeyHash(resolvePaymentKeyHash(address)); return buildScriptPubkey(keyHash).to_hex(); } static withAtLeastNSignatures( - addresses: string[], minimumRequired: number, + addresses: string[], + minimumRequired: number ): string { const nativeScripts = csl.NativeScripts.new(); addresses.forEach((address) => { - const keyHash = deserializeEd25519KeyHash( - resolvePaymentKeyHash(address), - ); + const keyHash = deserializeEd25519KeyHash(resolvePaymentKeyHash(address)); nativeScripts.add(buildScriptPubkey(keyHash)); }); @@ -33,9 +32,7 @@ export class ForgeScript { const nativeScripts = csl.NativeScripts.new(); addresses.forEach((address) => { - const keyHash = deserializeEd25519KeyHash( - resolvePaymentKeyHash(address), - ); + const keyHash = deserializeEd25519KeyHash(resolvePaymentKeyHash(address)); nativeScripts.add(buildScriptPubkey(keyHash)); }); @@ -47,9 +44,7 @@ export class ForgeScript { const nativeScripts = csl.NativeScripts.new(); addresses.forEach((address) => { - const keyHash = deserializeEd25519KeyHash( - resolvePaymentKeyHash(address), - ); + const keyHash = deserializeEd25519KeyHash(resolvePaymentKeyHash(address)); nativeScripts.add(buildScriptPubkey(keyHash)); }); diff --git a/packages/module/src/transaction/meshTxBuilder/meshTxBuilder.service.ts b/packages/module/src/transaction/meshTxBuilder/meshTxBuilder.service.ts index d10593dfc..7617015d1 100644 --- a/packages/module/src/transaction/meshTxBuilder/meshTxBuilder.service.ts +++ b/packages/module/src/transaction/meshTxBuilder/meshTxBuilder.service.ts @@ -1,5 +1,5 @@ import { IEvaluator, IFetcher, ISubmitter } from '@mesh/common/contracts'; -import { UTxO } from '@mesh/common/types'; +import { UTxO } from '@mesh/types'; import { MeshTxBuilderCore } from './meshTxBuilderCore'; import { MeshTxBuilderBody, TxIn, ScriptSourceInfo, ScriptTxIn } from './type'; diff --git a/packages/module/src/transaction/meshTxBuilder/meshTxBuilderCore.ts b/packages/module/src/transaction/meshTxBuilder/meshTxBuilderCore.ts index f48132dce..6767aaec6 100644 --- a/packages/module/src/transaction/meshTxBuilder/meshTxBuilderCore.ts +++ b/packages/module/src/transaction/meshTxBuilder/meshTxBuilderCore.ts @@ -13,7 +13,7 @@ import { UTxO, Unit, PoolParams, -} from '@mesh/common/types'; +} from '@mesh/types'; import { buildTxBuilder, toValue, diff --git a/packages/module/src/transaction/meshTxBuilder/type.ts b/packages/module/src/transaction/meshTxBuilder/type.ts index f3a299e8d..1ef8d1e03 100644 --- a/packages/module/src/transaction/meshTxBuilder/type.ts +++ b/packages/module/src/transaction/meshTxBuilder/type.ts @@ -6,7 +6,7 @@ import { PlutusScript, UTxO, PoolParams, -} from '@mesh/common/types'; +} from '@mesh/types'; export type MeshTxBuilderBody = { inputs: TxIn[]; diff --git a/packages/module/src/transaction/transaction.service.ts b/packages/module/src/transaction/transaction.service.ts index 604eb1a76..740dfaa2e 100644 --- a/packages/module/src/transaction/transaction.service.ts +++ b/packages/module/src/transaction/transaction.service.ts @@ -1,26 +1,66 @@ import { csl, keepRelevant, largestFirstMultiAsset } from '@mesh/core'; import { - DEFAULT_PROTOCOL_PARAMETERS, DEFAULT_REDEEMER_BUDGET, - POLICY_ID_LENGTH, SUPPORTED_COST_MODELS, SUPPORTED_TOKENS, + DEFAULT_PROTOCOL_PARAMETERS, + DEFAULT_REDEEMER_BUDGET, + POLICY_ID_LENGTH, + SUPPORTED_COST_MODELS, + SUPPORTED_TOKENS, } from '@mesh/common/constants'; import { IInitiator } from '@mesh/common/contracts'; -import { Checkpoint, Trackable, TrackableObject } from '@mesh/common/decorators'; import { - buildDataCost, buildDatumSource, buildMintWitness, - buildPlutusScriptSource, buildTxBuilder, buildTxInputsBuilder, - buildTxOutputBuilder, deserializeEd25519KeyHash, deserializeNativeScript, - deserializePlutusScript, deserializeTx, fromScriptRef, fromTxUnspentOutput, - fromUTF8, resolvePaymentKeyHash, resolveStakeKeyHash, toAddress, toBytes, - toPoolParams, toRedeemer, toRewardAddress, toTxUnspentOutput, toValue, + Checkpoint, + Trackable, + TrackableObject, +} from '@mesh/common/decorators'; +import { + buildDataCost, + buildDatumSource, + buildMintWitness, + buildPlutusScriptSource, + buildTxBuilder, + buildTxInputsBuilder, + buildTxOutputBuilder, + deserializeEd25519KeyHash, + deserializeNativeScript, + deserializePlutusScript, + deserializeTx, + fromScriptRef, + fromTxUnspentOutput, + fromUTF8, + resolvePaymentKeyHash, + resolveStakeKeyHash, + toAddress, + toBytes, + toPoolParams, + toRedeemer, + toRewardAddress, + toTxUnspentOutput, + toValue, } from '@mesh/common/utils'; import type { - Address, Certificates, MintBuilder, - TransactionBuilder, TxInputsBuilder, Withdrawals, + Address, + Certificates, + MintBuilder, + TransactionBuilder, + TxInputsBuilder, + Withdrawals, } from '@mesh/core'; import type { - Action, Asset, AssetMetadata, Data, Era, Mint, Protocol, - PlutusScript, PoolParams, Quantity, Recipient, Token, Unit, UTxO, -} from '@mesh/common/types'; + Action, + Asset, + AssetMetadata, + Data, + Era, + Mint, + Protocol, + PlutusScript, + PoolParams, + Quantity, + Recipient, + Token, + Unit, + UTxO, +} from '@mesh/types'; @Trackable export class Transaction { @@ -43,43 +83,44 @@ export class Transaction { this._era = options.era; this._initiator = options.initiator; this._mintBuilder = csl.MintBuilder.new(); - this._protocolParameters = options.parameters ?? DEFAULT_PROTOCOL_PARAMETERS; + this._protocolParameters = + options.parameters ?? DEFAULT_PROTOCOL_PARAMETERS; this._txBuilder = buildTxBuilder(options.parameters); this._txCertificates = csl.Certificates.new(); this._txInputsBuilder = csl.TxInputsBuilder.new(); this._txWithdrawals = csl.Withdrawals.new(); } - static attachMetadata(cborTx: string, cborTxMetadata: string, era: Era = 'BABBAGE') { + static attachMetadata( + cborTx: string, + cborTxMetadata: string, + era: Era = 'BABBAGE' + ) { const tx = deserializeTx(cborTx); - const txAuxData = tx.auxiliary_data() - ?? csl.AuxiliaryData.new(); + const txAuxData = tx.auxiliary_data() ?? csl.AuxiliaryData.new(); txAuxData.set_metadata( - csl.GeneralTransactionMetadata.from_hex(cborTxMetadata), + csl.GeneralTransactionMetadata.from_hex(cborTxMetadata) ); - txAuxData.set_prefer_alonzo_format( - era === 'ALONZO', - ); + txAuxData.set_prefer_alonzo_format(era === 'ALONZO'); - if (csl.hash_auxiliary_data(txAuxData).to_hex() !== tx.body().auxiliary_data_hash()?.to_hex()) { + if ( + csl.hash_auxiliary_data(txAuxData).to_hex() !== + tx.body().auxiliary_data_hash()?.to_hex() + ) { throw new Error( - '[Transaction] attachMetadata: The metadata hash does not match the auxiliary data hash.', + '[Transaction] attachMetadata: The metadata hash does not match the auxiliary data hash.' ); } - return csl.Transaction.new( - tx.body(), tx.witness_set(), txAuxData, - ).to_hex(); + return csl.Transaction.new(tx.body(), tx.witness_set(), txAuxData).to_hex(); } static deattachMetadata(cborTx: string) { const tx = deserializeTx(cborTx); - return csl.Transaction.new( - tx.body(), tx.witness_set(), undefined, - ).to_hex(); + return csl.Transaction.new(tx.body(), tx.witness_set(), undefined).to_hex(); } static maskMetadata(cborTx: string, era: Era = 'BABBAGE') { @@ -93,9 +134,10 @@ export class Transaction { const metadatum = txMetadata.get(label); mockMetadata.insert( - label, csl.TransactionMetadatum.from_hex( - '0'.repeat((metadatum?.to_hex() ?? '').length), - ), + label, + csl.TransactionMetadatum.from_hex( + '0'.repeat((metadatum?.to_hex() ?? '').length) + ) ); } @@ -103,13 +145,13 @@ export class Transaction { if (txAuxData !== undefined) { txAuxData.set_metadata(mockMetadata); - txAuxData.set_prefer_alonzo_format( - era === 'ALONZO', - ); + txAuxData.set_prefer_alonzo_format(era === 'ALONZO'); } return csl.Transaction.new( - tx.body(), tx.witness_set(), txAuxData, + tx.body(), + tx.witness_set(), + txAuxData ).to_hex(); } @@ -121,22 +163,21 @@ export class Transaction { return tx.auxiliary_data()?.metadata()?.to_hex() ?? ''; } - static writeMetadata(cborTx: string, cborTxMetadata: string, era: Era = 'BABBAGE') { + static writeMetadata( + cborTx: string, + cborTxMetadata: string, + era: Era = 'BABBAGE' + ) { const tx = deserializeTx(cborTx); - const txAuxData = tx.auxiliary_data() - ?? csl.AuxiliaryData.new(); + const txAuxData = tx.auxiliary_data() ?? csl.AuxiliaryData.new(); txAuxData.set_metadata( - csl.GeneralTransactionMetadata.from_hex(cborTxMetadata), + csl.GeneralTransactionMetadata.from_hex(cborTxMetadata) ); - txAuxData.set_prefer_alonzo_format( - era === 'ALONZO', - ); + txAuxData.set_prefer_alonzo_format(era === 'ALONZO'); - return csl.Transaction.new( - tx.body(), tx.witness_set(), txAuxData, - ).to_hex(); + return csl.Transaction.new(tx.body(), tx.witness_set(), txAuxData).to_hex(); } get size(): number { @@ -159,23 +200,27 @@ export class Transaction { return this._txBuilder.build_tx().to_hex(); } catch (error) { - throw new Error(`[Transaction] An error occurred during build: ${error}.`); + throw new Error( + `[Transaction] An error occurred during build: ${error}.` + ); } } burnAsset( forgeScript: string | PlutusScript | UTxO, - asset: Asset, redeemer?: Partial, + asset: Asset, + redeemer?: Partial ): Transaction { const totalQuantity = this._totalBurns.has(asset.unit) ? csl.BigNum.from_str(this._totalBurns.get(asset.unit) ?? '0') - .checked_add(csl.BigNum.from_str(asset.quantity)).to_str() + .checked_add(csl.BigNum.from_str(asset.quantity)) + .to_str() : asset.quantity; this._mintBuilder.add_asset( buildMintWitness(forgeScript, redeemer), csl.AssetName.new(toBytes(asset.unit.slice(POLICY_ID_LENGTH))), - csl.Int.new_negative(csl.BigNum.from_str(asset.quantity)), + csl.Int.new_negative(csl.BigNum.from_str(asset.quantity)) ); this._totalBurns.set(asset.unit, totalQuantity); @@ -187,10 +232,10 @@ export class Transaction { const stakeDelegation = csl.Certificate.new_stake_delegation( csl.StakeDelegation.new( csl.StakeCredential.from_keyhash( - deserializeEd25519KeyHash(resolveStakeKeyHash(rewardAddress)), + deserializeEd25519KeyHash(resolveStakeKeyHash(rewardAddress)) ), - csl.Ed25519KeyHash.from_bech32(poolId), - ), + csl.Ed25519KeyHash.from_bech32(poolId) + ) ); this._txCertificates.add(stakeDelegation); @@ -202,9 +247,9 @@ export class Transaction { const stakeDeregistration = csl.Certificate.new_stake_deregistration( csl.StakeDeregistration.new( csl.StakeCredential.from_keyhash( - deserializeEd25519KeyHash(resolveStakeKeyHash(rewardAddress)), - ), - ), + deserializeEd25519KeyHash(resolveStakeKeyHash(rewardAddress)) + ) + ) ); this._txCertificates.add(stakeDeregistration); @@ -215,14 +260,17 @@ export class Transaction { @Checkpoint() mintAsset( forgeScript: string | PlutusScript | UTxO, - mint: Mint, redeemer?: Partial, + mint: Mint, + redeemer?: Partial ): Transaction { const toAsset = ( - forgeScript: string | PlutusScript | UTxO, mint: Mint, + forgeScript: string | PlutusScript | UTxO, + mint: Mint ): Asset => { - const policyId = typeof forgeScript === 'string' - ? deserializeNativeScript(forgeScript).hash().to_hex() - : toPlutusScript(forgeScript).hash().to_hex(); + const policyId = + typeof forgeScript === 'string' + ? deserializeNativeScript(forgeScript).hash().to_hex() + : toPlutusScript(forgeScript).hash().to_hex(); const assetName = fromUTF8(mint.assetName); @@ -244,28 +292,34 @@ export class Transaction { if (scriptRef.is_plutus_script()) { const plutusScript = fromScriptRef(scriptRef) as PlutusScript; return deserializePlutusScript( - plutusScript.code, plutusScript.version, + plutusScript.code, + plutusScript.version ); } } throw new Error( - `[Transaction] No plutus script reference found in UTxO: ${utxo.input().transaction_id().to_hex()}`, + `[Transaction] No plutus script reference found in UTxO: ${utxo + .input() + .transaction_id() + .to_hex()}` ); }; const asset = toAsset(forgeScript, mint); - const existingQuantity = csl.BigNum - .from_str(this._totalMints.get(asset.unit)?.assetQuantity ?? '0'); + const existingQuantity = csl.BigNum.from_str( + this._totalMints.get(asset.unit)?.assetQuantity ?? '0' + ); - const totalQuantity = existingQuantity - .checked_add(csl.BigNum.from_str(asset.quantity)); + const totalQuantity = existingQuantity.checked_add( + csl.BigNum.from_str(asset.quantity) + ); this._mintBuilder.add_asset( buildMintWitness(forgeScript, redeemer), csl.AssetName.new(toBytes(fromUTF8(mint.assetName))), - csl.Int.new(csl.BigNum.from_str(asset.quantity)), + csl.Int.new(csl.BigNum.from_str(asset.quantity)) ); if (this._recipients.has(mint.recipient)) @@ -273,7 +327,8 @@ export class Transaction { else this._recipients.set(mint.recipient, [asset]); this._totalMints.set(asset.unit, { - ...mint, assetQuantity: totalQuantity.to_str(), + ...mint, + assetQuantity: totalQuantity.to_str(), }); return this; @@ -281,8 +336,10 @@ export class Transaction { @Checkpoint() redeemValue(options: { - value: UTxO, script: PlutusScript | UTxO, - datum?: Data | UTxO, redeemer?: Action, + value: UTxO; + script: PlutusScript | UTxO; + datum?: Data | UTxO; + redeemer?: Action; }): Transaction { const redeemer: Action = { tag: 'SPEND', @@ -299,17 +356,19 @@ export class Transaction { const witness = options.datum ? csl.PlutusWitness.new_with_ref( - buildPlutusScriptSource(options.script), - buildDatumSource(options.datum), - toRedeemer(redeemer), - ) + buildPlutusScriptSource(options.script), + buildDatumSource(options.datum), + toRedeemer(redeemer) + ) : csl.PlutusWitness.new_with_ref_without_datum( - buildPlutusScriptSource(options.script), - toRedeemer(redeemer), - ); + buildPlutusScriptSource(options.script), + toRedeemer(redeemer) + ); this._txInputsBuilder.add_plutus_script_input( - witness, utxo.input(), utxo.output().amount(), + witness, + utxo.input(), + utxo.output().amount() ); return this; @@ -319,9 +378,9 @@ export class Transaction { const stakeRegistration = csl.Certificate.new_stake_registration( csl.StakeRegistration.new( csl.StakeCredential.from_keyhash( - deserializeEd25519KeyHash(resolveStakeKeyHash(rewardAddress)), - ), - ), + deserializeEd25519KeyHash(resolveStakeKeyHash(rewardAddress)) + ) + ) ); this._txCertificates.add(stakeRegistration); @@ -331,7 +390,7 @@ export class Transaction { registerPool(params: PoolParams): Transaction { const poolRegistration = csl.Certificate.new_pool_registration( - csl.PoolRegistration.new(toPoolParams(params)), + csl.PoolRegistration.new(toPoolParams(params)) ); this._txCertificates.add(poolRegistration); @@ -341,7 +400,7 @@ export class Transaction { retirePool(poolId: string, epochNo: number): Transaction { const poolRetirement = csl.Certificate.new_pool_retirement( - csl.PoolRetirement.new(csl.Ed25519KeyHash.from_bech32(poolId), epochNo), + csl.PoolRetirement.new(csl.Ed25519KeyHash.from_bech32(poolId), epochNo) ); this._txCertificates.add(poolRetirement); @@ -358,27 +417,24 @@ export class Transaction { * @see {@link https://meshjs.dev/apis/transaction#sendAssets} */ @Checkpoint() - sendAssets( - recipient: Recipient, assets: Asset[], - ): Transaction { + sendAssets(recipient: Recipient, assets: Asset[]): Transaction { const amount = toValue(assets); const multiAsset = amount.multiasset(); - if (amount.is_zero() || multiAsset === undefined) - return this; + if (amount.is_zero() || multiAsset === undefined) return this; - const txOutputAmountBuilder = buildTxOutputBuilder( - recipient, - ).next(); + const txOutputAmountBuilder = buildTxOutputBuilder(recipient).next(); const txOutput = amount.coin().is_zero() ? txOutputAmountBuilder - .with_asset_and_min_required_coin_by_utxo_cost(multiAsset, - buildDataCost(this._protocolParameters.coinsPerUTxOSize), - ).build() + .with_asset_and_min_required_coin_by_utxo_cost( + multiAsset, + buildDataCost(this._protocolParameters.coinsPerUTxOSize) + ) + .build() : txOutputAmountBuilder - .with_coin_and_asset(amount.coin(), multiAsset) - .build(); + .with_coin_and_asset(amount.coin(), multiAsset) + .build(); assets.forEach((asset) => { this.setTxOutput(asset); @@ -397,19 +453,17 @@ export class Transaction { * @returns {Transaction} The Transaction object. * @see {@link https://meshjs.dev/apis/transaction#sendAda} */ - sendLovelace( - recipient: Recipient, lovelace: string, - ): Transaction { - const txOutputBuilder = buildTxOutputBuilder( - recipient, - ); + sendLovelace(recipient: Recipient, lovelace: string): Transaction { + const txOutputBuilder = buildTxOutputBuilder(recipient); - const txOutput = txOutputBuilder.next() + const txOutput = txOutputBuilder + .next() .with_coin(csl.BigNum.from_str(lovelace)) .build(); this.setTxOutput({ - unit: 'lovelace', quantity: lovelace, + unit: 'lovelace', + quantity: lovelace, }); this._txBuilder.add_output(txOutput); @@ -425,13 +479,13 @@ export class Transaction { * @returns {Transaction} The Transaction object. * @see {@link https://meshjs.dev/apis/transaction#sendToken} */ - sendToken( - recipient: Recipient, ticker: Token, amount: string, - ): Transaction { - this.sendAssets(recipient, [{ - quantity: amount, - unit: SUPPORTED_TOKENS[ticker], - }]); + sendToken(recipient: Recipient, ticker: Token, amount: string): Transaction { + this.sendAssets(recipient, [ + { + quantity: amount, + unit: SUPPORTED_TOKENS[ticker], + }, + ]); return this; } @@ -444,17 +498,11 @@ export class Transaction { * @returns {Transaction} The Transaction object. */ @Checkpoint() - sendValue( - recipient: Recipient, value: UTxO, - ): Transaction { + sendValue(recipient: Recipient, value: UTxO): Transaction { const amount = toValue(value.output.amount); - const txOutputBuilder = buildTxOutputBuilder( - recipient, - ); + const txOutputBuilder = buildTxOutputBuilder(recipient); - const txOutput = txOutputBuilder.next() - .with_value(amount) - .build(); + const txOutput = txOutputBuilder.next().with_value(amount).build(); value.output.amount.forEach((asset) => { this.setTxOutput(asset); @@ -502,8 +550,9 @@ export class Transaction { */ setMetadata(key: number, value: unknown): Transaction { this._txBuilder.add_json_metadatum_with_schema( - csl.BigNum.from_str(key.toString()), JSON.stringify(value), - csl.MetadataJsonSchema.NoConversions, + csl.BigNum.from_str(key.toString()), + JSON.stringify(value), + csl.MetadataJsonSchema.NoConversions ); return this; @@ -517,15 +566,17 @@ export class Transaction { */ @Checkpoint() setRequiredSigners(addresses: string[]): Transaction { - const signatures = Array.from(new Set( - addresses - .map((address) => { - return address.startsWith('addr') - ? resolvePaymentKeyHash(address) - : resolveStakeKeyHash(address); - }) - .map((keyHash) => deserializeEd25519KeyHash(keyHash)) - )); + const signatures = Array.from( + new Set( + addresses + .map((address) => { + return address.startsWith('addr') + ? resolvePaymentKeyHash(address) + : resolveStakeKeyHash(address); + }) + .map((keyHash) => deserializeEd25519KeyHash(keyHash)) + ) + ); signatures.forEach((signature) => { this._txBuilder.add_required_signer(signature); @@ -543,7 +594,7 @@ export class Transaction { */ setTimeToStart(slot: string): Transaction { this._txBuilder.set_validity_start_interval_bignum( - csl.BigNum.from_str(slot), + csl.BigNum.from_str(slot) ); return this; @@ -557,9 +608,7 @@ export class Transaction { * @see {@link https://meshjs.dev/apis/transaction#setTimeLimit} */ setTimeToExpire(slot: string): Transaction { - this._txBuilder.set_ttl_bignum( - csl.BigNum.from_str(slot), - ); + this._txBuilder.set_ttl_bignum(csl.BigNum.from_str(slot)); return this; } @@ -578,7 +627,7 @@ export class Transaction { this._txInputsBuilder.add_input( utxo.output().address(), utxo.input(), - utxo.output().amount(), + utxo.output().amount() ); }); @@ -605,9 +654,7 @@ export class Transaction { const address = toRewardAddress(rewardAddress); if (address !== undefined) { - this._txWithdrawals.insert( - address, csl.BigNum.from_str(lovelace), - ); + this._txWithdrawals.insert(address, csl.BigNum.from_str(lovelace)); } return this; @@ -615,23 +662,23 @@ export class Transaction { private async addBurnInputsIfNeeded() { if ( - this._initiator - && this._totalBurns.size > 0 - && this.notVisited('setTxInputs') + this._initiator && + this._totalBurns.size > 0 && + this.notVisited('setTxInputs') ) { const utxos = await this._initiator.getUsedUTxOs(); - const inputs = largestFirstMultiAsset(this._totalBurns, - utxos.map((utxo) => fromTxUnspentOutput(utxo)), + const inputs = largestFirstMultiAsset( + this._totalBurns, + utxos.map((utxo) => fromTxUnspentOutput(utxo)) ).map((utxo) => toTxUnspentOutput(utxo)); - inputs - .forEach((utxo) => { - this._txInputsBuilder.add_input( - utxo.output().address(), - utxo.input(), - utxo.output().amount(), - ); - }); + inputs.forEach((utxo) => { + this._txInputsBuilder.add_input( + utxo.output().address(), + utxo.input(), + utxo.output().amount() + ); + }); } } @@ -664,15 +711,17 @@ export class Transaction { const availableUTxOs = await this.filterAvailableUTxOs(); const txInputs = keepRelevant( - this._txOutputs, availableUTxOs.map((au) => fromTxUnspentOutput(au)) + this._txOutputs, + availableUTxOs.map((au) => fromTxUnspentOutput(au)) ); txInputs .map((utxo) => toTxUnspentOutput(utxo)) .forEach((utxo) => { this._txInputsBuilder.add_input( - utxo.output().address(), utxo.input(), - utxo.output().amount(), + utxo.output().address(), + utxo.input(), + utxo.output().amount() ); }); } @@ -698,32 +747,30 @@ export class Transaction { this._txBuilder.get_mint_builder() || this.notVisited('redeemValue') === false ) { - const costModels = this._era !== undefined - ? SUPPORTED_COST_MODELS[this._era] - : SUPPORTED_COST_MODELS.BABBAGE; + const costModels = + this._era !== undefined + ? SUPPORTED_COST_MODELS[this._era] + : SUPPORTED_COST_MODELS.BABBAGE; this._txBuilder.calc_script_data_hash(costModels); } } private async forgeAssetsIfNeeded() { - type Mintdata = { unit: string, data: Mint }; + type Mintdata = { unit: string; data: Mint }; type Metadata = Record>; const forge = (mint: Mintdata, meta?: Metadata): Metadata => { const name = mint.data.assetName; const metadata = mint.data.metadata; - const collection = mint.unit - .slice(0, POLICY_ID_LENGTH); + const collection = mint.unit.slice(0, POLICY_ID_LENGTH); if (mint.data.label === '777') { return metadata as any; // TODO: fix this } if (meta && meta[collection]) { - const { - [collection]: oldCollection, ...rest - } = meta; + const { [collection]: oldCollection, ...rest } = meta; const newCollection = { [name]: metadata, @@ -733,7 +780,8 @@ export class Transaction { return { [collection]: { ...newCollection, - }, ...rest, + }, + ...rest, }; } @@ -753,20 +801,24 @@ export class Transaction { await this.addBurnInputsIfNeeded(); - Array - .from(this._totalMints, (mint) => ({ - unit: mint[0], - data: mint[1], - })) + Array.from( + this._totalMints, + (mint) => + { + unit: mint[0], + data: mint[1], + } + ) .reduce((metadatums, mint) => { - return metadatums.set(mint.data.label, forge( - mint, metadatums.get(mint.data.label), - )); - }, new Map) + return metadatums.set( + mint.data.label, + forge(mint, metadatums.get(mint.data.label)) + ); + }, new Map()) .forEach((metadata, label) => { this._txBuilder.add_json_metadatum( csl.BigNum.from_str(label), - JSON.stringify(metadata), + JSON.stringify(metadata) ); }); @@ -774,20 +826,17 @@ export class Transaction { } private async filterAvailableUTxOs(selectedUTxOs: UTxO[] = []) { - if (this._initiator === undefined) - return []; - - const allUTxOs = await this._initiator - .getUsedUTxOs(); - - return allUTxOs - .filter((au) => { - return ( - selectedUTxOs.find( - (su) => su.input.txHash === au.input().transaction_id().to_hex() - ) === undefined - ); - }); + if (this._initiator === undefined) return []; + + const allUTxOs = await this._initiator.getUsedUTxOs(); + + return allUTxOs.filter((au) => { + return ( + selectedUTxOs.find( + (su) => su.input.txHash === au.input().transaction_id().to_hex() + ) === undefined + ); + }); } private addMintOutputs() { @@ -796,14 +845,15 @@ export class Transaction { const multiAsset = amount.multiasset(); if (multiAsset !== undefined) { - const txOutputBuilder = buildTxOutputBuilder( - recipient, - ); + const txOutputBuilder = buildTxOutputBuilder(recipient); - const txOutput = txOutputBuilder.next() - .with_asset_and_min_required_coin_by_utxo_cost(multiAsset, - buildDataCost(this._protocolParameters.coinsPerUTxOSize), - ).build(); + const txOutput = txOutputBuilder + .next() + .with_asset_and_min_required_coin_by_utxo_cost( + multiAsset, + buildDataCost(this._protocolParameters.coinsPerUTxOSize) + ) + .build(); this._txBuilder.add_output(txOutput); } @@ -812,14 +862,14 @@ export class Transaction { private notVisited(checkpoint: string) { return ( - (this as unknown as TrackableObject).__visits - .includes(checkpoint) === false + (this as unknown as TrackableObject).__visits.includes(checkpoint) === + false ); } private setTxOutput(asset: Asset) { const existingQuantity = csl.BigNum.from_str( - this._txOutputs.get(asset.unit) ?? '0', + this._txOutputs.get(asset.unit) ?? '0' ); const totalQuantity = existingQuantity diff --git a/packages/module/src/common/types/Account.ts b/packages/module/src/types/Account.ts similarity index 100% rename from packages/module/src/common/types/Account.ts rename to packages/module/src/types/Account.ts diff --git a/packages/module/src/common/types/AccountInfo.ts b/packages/module/src/types/AccountInfo.ts similarity index 100% rename from packages/module/src/common/types/AccountInfo.ts rename to packages/module/src/types/AccountInfo.ts diff --git a/packages/module/src/common/types/Action.ts b/packages/module/src/types/Action.ts similarity index 100% rename from packages/module/src/common/types/Action.ts rename to packages/module/src/types/Action.ts diff --git a/packages/module/src/common/types/Asset.ts b/packages/module/src/types/Asset.ts similarity index 100% rename from packages/module/src/common/types/Asset.ts rename to packages/module/src/types/Asset.ts diff --git a/packages/module/src/common/types/AssetExtended.ts b/packages/module/src/types/AssetExtended.ts similarity index 100% rename from packages/module/src/common/types/AssetExtended.ts rename to packages/module/src/types/AssetExtended.ts diff --git a/packages/module/src/common/types/AssetMetadata.ts b/packages/module/src/types/AssetMetadata.ts similarity index 70% rename from packages/module/src/common/types/AssetMetadata.ts rename to packages/module/src/types/AssetMetadata.ts index 4746c949b..58a79b77a 100644 --- a/packages/module/src/common/types/AssetMetadata.ts +++ b/packages/module/src/types/AssetMetadata.ts @@ -19,16 +19,19 @@ export type NonFungibleAssetMetadata = type AudioAssetMetadata = MetadataStandard & Files; -export type ImageAssetMetadata = MetadataStandard & Files & { - artists?: [{ - name: string; - twitter?: `https://twitter.com/${string}`; - }]; - attributes?: { - [key: string]: string; +export type ImageAssetMetadata = MetadataStandard & + Files & { + artists?: [ + { + name: string; + twitter?: `https://twitter.com/${string}`; + } + ]; + attributes?: { + [key: string]: string; + }; + traits?: string[]; }; - traits?: string[]; -}; type SmartAssetMetadata = MetadataStandard & Files; diff --git a/packages/module/src/common/types/BlockInfo.ts b/packages/module/src/types/BlockInfo.ts similarity index 100% rename from packages/module/src/common/types/BlockInfo.ts rename to packages/module/src/types/BlockInfo.ts diff --git a/packages/module/src/common/types/Data.ts b/packages/module/src/types/Data.ts similarity index 100% rename from packages/module/src/common/types/Data.ts rename to packages/module/src/types/Data.ts diff --git a/packages/module/src/common/types/DataSignature.ts b/packages/module/src/types/DataSignature.ts similarity index 100% rename from packages/module/src/common/types/DataSignature.ts rename to packages/module/src/types/DataSignature.ts diff --git a/packages/module/src/types/Era.ts b/packages/module/src/types/Era.ts new file mode 100644 index 000000000..5191ea62e --- /dev/null +++ b/packages/module/src/types/Era.ts @@ -0,0 +1 @@ +export type Era = 'ALONZO' | 'BABBAGE'; diff --git a/packages/module/src/common/types/Mint.ts b/packages/module/src/types/Mint.ts similarity index 100% rename from packages/module/src/common/types/Mint.ts rename to packages/module/src/types/Mint.ts diff --git a/packages/module/src/common/types/NativeScript.ts b/packages/module/src/types/NativeScript.ts similarity index 100% rename from packages/module/src/common/types/NativeScript.ts rename to packages/module/src/types/NativeScript.ts diff --git a/packages/module/src/common/types/Network.ts b/packages/module/src/types/Network.ts similarity index 78% rename from packages/module/src/common/types/Network.ts rename to packages/module/src/types/Network.ts index 7b8b7ebb9..1fe831860 100644 --- a/packages/module/src/common/types/Network.ts +++ b/packages/module/src/types/Network.ts @@ -1,6 +1,6 @@ const ALL_NETWORKS = ['testnet', 'preview', 'preprod', 'mainnet'] as const; -export type Network = typeof ALL_NETWORKS[number]; +export type Network = (typeof ALL_NETWORKS)[number]; export const isNetwork = (value: unknown): value is Network => { return ALL_NETWORKS.includes(value as Network); diff --git a/packages/module/src/types/PlutusScript.ts b/packages/module/src/types/PlutusScript.ts new file mode 100644 index 000000000..5ad1efa22 --- /dev/null +++ b/packages/module/src/types/PlutusScript.ts @@ -0,0 +1,8 @@ +import { LANGUAGE_VERSIONS } from '../common/constants'; + +export type PlutusScript = { + version: LanguageVersion; + code: string; +}; + +export type LanguageVersion = keyof typeof LANGUAGE_VERSIONS; diff --git a/packages/module/src/common/types/PoolParams.ts b/packages/module/src/types/PoolParams.ts similarity index 100% rename from packages/module/src/common/types/PoolParams.ts rename to packages/module/src/types/PoolParams.ts diff --git a/packages/module/src/common/types/Protocol.ts b/packages/module/src/types/Protocol.ts similarity index 100% rename from packages/module/src/common/types/Protocol.ts rename to packages/module/src/types/Protocol.ts diff --git a/packages/module/src/types/Recipient.ts b/packages/module/src/types/Recipient.ts new file mode 100644 index 000000000..067897c0f --- /dev/null +++ b/packages/module/src/types/Recipient.ts @@ -0,0 +1,14 @@ +import { Data } from './Data'; +import { NativeScript } from './NativeScript'; +import { PlutusScript } from './PlutusScript'; + +export type Recipient = + | string + | { + address: string; + datum?: { + value: Data; + inline?: boolean; + }; + script?: PlutusScript | NativeScript; + }; diff --git a/packages/module/src/common/types/Relay.ts b/packages/module/src/types/Relay.ts similarity index 100% rename from packages/module/src/common/types/Relay.ts rename to packages/module/src/types/Relay.ts diff --git a/packages/module/src/common/types/Token.ts b/packages/module/src/types/Token.ts similarity index 100% rename from packages/module/src/common/types/Token.ts rename to packages/module/src/types/Token.ts diff --git a/packages/module/src/common/types/TransactionInfo.ts b/packages/module/src/types/TransactionInfo.ts similarity index 100% rename from packages/module/src/common/types/TransactionInfo.ts rename to packages/module/src/types/TransactionInfo.ts diff --git a/packages/module/src/common/types/UTxO.ts b/packages/module/src/types/UTxO.ts similarity index 100% rename from packages/module/src/common/types/UTxO.ts rename to packages/module/src/types/UTxO.ts diff --git a/packages/module/src/common/types/Wallet.ts b/packages/module/src/types/Wallet.ts similarity index 100% rename from packages/module/src/common/types/Wallet.ts rename to packages/module/src/types/Wallet.ts diff --git a/packages/module/src/common/types/index.ts b/packages/module/src/types/index.ts similarity index 100% rename from packages/module/src/common/types/index.ts rename to packages/module/src/types/index.ts diff --git a/packages/module/src/wallet/app.service.ts b/packages/module/src/wallet/app.service.ts index c0cdcdb3b..6d43cfe4d 100644 --- a/packages/module/src/wallet/app.service.ts +++ b/packages/module/src/wallet/app.service.ts @@ -14,7 +14,7 @@ import { } from '@mesh/common/utils'; import { EmbeddedWallet } from './embedded.service'; import type { Address, TransactionUnspentOutput } from '@mesh/core'; -import type { DataSignature } from '@mesh/common/types'; +import type { DataSignature } from '@mesh/types'; const DEFAULT_PASSWORD = 'MARI0TIME'; diff --git a/packages/module/src/wallet/browser.service.ts b/packages/module/src/wallet/browser.service.ts index 1b24aab9b..d56433147 100644 --- a/packages/module/src/wallet/browser.service.ts +++ b/packages/module/src/wallet/browser.service.ts @@ -28,7 +28,7 @@ import type { DataSignature, UTxO, Wallet, -} from '@mesh/common/types'; +} from '@mesh/types'; export class BrowserWallet implements IInitiator, ISigner, ISubmitter { walletInstance: WalletInstance; @@ -290,20 +290,20 @@ export class BrowserWallet implements IInitiator, ISigner, ISubmitter { } } -declare global { - interface Window { - cardano: Cardano; - } -} - -type Cardano = { - [key: string]: { - name: string; - icon: string; - apiVersion: string; - enable: () => Promise; - }; -}; +// declare global { +// interface Window { +// cardano: Cardano; +// } +// } + +// type Cardano = { +// [key: string]: { +// name: string; +// icon: string; +// apiVersion: string; +// enable: () => Promise; +// }; +// }; type TransactionSignatureRequest = { cbor: string; diff --git a/packages/module/src/wallet/embedded.service.ts b/packages/module/src/wallet/embedded.service.ts index c506c61b1..5abd672cc 100644 --- a/packages/module/src/wallet/embedded.service.ts +++ b/packages/module/src/wallet/embedded.service.ts @@ -2,38 +2,64 @@ import { generateMnemonic, mnemonicToEntropy } from 'bip39'; import { customAlphabet } from 'nanoid'; import { csl, deriveAccountKeys, signMessage } from '@mesh/core'; import { - buildBaseAddress, buildBip32PrivateKey, - buildRewardAddress, buildEnterpriseAddress, - deserializeTx, deserializeTxHash, fromBytes, - fromUTF8, resolveTxHash, + buildBaseAddress, + buildBip32PrivateKey, + buildRewardAddress, + buildEnterpriseAddress, + deserializeTx, + deserializeTxHash, + fromBytes, + fromUTF8, + resolveTxHash, } from '@mesh/common/utils'; import type { - Address, Certificates, Ed25519KeyHashes, - Message, NativeScripts, PrivateKey, Signer, - TransactionBody, TransactionInputs, TransactionWitnessSet, - Vkeywitnesses, Withdrawals, + Address, + Certificates, + Ed25519KeyHashes, + Message, + NativeScripts, + PrivateKey, + Signer, + TransactionBody, + TransactionInputs, + TransactionWitnessSet, + Vkeywitnesses, + Withdrawals, } from '@mesh/core'; -import type { Account, DataSignature, UTxO } from '@mesh/common/types'; +import type { Account, DataSignature, UTxO } from '@mesh/types'; export class EmbeddedWallet { constructor( private readonly _networkId: number, - private readonly _encryptedSecret: string | [string, string], + private readonly _encryptedSecret: string | [string, string] ) {} getAccount(accountIndex: number, password: string): Account { - return this.accountContext(accountIndex, password, (paymentKey, stakeKey) => { - const baseAddress = buildBaseAddress( - this._networkId, paymentKey.to_public().hash(), stakeKey.to_public().hash(), - ).to_address().to_bech32(); - - const enterpriseAddress = buildEnterpriseAddress( - this._networkId, paymentKey.to_public().hash(), - ).to_address().to_bech32(); - - const rewardAddress = buildRewardAddress( - this._networkId, stakeKey.to_public().hash(), - ).to_address().to_bech32(); + return this.accountContext( + accountIndex, + password, + (paymentKey, stakeKey) => { + const baseAddress = buildBaseAddress( + this._networkId, + paymentKey.to_public().hash(), + stakeKey.to_public().hash() + ) + .to_address() + .to_bech32(); + + const enterpriseAddress = buildEnterpriseAddress( + this._networkId, + paymentKey.to_public().hash() + ) + .to_address() + .to_bech32(); + + const rewardAddress = buildRewardAddress( + this._networkId, + stakeKey.to_public().hash() + ) + .to_address() + .to_bech32(); return { baseAddress, @@ -45,23 +71,32 @@ export class EmbeddedWallet { } signData( - accountIndex: number, password: string, - address: string, payload: string, + accountIndex: number, + password: string, + address: string, + payload: string ): DataSignature { try { - return this.accountContext(accountIndex, password, (paymentKey, stakeKey) => { + return this.accountContext( + accountIndex, + password, + (paymentKey, stakeKey) => { const message: Message = { payload }; const signer: Signer = { address: EmbeddedWallet.resolveAddress( - this._networkId, address, paymentKey, stakeKey + this._networkId, + address, + paymentKey, + stakeKey ), key: address.startsWith('stake') ? stakeKey : paymentKey, }; - const { - coseSign1: signature, coseKey: key - } = signMessage(message, signer); + const { coseSign1: signature, coseKey: key } = signMessage( + message, + signer + ); return { signature, key }; } @@ -72,18 +107,24 @@ export class EmbeddedWallet { } signTx( - accountIndex: number, password: string, utxos: UTxO[], - unsignedTx: string, partialSign: boolean, + accountIndex: number, + password: string, + utxos: UTxO[], + unsignedTx: string, + partialSign: boolean ): Vkeywitnesses { try { - const txHash = deserializeTxHash( - resolveTxHash(unsignedTx) - ); + const txHash = deserializeTxHash(resolveTxHash(unsignedTx)); - return this.accountContext(accountIndex, password, (paymentKey, stakeKey) => { + return this.accountContext( + accountIndex, + password, + (paymentKey, stakeKey) => { const signatures = csl.Vkeywitnesses.new(); const signers = EmbeddedWallet.resolveSigners( - unsignedTx, utxos, paymentKey.to_public().hash().to_hex() + unsignedTx, + utxos, + paymentKey.to_public().hash().to_hex() ); signers.forEach((tkh: string) => { @@ -124,14 +165,18 @@ export class EmbeddedWallet { } static encryptSigningKeys( - cborPaymentKey: string, cborStakeKey: string, password: string, + cborPaymentKey: string, + cborStakeKey: string, + password: string ): [string, string] { const encryptedPaymentKey = EmbeddedWallet.encrypt( - cborPaymentKey.slice(4), password, + cborPaymentKey.slice(4), + password ); const encryptedStakeKey = EmbeddedWallet.encrypt( - cborStakeKey.slice(4), password, + cborStakeKey.slice(4), + password ); return [encryptedPaymentKey, encryptedStakeKey]; @@ -143,11 +188,14 @@ export class EmbeddedWallet { } private accountContext( - accountIndex: number, password: string, - callback: (paymentKey: PrivateKey, stakeKey: PrivateKey) => T, + accountIndex: number, + password: string, + callback: (paymentKey: PrivateKey, stakeKey: PrivateKey) => T ): T { const { paymentKey, stakeKey } = EmbeddedWallet.resolveKeys( - accountIndex, password, this._encryptedSecret, + accountIndex, + password, + this._encryptedSecret ); const result = callback(paymentKey, stakeKey); @@ -160,9 +208,7 @@ export class EmbeddedWallet { private static decrypt(data: string, password: string): string { try { - return csl.decrypt_with_password( - fromUTF8(password), data, - ); + return csl.decrypt_with_password(fromUTF8(password), data); } catch (error) { throw new Error('The password is incorrect.'); } @@ -172,43 +218,44 @@ export class EmbeddedWallet { const generateRandomHex = customAlphabet('0123456789abcdef'); const salt = generateRandomHex(64); const nonce = generateRandomHex(24); - return csl.encrypt_with_password( - fromUTF8(password), salt, nonce, data, - ); + return csl.encrypt_with_password(fromUTF8(password), salt, nonce, data); } private static resolveAddress( - networkId: number, bech32: string, - payment: PrivateKey, stake: PrivateKey, + networkId: number, + bech32: string, + payment: PrivateKey, + stake: PrivateKey ): Address { const address = [ - buildBaseAddress(networkId, payment.to_public().hash(), stake.to_public().hash()), + buildBaseAddress( + networkId, + payment.to_public().hash(), + stake.to_public().hash() + ), buildEnterpriseAddress(networkId, payment.to_public().hash()), buildRewardAddress(networkId, stake.to_public().hash()), ].find((a) => a.to_address().to_bech32() === bech32); - if (address !== undefined) - return address.to_address(); + if (address !== undefined) return address.to_address(); throw new Error(`Address: ${bech32} doesn't belong to this account.`); } private static resolveKeys( - accountIndex: number, password: string, - encryptedSecret: string | [string, string], - ): { paymentKey: PrivateKey; stakeKey: PrivateKey; } { + accountIndex: number, + password: string, + encryptedSecret: string | [string, string] + ): { paymentKey: PrivateKey; stakeKey: PrivateKey } { if (typeof encryptedSecret === 'string') { - const rootKey = EmbeddedWallet - .decrypt(encryptedSecret, password); + const rootKey = EmbeddedWallet.decrypt(encryptedSecret, password); return deriveAccountKeys(rootKey, accountIndex); } - const cborPaymentKey = EmbeddedWallet - .decrypt(encryptedSecret[0], password); + const cborPaymentKey = EmbeddedWallet.decrypt(encryptedSecret[0], password); - const cborStakeKey = EmbeddedWallet - .decrypt(encryptedSecret[1], password); + const cborStakeKey = EmbeddedWallet.decrypt(encryptedSecret[1], password); return { paymentKey: csl.PrivateKey.from_hex(cborPaymentKey), @@ -217,8 +264,9 @@ export class EmbeddedWallet { } private static resolveSigners( - cborTx: string, utxos: UTxO[], - paymentKeyHash: string, + cborTx: string, + utxos: UTxO[], + paymentKeyHash: string ): Set { const resolveTxBodySigners = (txBody: TransactionBody) => { const resolveCertificatesSigners = ( @@ -233,49 +281,43 @@ export class EmbeddedWallet { const cSigners = new Array(); switch (c.kind()) { case csl.CertificateKind.StakeDeregistration: { - const credential = c.as_stake_deregistration() - ?.stake_credential(); + const credential = c.as_stake_deregistration()?.stake_credential(); const keyHash = credential?.kind() === csl.StakeCredKind.Key ? credential.to_keyhash() : undefined; - if (keyHash) - cSigners.push(keyHash.to_hex()); + if (keyHash) cSigners.push(keyHash.to_hex()); break; } case csl.CertificateKind.StakeDelegation: { - const credential = c.as_stake_delegation() - ?.stake_credential(); + const credential = c.as_stake_delegation()?.stake_credential(); const keyHash = credential?.kind() === csl.StakeCredKind.Key ? credential.to_keyhash() : undefined; - if (keyHash) - cSigners.push(keyHash.to_hex()); + if (keyHash) cSigners.push(keyHash.to_hex()); break; } case csl.CertificateKind.PoolRegistration: { - const poolOwners = c.as_pool_registration() + const poolOwners = c + .as_pool_registration() ?.pool_params() .pool_owners(); - cSigners.push( - ...resolveRequiredSigners(poolOwners) - ); + cSigners.push(...resolveRequiredSigners(poolOwners)); break; } case csl.CertificateKind.PoolRetirement: { - const poolKeyhash = c.as_pool_retirement() - ?.pool_keyhash(); + const poolKeyhash = c.as_pool_retirement()?.pool_keyhash(); - if (poolKeyhash) - cSigners.push(poolKeyhash.to_hex()); + if (poolKeyhash) cSigners.push(poolKeyhash.to_hex()); break; } case csl.CertificateKind.MoveInstantaneousRewardsCert: { - const credentials = c.as_move_instantaneous_rewards_cert() + const credentials = c + .as_move_instantaneous_rewards_cert() ?.move_instantaneous_reward() .as_to_stake_creds(); @@ -287,26 +329,26 @@ export class EmbeddedWallet { ? credential.to_keyhash() : undefined; - if (keyHash) - cSigners.push(keyHash.to_hex()); + if (keyHash) cSigners.push(keyHash.to_hex()); } } break; } } - return resolveCertificatesSigners(certificates, - [...signers, ...cSigners], index + 1, + return resolveCertificatesSigners( + certificates, + [...signers, ...cSigners], + index + 1 ); }; const resolveTxInputsSigners = ( inputs: TransactionInputs | undefined, signers: string[] = [], - index = 0, + index = 0 ): string[] => { - if (inputs === undefined || index >= inputs.len()) - return signers; + if (inputs === undefined || index >= inputs.len()) return signers; const inputIndex = inputs.get(index).index(); const inputHash = inputs.get(index).transaction_id(); @@ -320,28 +362,27 @@ export class EmbeddedWallet { ? paymentKeyHash : 'OUR_PRINCESS_IS_IN_ANOTHER_CASTLE'; - return resolveTxInputsSigners(inputs, - [...signers, signer], index + 1, - ); + return resolveTxInputsSigners(inputs, [...signers, signer], index + 1); }; const resolveRequiredSigners = ( keyHashes: Ed25519KeyHashes | undefined, signers: string[] = [], - index = 0, + index = 0 ): string[] => { - if (keyHashes === undefined || index >= keyHashes.len()) - return signers; + if (keyHashes === undefined || index >= keyHashes.len()) return signers; - return resolveRequiredSigners(keyHashes, - [...signers, keyHashes.get(index).to_hex()], index + 1, + return resolveRequiredSigners( + keyHashes, + [...signers, keyHashes.get(index).to_hex()], + index + 1 ); }; const resolveWithdrawalsSigners = ( withdrawals: Withdrawals | undefined, signers: string[] = [], - index = 0, + index = 0 ): string[] => { if (withdrawals === undefined || index >= withdrawals.len()) return signers; @@ -352,8 +393,10 @@ export class EmbeddedWallet { ? credential.to_keyhash() : undefined; - return resolveWithdrawalsSigners(withdrawals, - keyHash ? [...signers, keyHash.to_hex()] : signers, index + 1, + return resolveWithdrawalsSigners( + withdrawals, + keyHash ? [...signers, keyHash.to_hex()] : signers, + index + 1 ); }; @@ -373,11 +416,11 @@ export class EmbeddedWallet { }; const resolveTxWitnessSetSigners = ( - txWitnessSet: TransactionWitnessSet, + txWitnessSet: TransactionWitnessSet ) => { const resolveNativeScriptsSigners = ( scripts: NativeScripts | undefined, - signers: string[] = [], + signers: string[] = [] ): string[] => { if (scripts) { for (let index = 0; index < scripts.len(); index += 1) { @@ -390,17 +433,17 @@ export class EmbeddedWallet { case csl.NativeScriptKind.ScriptAll: return resolveNativeScriptsSigners( ns.as_script_all()?.native_scripts(), - signers, + signers ); case csl.NativeScriptKind.ScriptAny: return resolveNativeScriptsSigners( ns.as_script_any()?.native_scripts(), - signers, + signers ); case csl.NativeScriptKind.ScriptNOfK: return resolveNativeScriptsSigners( ns.as_script_n_of_k()?.native_scripts(), - signers, + signers ); } } @@ -410,9 +453,7 @@ export class EmbeddedWallet { const nativeScripts = txWitnessSet.native_scripts(); - return [ - ...resolveNativeScriptsSigners(nativeScripts), - ]; + return [...resolveNativeScriptsSigners(nativeScripts)]; }; const tx = deserializeTx(cborTx); diff --git a/packages/module/src/wallet/mina.service.ts b/packages/module/src/wallet/mina.service.ts index f886a3ddb..16ae4dcff 100644 --- a/packages/module/src/wallet/mina.service.ts +++ b/packages/module/src/wallet/mina.service.ts @@ -1,5 +1,5 @@ import axios from 'axios'; -import type { UTxO } from '@mesh/common/types'; +import type { UTxO } from '@mesh/types'; import { deserializeTx } from '@mesh/common/utils'; import { csl } from '@mesh/core'; const minaFrontendUrl = 'http://localhost:4000/';