diff --git a/package-lock.json b/package-lock.json index 07a001a..24c9299 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@indigo-labs/dexter", - "version": "4.2.1", + "version": "5.0.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@indigo-labs/dexter", - "version": "4.2.1", + "version": "5.0.3", "license": "MIT", "dependencies": { "@types/crypto-js": "^4.1.1", @@ -15,7 +15,7 @@ "bottleneck": "^2.19.5", "crypto-js": "^4.1.1", "lodash": "^4.17.21", - "lucid-cardano": "^0.8.7" + "lucid-cardano": "^0.10.7" }, "devDependencies": { "@babel/core": "^7.21.4", @@ -5754,9 +5754,9 @@ } }, "node_modules/lucid-cardano": { - "version": "0.8.9", - "resolved": "https://registry.npmjs.org/lucid-cardano/-/lucid-cardano-0.8.9.tgz", - "integrity": "sha512-2deXHPB12/1yMSRFYk0qmiqazvN0V+HLeEFyYsUyIjuzwk8F72mC8ZsjUjPt9NeWgySuyPivPFjXt3jSrG+iIA==", + "version": "0.10.7", + "resolved": "https://registry.npmjs.org/lucid-cardano/-/lucid-cardano-0.10.7.tgz", + "integrity": "sha512-hxJRMWj8VH+SGFqsVMG6T3LSRuxzwFbWOQ5DTGQQUyR/20FL7bjiVL+2ivMJF52tAbFKcwqpRD4fddR7LbqcAw==", "dependencies": { "@peculiar/webcrypto": "^1.4.0", "node-fetch": "^3.2.3", diff --git a/package.json b/package.json index 2f57187..bad6db1 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "bottleneck": "^2.19.5", "crypto-js": "^4.1.1", "lodash": "^4.17.21", - "lucid-cardano": "^0.8.7" + "lucid-cardano": "^0.10.7" }, "devDependencies": { "@babel/core": "^7.21.4", diff --git a/src/dex/api/base-api.ts b/src/dex/api/base-api.ts index ba83043..f390c4f 100644 --- a/src/dex/api/base-api.ts +++ b/src/dex/api/base-api.ts @@ -11,6 +11,6 @@ export abstract class BaseApi { /** * Fetch all liquidity pools matching assetA & assetB. */ - abstract liquidityPools(assetA: Token, assetB?: Token): Promise; + abstract liquidityPools(assetA?: Token, assetB?: Token): Promise; -} \ No newline at end of file +} diff --git a/src/dex/api/spectrum-api.ts b/src/dex/api/spectrum-api.ts index 6e82199..7c27a31 100644 --- a/src/dex/api/spectrum-api.ts +++ b/src/dex/api/spectrum-api.ts @@ -4,15 +4,14 @@ import { LiquidityPool } from '../models/liquidity-pool'; import axios, { AxiosInstance } from 'axios'; import { RequestConfig } from '@app/types'; import { appendSlash, tokensMatch } from '@app/utils'; -import { TeddySwap } from '@dex/teddyswap'; import { Spectrum } from '@dex/spectrum'; export class SpectrumApi extends BaseApi { protected readonly api: AxiosInstance; - protected readonly dex: TeddySwap; + protected readonly dex: Spectrum; - constructor(dex: TeddySwap, requestConfig: RequestConfig) { + constructor(dex: Spectrum, requestConfig: RequestConfig) { super(); this.dex = dex; diff --git a/src/dex/api/vyfinance-api.ts b/src/dex/api/vyfinance-api.ts index 78cbcad..17c0852 100644 --- a/src/dex/api/vyfinance-api.ts +++ b/src/dex/api/vyfinance-api.ts @@ -24,15 +24,15 @@ export class VyfinanceApi extends BaseApi { }); } - liquidityPools(assetA: Token, assetB?: Token): Promise { - const assetAId: string = (assetA === 'lovelace') - ? 'lovelace' - : assetA.identifier(); + liquidityPools(assetA?: Token, assetB?: Token): Promise { + const assetAId: string = (assetA && assetA !== 'lovelace') + ? assetA.identifier() + : 'lovelace'; let assetBId: string = (assetB && assetB !== 'lovelace') ? assetB.identifier() : 'lovelace'; - const url: string = assetB + const url: string = assetA && assetB ? `/lp?networkId=1&v2=true&tokenAUnit=${assetAId}&tokenBUnit=${assetBId}` : '/lp?networkId=1&v2=true'; @@ -48,12 +48,13 @@ export class VyfinanceApi extends BaseApi { ? new Asset(poolDetails['bAsset']['currencySymbol'], Buffer.from(poolDetails['bAsset']['tokenName']).toString('hex')) : 'lovelace'; + let liquidityPool: LiquidityPool = new LiquidityPool( VyFinance.identifier, tokenA, tokenB, - BigInt(pool['tokenAQuantity']), - BigInt(pool['tokenBQuantity']), + BigInt(pool['tokenAQuantity'] ?? 0), + BigInt(pool['tokenBQuantity'] ?? 0), pool['poolValidatorUtxoAddress'], pool['orderValidatorUtxoAddress'], pool['orderValidatorUtxoAddress'], @@ -63,10 +64,12 @@ export class VyfinanceApi extends BaseApi { liquidityPool.lpToken = new Asset(lpTokenDetails[0], lpTokenDetails[1]); liquidityPool.poolFeePercent = (poolDetails['feesSettings']['barFee'] + poolDetails['feesSettings']['liqFee']) / 100; liquidityPool.identifier = liquidityPool.lpToken.identifier(); + liquidityPool.extra.nft = new Asset(poolDetails['mainNFT']['currencySymbol'], poolDetails['mainNFT']['tokenName']); return liquidityPool; }).filter((pool: LiquidityPool | undefined) => pool !== undefined) as LiquidityPool[]; - }).catch(() => { + }).catch((e) => { + console.error(e) return []; }); } diff --git a/src/dex/base-dex.ts b/src/dex/base-dex.ts index 59e5b20..c7366ec 100644 --- a/src/dex/base-dex.ts +++ b/src/dex/base-dex.ts @@ -1,7 +1,7 @@ import { LiquidityPool } from './models/liquidity-pool'; import { BaseDataProvider } from '@providers/data/base-data-provider'; import { Asset, Token } from './models/asset'; -import { AssetBalance, DatumParameters, PayToAddress, SwapFee, UTxO } from '@app/types'; +import { AssetBalance, DatumParameters, PayToAddress, SpendUTxO, SwapFee, UTxO } from '@app/types'; import { DatumParameterKey } from '@app/constants'; import { tokensMatch } from '@app/utils'; import { BaseApi } from '@dex/api/base-api'; @@ -46,7 +46,7 @@ export abstract class BaseDex { /** * Craft a swap order for this DEX. */ - abstract buildSwapOrder(liquidityPool: LiquidityPool, swapParameters: DatumParameters, spendUtxos?: UTxO[]): Promise; + abstract buildSwapOrder(liquidityPool: LiquidityPool, swapParameters: DatumParameters, spendUtxos?: SpendUTxO[]): Promise; /** * Craft a swap order cancellation for this DEX. diff --git a/src/dex/minswap.ts b/src/dex/minswap.ts index 549ed62..477f58d 100644 --- a/src/dex/minswap.ts +++ b/src/dex/minswap.ts @@ -7,7 +7,7 @@ import { AssetBalance, DatumParameters, DefinitionConstr, DefinitionField, PayToAddress, - RequestConfig, + RequestConfig, SpendUTxO, SwapFee, UTxO } from '@app/types'; @@ -18,6 +18,7 @@ import order from '@dex/definitions/minswap/order'; import { BaseApi } from '@dex/api/base-api'; import { MinswapApi } from '@dex/api/minswap-api'; import pool from '@dex/definitions/minswap/pool'; +import { Script } from 'lucid-cardano'; export class Minswap extends BaseDex { @@ -32,6 +33,11 @@ export class Minswap extends BaseDex { public readonly lpTokenPolicyId: string = 'e4214b7cce62ac6fbba385d164df48e157eae5863521b4b67ca71d86'; public readonly poolNftPolicyId: string = '0be55d262b29f564998ff81efe21bdc0022621c12f15af08d0f2ddb1'; public readonly poolValidityAsset: string = '13aa2accf2e1561723aa26871e071fdf32c867cff7e7d50ad470d62f4d494e53574150'; + public readonly cancelDatum: string = 'd87a80'; + public readonly orderScript: Script = { + type: 'PlutusV1', + script: '59014f59014c01000032323232323232322223232325333009300e30070021323233533300b3370e9000180480109118011bae30100031225001232533300d3300e22533301300114a02a66601e66ebcc04800400c5288980118070009bac3010300c300c300c300c300c300c300c007149858dd48008b18060009baa300c300b3754601860166ea80184ccccc0288894ccc04000440084c8c94ccc038cd4ccc038c04cc030008488c008dd718098018912800919b8f0014891ce1317b152faac13426e6a83e06ff88a4d62cce3c1634ab0a5ec133090014a0266008444a00226600a446004602600a601a00626600a008601a006601e0026ea8c03cc038dd5180798071baa300f300b300e3754601e00244a0026eb0c03000c92616300a001375400660106ea8c024c020dd5000aab9d5744ae688c8c0088cc0080080048c0088cc00800800555cf2ba15573e6e1d200201', + }; constructor(requestConfig: RequestConfig = {}) { super(); @@ -177,7 +183,7 @@ export class Minswap extends BaseDex { return Number(priceImpactNumerator * 100n) / Number(priceImpactDenominator); } - public async buildSwapOrder(liquidityPool: LiquidityPool, swapParameters: DatumParameters, spendUtxos: UTxO[] = []): Promise { + public async buildSwapOrder(liquidityPool: LiquidityPool, swapParameters: DatumParameters, spendUtxos: SpendUTxO[] = []): Promise { const batcherFee: SwapFee | undefined = this.swapOrderFees().find((fee: SwapFee) => fee.id === 'batcherFee'); const deposit: SwapFee | undefined = this.swapOrderFees().find((fee: SwapFee) => fee.id === 'deposit'); @@ -232,7 +238,12 @@ export class Minswap extends BaseDex { addressType: AddressType.Base, assetBalances: relevantUtxo.assetBalances, isInlineDatum: false, - spendUtxos: [relevantUtxo], + spendUtxos: [{ + utxo: relevantUtxo, + redeemer: this.cancelDatum, + validator: this.orderScript, + signer: returnAddress, + }], } ]; } diff --git a/src/dex/muesliswap.ts b/src/dex/muesliswap.ts index 2c008eb..9463d0e 100644 --- a/src/dex/muesliswap.ts +++ b/src/dex/muesliswap.ts @@ -6,7 +6,7 @@ import { DefinitionConstr, DefinitionField, PayToAddress, - RequestConfig, + RequestConfig, SpendUTxO, SwapFee, UTxO } from '@app/types'; @@ -20,6 +20,7 @@ import pool from '@dex/definitions/muesliswap/pool'; import order from '@dex/definitions/muesliswap/order'; import { BaseApi } from '@dex/api/base-api'; import { MuesliSwapApi } from '@dex/api/muesliswap-api'; +import { Script } from 'lucid-cardano'; export class MuesliSwap extends BaseDex { @@ -34,6 +35,11 @@ export class MuesliSwap extends BaseDex { public readonly poolNftPolicyIdV1: string = '909133088303c49f3a30f1cc8ed553a73857a29779f6c6561cd8093f'; public readonly poolNftPolicyIdV2: string = '7a8041a0693e6605d010d5185b034d55c79eaf7ef878aae3bdcdbf67'; public readonly factoryToken: string = 'de9b756719341e79785aa13c164e7fe68c189ed04d61c9876b2fe53f4d7565736c69537761705f414d4d'; + public readonly cancelDatum: string = 'd87980'; + public readonly orderScript: Script = { + type: 'PlutusV2', + script: '59152a010000323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323223232323232322232323232323232323232533355333573460d000226464646424446600200a0086eb4d5d09aba2003355333573460d060da0022660a06eb4d5d098360009bad357426ae88c1b000458c1b88894ccd5cd18358008b0a999ab9a337100029000099801983500118350008991982a19b8400300133708004002660ce0040026ea8d5d080098350010a999ab9a306700113212223002004375a6ae84c1a800854ccd5cd18330008220b099180e1a9a805030911111111111299a999aa983583601892999ab9a3371e01c002260c80020c400840d20c2a020426038660946010002660946603a666aa60b40c06a0340c26a0340c4666aa60b40c044a66a6a0044444a66a6605060a4030008260ba0060b642660c200200420020ba60546a0140c2660366660486a01e0c26a01e0c460460246660486a01e0c26a01e0c466604c6a0120886a01e0c26a01e0c4660946008a0226020a00a4426464646464646046660a2601e00e660a2603e032660a2602ea018660a26016a030660a26a01044666ae68cdc499b8200248008cdc1240000020be0cc660a26a0104426ae68cdc419b8200248008cdc1011000998289982899814982980c98298029982899827981d00c981d0029982899827981700c98170029982899827980e00c980e0029982899827980e80c980e802a99a980f80c88020a99a80202e031998289a9980f1a804111919191982d99b8400300133708004002660dc00400266e0808c008cdc099b8202200133704004044660ac60540329001112999ab9a3370e00a0042660760440020bc66048660446a00c0d26660560040026a6a6603c010660ac66605a6a0200960040029001111982c19b84002001330583370a0040020020d0660446a0200966660566a02c0d06a02c0d26a6603c660ac6054032900100438435014068350130663027002301b00135001063533553353500b22350022222222222223333500d206620662066233355306f070035235001225335330470020041306a00306800d2135001223500122223501222350022222222222223335530700762235002222253353303e01800413307a006005100507300a16162215335001133052300a00235002204a2216306a00137540144666aa60b80ba604a04c400266aa60b00ba46a00244446a0084466a0044a666ae68cdc78048008a999a80282d102d90a99a9981a0009a80803390a99a9999999aba40012325333573460e060ea0022646666aae7c00481848cccd55cf9aba2002253353039357420064260c82460020040c240c40d60d460e80020bc6ea8008817881788178817819c84cc140d4004800522010f4d7565736c69537761705f76322e320005c05b061206230273500705e13306822533500105922132533553353035303735003062215335007213304a00200105615335006205605c15335333049034350030613500922200113305e30073500306200110011001300400130313500505c30513500304025333535001203f16216215335330290013500505c21533533333335748002464a666ae68c194c1a80044c8cccd55cf800902b11999aab9f35744004464a66a6666666ae900048c94ccd5cd183598380008991999aab9f001205c23233335573e00240bc4646666aae7c00481808c8cccd55cf80090311191999aab9f001206423233335573e00240cc4646666aae7c00481a08c8cccd55cf800903511999aab9f35744004464a66aa66aa66aa66aa66aa66aa66aa66a6666666ae900048c94ccd5cd183f9842008008991999aab9f001207023233335573e00240e446666aae7cd5d10011299a98241aba1005213253353333333574800246464a666ae68c224040044cccd55cf984680801103c91999aab9f35744611c02006464a66a6666666ae900048c8c94ccd5cd18480080089999aab9f309301002207f23233335573e0024102024646666aae7c004820c048cccd55cf9aba200225335305a3574261320201042a66a60b66ae84018854cd4c170d5d0802909844009998410080180100084280842008418090420084680846009aba200208a0135744612802006110022a666ae68c23c040044cccd55cf984980801103f91999aab9f357446128020064a66a60aa6ae84c2540401084c20804c208040041fc82000422404220041f4c24c04004dd5001103e103e103e103e0428090983e983e80083d1aba1308f01004207a083010820115333573461140200226666aae7cc234040088c1e81e481e4208041dcc23404004dd5001103b103b103b103b03f90983b9983780180083a1aba1004072207307c07b357440040f26106020020da6ea800881b481b481b481b41d884c1b8c1bc0041ac854cd4c110d5d0808909837980100083603590a99a98221aba100f21306f300200106c06b21533530443574201a4260de60040020d80d642a66a60886ae8402c84c1bcc0080041b01ac854cd4c10cd5d080490983798010008360359099299a9999999aba4001232325333573461060200226666aae7cc218040088c1cc1e481c81ec54ccd5cd18410080089999aab9f30860100223073072207207b070308601001375400440de40de40de40de0f04260e060060020da6ae8401c1ac854cd4c10cd5d080290983798010008360359aba1011206b074073357440040e26ae880081bcd5d10010369aba200206b357440040d26ae8800819cd5d1001032983780082c9baa002205920592059205906221305a305c0010573574200640ae0c00be60d20020a66ea8008814c814c814c814c17084d4004800458588c8d4d4d401016c888818888d40048c894ccd54ccd4018854ccd4010854ccd402084c0140c44c0100c054ccd401484c0140c44c0100c011810c54ccd401c84c0100c04c00c0bc54ccd401084c0100c04c00c0bc11454ccd400c810811010454ccd400c854ccd401c84c0100c04c00c0bc54ccd401084c0100c04c00c0bc11410854ccd401884c00c0bc4c0080b854ccd400c84c00c0bc4c0080b811054cd400415016c16c15094ccd4008854ccd4018854ccd401084ccc0d00c400800458585810854ccd4014854ccd400c84ccc0cc0c0008004585858104100c100ccc198888c94ccd5cd19b87003371a002200426600866e0000d20023370066e080092080043371c002006a66a660d244a66a0020a64426a00444a666ae68cdc78012451c5817c34e5702473304f3cf676299176d3824e55b8c0bfa94830429fd001305900113006003353533533069221225333573466e2000520001615335002162215333573460d20062004266a600c0c400266e0400d200205c30323500605d00405e204321533500116221350022253350031002221616480012000350012233335001262626232533530303032001213212333001003002005350022043163330672225335002162213500222533533035002005100113300700300530303500405b0015333573460ba60c400226464642466002006004606c6ae84d5d11831801a999ab9a305e3063001132323232323232323232323232323232323232323232321233333333333300101801601401201000e00c009007005003002304e357426ae88008ccc121d710009aba10013574400466608c09040026ae84004d5d100119822bae357420026ae8800d4ccd5cd1836983900089919191909198008020012999ab9a307030750011330583304175a6ae84c1d0004c158d5d09aba230740011637546ae84d5d11839801a999ab9a306e30730011323212330010030023055357426ae88c1cc008cc0fdd69aba130720011637546ae84c1c400458dd51aba10013574400466607e0a6eb4d5d08009aba20023303e040357420026ae88008ccc0edd701d1aba100135744004666072eb80e0d5d08009aba200233038035357420026ae88008cc0d80c8d5d08009aba23063002330340303574260c40022c6ea8d5d098308008b1baa00133041300700430080043304030240033018003305d22533500104e2213303e33303d03c303f3040002500530040011303a303b001355333573460aa60b40022646090a666ae68c158c16c0044c8c8c8c8c8c8cccccccc134c10cd5d098300039bae3574200c6eb8d5d08029bae357420086eb8d5d08019bad3574200460846ae84004dd69aba1357440026ae88004d5d10009aba2001357440026ae88004d5d1182d0008b1baa3574260b20022c40026ea80048d40041408d4004814488d400888d400c88c8c8c8cc104cdc200100099b84003001330540010023370400a00666e0800c0048d4004888880c9200233035001043223355304204723500122330390023355304504a235001223303c0023335001370090003802337000029000000998028010009299a8008890008b11199aa9822022980680711a80091199aa9823824180800891a80091199a80091980ea400000203846603a0029000000998018010009119aa981f82211a800911981b001199a800919aa982182411a800911981d001181900080091199804018801000919aa982182411a800911981d0011806000800999801816001000911199aa981f02202119aa981f82211a800911981b0011817000999aa981f022111a80111299a999aa98238241981b91199805025801000980402511a8009119805001002803080189982300200182080099aa981f82211a800911981b0011982a11299a800898050019109a80111299a9980600100408911198010050020980300180200111980091299a80101f880081b909111800802111a801111a801911919a802919a80212999ab9a3371e004002006078407a466a008407a4a666ae68cdc780100080181e0a99a80190a99a8011099a801119a801119a801119a8011198190010009020119a801102011981900100091102011119a80210201112999ab9a3370e00c0062a666ae68cdc380280109980f00200082082081d0a99a800901d02011a800911110149111981e998170019981e9981700100081e01e1981511299a801108018800818911198251119a800a4000446a00444a666ae68cdc78010040998281119a800a4000446a00444a666ae68cdc78010068800898030018008980300180191a8009111111100311981411199a80181e0010009a80081d891980081101a91a80091111111111100511999999aba40012323253335734608200226666aae7cc11000880c08cccd55cf9aba2304500325335300835742608c008426066605e00206040620740722a666ae68c1000044cccd55cf9822001101811999aab9f35744608a0064a66a60106ae84c11801084c0ccc0cc0040c080c40e80e40b8c110004dd5001101690169016901681b11999999aba4001202c202c202c2302d375a004405806a46666666ae9000480ac80ac80ac80ac8c0b0dd700101a111a8009111111111111982691299a80081b9109a801112999ab9a3371e0040282607a0022600c006004930919999999800801912999ab9a3370e0040020302a666ae68cdc480100080a80b1109ab9a337100040024426ae68cdc480100091199ab9a3371200400205206000444a666ae68cdc480100088008801112999ab9a337120040022004200244666ae68cdc40010008138171109ab9a3370e00400246a0024444444400e44a666ae68cdc79a8010179a800817889ab9a3370e6a0040606a00206004646a0024466a004404a04a46a00244444444444401846a0024444008446464a666ae68c0d400403854ccd5cd181a0008980998021aba13037002153335734606600201e2c606e0026ea80048c94ccd5cd1818181a80089919091980080180118021aba135744606a00460126ae84c0d000458dd50009192999ab9a302f3034001132323232323232321233330010090070030023302375c6ae84d5d10022999ab9a3037001132122230020043574260720042a666ae68c0d80044c84888c004010dd71aba13039002153335734606a0020262c60720026ea8d5d08009aba200233300675c00a6ae84004d5d1181a001180b1aba1303300116375400266002eb9d69111981a111999aab9f0012027232330293301a30073037001300630360013004357440066ae840080a4dd58009119819111999aab9f001202523302630053574200460066ae8800809cdd6000919192999ab9a302f00113212222300400530043574260600042a666ae68c0b80044c848888c008014c054d5d098180010a999ab9a302d00113212222300100530053574260600042a666ae68c0b00044c848888c00c014dd71aba13030002163030001375400246464a666ae68cdc3a401800222444401c2a666ae68cdc3a4014002220522a666ae68cdc3a40100022646424444444660020120106eb4d5d09aba23030003375c6ae84c0bc00854ccd5cd18170008991909111111198010048041bae357426ae88c0c000cdd71aba1302f002153335734605a00226464244444446600c0120106eb8d5d09aba23030003301435742605e0042a666ae68c0b00044c848888888c01c020c050d5d098178010a999ab9a302b001132122222223005008301435742605e0042c605e0026ea80048c94ccd5cd181498170008991909198008018011bad357426ae88c0b8008c00cd5d098168008b1baa001232533357346050605a00226eb8d5d098160008b1baa0011122200111001222002110012220032122230030042213573466e3c0080048894cd4cc00c00800403c058894cd400840040348d400488cd40088004988d4004888888880208c94ccd5cd180e8008088a999ab9a301c00100a1630203754002464a666ae68c06cc0800044cc00cc018d5d0980f800998040021aba135744603e0022c6ea80048848cc00400c0088c8c94ccd5cd180d8008991998029bad35742603e0066eb4d5d08009bad357426ae88004d5d1180f0010a999ab9a301a0011300a300535742603c0042c603c0026ea8004888488ccc00401401000c8c8c94ccd5cd180c800898021bae3574260380042a666ae68c0600044c020dd71aba1301c00216301c001375400242446002006446464a666ae68c05c0044c01cc010d5d0980d8010a999ab9a301800100516301b0013754002200220184244600400644444444246666666600201201000e00c00a008006004424600200460264422444a66a00220044426600a004666aa600e01a00a0080026024442244a66a00200a44266012600800466aa600c016008002200220084424466002008006601c4422444a66a00226a006010442666a00a0126008004666aa600e01000a0080022400244004440026014444a666ae68c01c00440084cc00c004cdc30010009111111100291111110021b8148000dc3a40006e1d2002370e90021b874801955cf2ab9d23230010012233003300200200101', + }; constructor(requestConfig: RequestConfig = {}) { super(); @@ -164,7 +170,7 @@ export class MuesliSwap extends BaseDex { return(swapPrice - oldPrice) / oldPrice * 100; } - public async buildSwapOrder(liquidityPool: LiquidityPool, swapParameters: DatumParameters, spendUtxos: UTxO[] = []): Promise { + public async buildSwapOrder(liquidityPool: LiquidityPool, swapParameters: DatumParameters, spendUtxos: SpendUTxO[] = []): Promise { const matchMakerFee: SwapFee | undefined = this.swapOrderFees().find((fee: SwapFee): boolean => fee.id === 'matchmakerFee'); const deposit: SwapFee | undefined = this.swapOrderFees().find((fee: SwapFee): boolean => fee.id === 'deposit'); @@ -224,7 +230,12 @@ export class MuesliSwap extends BaseDex { addressType: AddressType.Base, assetBalances: relevantUtxo.assetBalances, isInlineDatum: false, - spendUtxos: [relevantUtxo], + spendUtxos: [{ + utxo: relevantUtxo, + redeemer: this.cancelDatum, + validator: this.orderScript, + signer: returnAddress, + }], } ]; } diff --git a/src/dex/spectrum.ts b/src/dex/spectrum.ts index 268fdc4..1ec3910 100644 --- a/src/dex/spectrum.ts +++ b/src/dex/spectrum.ts @@ -8,7 +8,7 @@ import { DefinitionConstr, DefinitionField, PayToAddress, - RequestConfig, + RequestConfig, SpendUTxO, SwapFee, UTxO } from '@app/types'; @@ -19,6 +19,7 @@ import pool from './definitions/spectrum/pool'; import order from './definitions/spectrum/order'; import { correspondingReserves, tokensMatch } from '@app/utils'; import { SpectrumApi } from '@dex/api/spectrum-api'; +import { Script } from 'lucid-cardano'; const MAX_INT: bigint = 9_223_372_036_854_775_807n; @@ -31,6 +32,11 @@ export class Spectrum extends BaseDex { * On-Chain constants. */ public readonly orderAddress: string = 'addr1wynp362vmvr8jtc946d3a3utqgclfdl5y9d3kn849e359hsskr20n'; + public readonly cancelDatum: string = 'd8799f00000001ff'; + public readonly orderScript: Script = { + type: 'PlutusV2', + script: '5904f901000032323232323232323232323232323232323232323222253330143232323232323232323232323232323232323232323232323232323253330303370e90010010991919299981999b8753330333370e6eb4c0d0c0d403d2000148000520024800054cc090cdc399814805181a00e240042a66048664466ebcdd3981c0011ba730380013034004303400815330243370e666064444a666060002200426600666e00009200230380014800004d20041533024337126eb4c0d0c0d405800854cc0900044cccc8888cdc499b833370466e08cc0b403800c008004cdc019b823302d00e004483403ccdc100100099b8000648008c0d0078c0d0074dd6981a00b1bad303401b13322332303522533303200114a02a66607066ebcc0e400400c52889801181d0009ba90010023758606864606c606c606c606c606c002606a0286eb8c0d00614cc8cc0cc00452899191929981319b8f375c606c606e0046eb8c0d8c0dc0044cdc79bae3036002375c606c002606e04e606c002606603826666644444646466e24cdc099b81302900d375a00266e0ccdc10028020019814809a99981c191929981599b8f375c607660780046eb8c0ecc0f00044cdc79bae303b002375c60760026078058607600c26ea00144004dd424000606603a6eb4c0cc054004dd6981980c9bad303301853330313232325330253371e6eb8c0d4c0d8008dd7181a981b000899b8f375c606a0046eb8c0d4004c0d8098c0d4004c0c806c4cdc199b82001375a606402e66e04dd6981900b9bad30320181001337026604c01460620346604c00860620342c606600460540026ea8c0b8c0bc064dd599181718179818000981698170009817000998139bad302b00700a37566460566058605a002605460560026056002660486eb4c0a001401ccc88c8c8c94ccc0acc8c8c94ccc0b8cdc3a40040042646464a66606266e1d200000214a0266ebcdd38021ba70013034002302b001375400e2646464a66606266e1d200200214a0266ebcdd38021ba70013034002302b001375400e606200460500026ea8004400858c8c8c8c8c94ccc0bccdc3a4000004264646464a66606666e1d200000213232323253330373370e90010010b099ba548000004c0e8008c0c4004dd5000981a0008b181b00118168009baa001303000113374a9001015181900118148009baa001302c302d302e001302b302d0053756646464a66605866e1d2002002161533302c3371e6eb8c0b40040184c0b4c0b8c0bc01c58c0bc008c098004dd50009918151816000981498158019bae302700b302700a33022375a604c002008604c002604a002604a0206eb0c088008dd61810801181098108009810980f805180f800980f000980e800980e000980d800980d000980c800980c000980c002180b8008a4c2c4a66601600229000099980899baf300d3012001375200c6eb4c054c048dd5980a9809000a4000446660220040020062940cdd2a4000660026ea4008cc004dd48010042ba0489002232333004003375c601c0026eb8c038c03c004c03c004888cccc01000920002333300500248001d69bab00100323002375200244446601444a66600e002200a2a66601a66ebcc024c0380040184c010c044c0380044c008c03c00400555cfa5eb8155ce91299980299b8800248000584cc00c008004c0048894ccc014cdc3801240002600c00226600666e04009200230070012323002233002002001230022330020020015734ae855d1118011baa0015573c1', + }; constructor(requestConfig: RequestConfig = {}) { super(); @@ -156,7 +162,7 @@ export class Spectrum extends BaseDex { return (1 - (Number(reserveIn) / Number(reserveIn + swapInAmount))) * 100; } - public async buildSwapOrder(liquidityPool: LiquidityPool, swapParameters: DatumParameters, spendUtxos: UTxO[] = []): Promise { + public async buildSwapOrder(liquidityPool: LiquidityPool, swapParameters: DatumParameters, spendUtxos: SpendUTxO[] = []): Promise { const batcherFee: SwapFee | undefined = this.swapOrderFees().find((fee: SwapFee) => fee.id === 'batcherFee'); const deposit: SwapFee | undefined = this.swapOrderFees().find((fee: SwapFee) => fee.id === 'deposit'); const minReceive = swapParameters.MinReceive as bigint; @@ -211,8 +217,29 @@ export class Spectrum extends BaseDex { ]; } - public buildCancelSwapOrder(txOutputs: UTxO[], returnAddress: string): Promise { - throw new Error('Method not implemented.'); + public async buildCancelSwapOrder(txOutputs: UTxO[], returnAddress: string): Promise { + const relevantUtxo: UTxO | undefined = txOutputs.find((utxo: UTxO) => { + return utxo.address === this.orderAddress; + }); + + if (! relevantUtxo) { + return Promise.reject('Unable to find relevant UTxO for cancelling the swap order.'); + } + + return [ + { + address: returnAddress, + addressType: AddressType.Base, + assetBalances: relevantUtxo.assetBalances, + isInlineDatum: false, + spendUtxos: [{ + utxo: relevantUtxo, + redeemer: this.cancelDatum, + validator: this.orderScript, + signer: returnAddress, + }], + } + ]; } public swapOrderFees(): SwapFee[] { diff --git a/src/dex/sundaeswap.ts b/src/dex/sundaeswap.ts index 1416f4c..2159937 100644 --- a/src/dex/sundaeswap.ts +++ b/src/dex/sundaeswap.ts @@ -8,7 +8,7 @@ import { DefinitionConstr, DefinitionField, PayToAddress, - RequestConfig, + RequestConfig, SpendUTxO, SwapFee, UTxO } from '@app/types'; @@ -19,6 +19,7 @@ import pool from '@dex/definitions/sundaeswap/pool'; import order from '@dex/definitions/sundaeswap/order'; import { BaseApi } from '@dex/api/base-api'; import { SundaeSwapApi } from '@dex/api/sundaeswap-api'; +import { Script } from 'lucid-cardano'; export class SundaeSwap extends BaseDex { @@ -31,6 +32,11 @@ export class SundaeSwap extends BaseDex { public readonly orderAddress: string = 'addr1wxaptpmxcxawvr3pzlhgnpmzz3ql43n2tc8mn3av5kx0yzs09tqh8'; public readonly poolAddress: string = 'addr1w9qzpelu9hn45pefc0xr4ac4kdxeswq7pndul2vuj59u8tqaxdznu'; public readonly lpTokenPolicyId: string = '0029cb7c88c7567b63d1a512c0ed626aa169688ec980730c0473b913'; + public readonly cancelDatum: string = 'd87a80'; + public readonly orderScript: Script = { + type: 'PlutusV1', + script: '59084601000033233322232332232333222323332223322323332223233223233223332223333222233322233223322332233223332223322332233322232323232322222325335300b001103c13503d35303b3357389201035054350003c498ccc888c8c8c94cd4c05c0144d4c0680188888cd4c04c480048d4c0ed40188888888888cd4c078480048ccd5cd19b8f375c0020180440420066a6040006446a6048004446a605000444666aa60302400244a66a6a07c0044266a08c0020042002a0886466a002a088a08a2446600466a609000846a0820024a0806600400e00226a606ca002444444444466a6032240024646464666ae68cdc399991119191800802990009aa82c1119a9a826000a4000446a6aa08a00444a66a6050666ae68cdc78010048150148980380089803001990009aa82b9119a9a825800a4000446a6aa08800444a66a604e666ae68cdc7801003814814080089803001999aa81e3ae335503c75ceb4d4c084cccd5cd19b8735573aa006900011998119aba1500335742a00466a080eb8d5d09aba2500223505135304f33573892010350543100050499262220020183371491010270200035302801422220044800808007c4d5d1280089aab9e500113754002012264a66a6a070601a6aae78dd50008a81a910a99a9a81d0008a81b910a99a9a81e0008a81c910a99a9a81f0008a81d910a99a9a8200008a81e910a99a9a8210008a81f910a99a9a8220008a820910a99a9a8230008a821910a99a9a8240008a822910a99a9a8250008a823910a99a9a82600089999999999825981000a18100090080071810006181000500418100031810002001110a8259a980a1999ab9a3370e6aae754009200023301635742a0046ae84d5d1280111a8211a982019ab9c490103505431000414992622002135573ca00226ea8004cd40148c8c8c8c8cccd5cd19b8735573aa00890001199980d9bae35742a0086464646666ae68cdc39aab9d5002480008cc88cc08c008004c8c8c8cccd5cd19b8735573aa004900011991198148010009919191999ab9a3370e6aae754009200023302d304735742a00466a07a4646464646666ae68cdc3a800a4004466606a6eb4d5d0a8021bad35742a0066eb4d5d09aba2500323333573466e1d4009200023037304e357426aae7940188d4154d4c14ccd5ce2490350543100054499264984d55cea80189aba25001135573ca00226ea8004d5d09aba2500223504e35304c335738921035054310004d49926135573ca00226ea8004d5d0a80119a81cbae357426ae8940088d4128d4c120cd5ce249035054310004949926135573ca00226ea8004d5d0a80119a81abae357426ae8940088d4118d4c110cd5ce249035054310004549926135573ca00226ea8004d5d0a8019bad35742a00464646464646666ae68cdc3a800a40084605c646464646666ae68cdc3a800a40044606c6464646666ae68cdc39aab9d5002480008cc88cd40f8008004dd69aba15002375a6ae84d5d1280111a8289a982799ab9c491035054310005049926135573ca00226ea8004d5d09aab9e500423333573466e1d40092000233036304b35742a0086eb4d5d09aba2500423504e35304c335738921035054310004d499264984d55cea80109aab9e5001137540026ae84d55cf280291999ab9a3370ea0049001118169bad357426aae7940188cccd5cd19b875003480008ccc0bcc11cd5d0a8031bad35742a00a66a072eb4d5d09aba2500523504a353048335738920103505431000494992649926135573aa00626ae8940044d55cf280089baa001357426ae8940088d4108d4c100cd5ce249035054310004149926135744a00226ae8940044d55cf280089baa0010033350052323333573466e1d40052002201623333573466e1d40092000201623504035303e335738921035054310003f499264984d55ce9baa001002335005200100112001230023758002640026aa072446666aae7c004940c08cd40bcd5d080118019aba2002498c8004d540e088448894cd4d40bc0044008884cc014008ccd54c01c48004014010004c8004d540dc884894cd4d40b400440188854cd4c01cc01000840244cd4c01848004010004488008488004800488848ccc00401000c00880048848cc00400c00880044880084880048004888848cccc00401401000c00880048848cc00400c00880048848cc00400c00880048848cc00400c00880048488c00800c888488ccc00401401000c800484888c00c0108884888ccc00801801401084888c00401080048488c00800c88488cc00401000c800448848cc00400c008480044488c88c008dd5800990009aa80d11191999aab9f0022501223350113355008300635573aa004600a6aae794008c010d5d100180c09aba10011122123300100300211200112232323333573466e1d400520002350083005357426aae79400c8cccd5cd19b87500248008940208d405cd4c054cd5ce24810350543100016499264984d55cea80089baa00112122300200311220011200113500d35300b3357389211f556e6578706563746564205478496e666f20636f6e737472756374696f6e2e0000c498888888888848cccccccccc00402c02802402001c01801401000c00880044488008488488cc00401000c480048c8c8cccd5cd19b875001480088c018dd71aba135573ca00646666ae68cdc3a80124000460106eb8d5d09aab9e500423500c35300a3357389201035054310000b499264984d55cea80089baa001212230020032122300100320012323333573466e1d40052002200823333573466e1d40092000200a2350073530053357389210350543100006499264984d55ce9baa0011200120011261220021220012001112323001001223300330020020014891c0029cb7c88c7567b63d1a512c0ed626aa169688ec980730c0473b9130001', + }; constructor(requestConfig: RequestConfig = {}) { super(); @@ -146,7 +152,7 @@ export class SundaeSwap extends BaseDex { return (1 - (Number(reserveIn) / Number(reserveIn + swapInAmount))) * 100; } - public async buildSwapOrder(liquidityPool: LiquidityPool, swapParameters: DatumParameters, spendUtxos: UTxO[] = []): Promise { + public async buildSwapOrder(liquidityPool: LiquidityPool, swapParameters: DatumParameters, spendUtxos: SpendUTxO[] = []): Promise { const scooperFee: SwapFee | undefined = this.swapOrderFees().find((fee: SwapFee) => fee.id === 'scooperFee'); const deposit: SwapFee | undefined = this.swapOrderFees().find((fee: SwapFee) => fee.id === 'deposit'); @@ -207,7 +213,12 @@ export class SundaeSwap extends BaseDex { addressType: AddressType.Base, assetBalances: relevantUtxo.assetBalances, isInlineDatum: false, - spendUtxos: [relevantUtxo], + spendUtxos: [{ + utxo: relevantUtxo, + redeemer: this.cancelDatum, + validator: this.orderScript, + signer: returnAddress, + }], } ]; } diff --git a/src/dex/teddyswap.ts b/src/dex/teddyswap.ts index d1f2c82..f818c8d 100644 --- a/src/dex/teddyswap.ts +++ b/src/dex/teddyswap.ts @@ -8,7 +8,7 @@ import { DefinitionConstr, DefinitionField, PayToAddress, - RequestConfig, + RequestConfig, SpendUTxO, SwapFee, UTxO } from '@app/types'; @@ -19,6 +19,7 @@ import pool from './definitions/teddyswap/pool'; import order from './definitions/teddyswap/order'; import { correspondingReserves, tokensMatch } from '@app/utils'; import { TeddyswapApi } from '@dex/api/teddyswap-api'; +import { Script } from 'lucid-cardano'; const MAX_INT: bigint = 9_223_372_036_854_775_807n; @@ -31,6 +32,11 @@ export class TeddySwap extends BaseDex { * On-Chain constants. */ public readonly orderAddress: string = 'addr1z99tz7hungv6furtdl3zn72sree86wtghlcr4jc637r2eadkp2avt5gp297dnxhxcmy6kkptepsr5pa409qa7gf8stzs0706a3'; + public readonly cancelDatum: string = 'd8799f00000001ff'; + public readonly orderScript: Script = { + type: 'PlutusV2', + script: '5905090100003232323232323232323232323232323232323232323222253330153232323232323232323232323232323232323232323232323232323253330313370e90010010991919299812a99981a19b8753330343370e6eb4c0d4c0d803d2000148000520024800054cc094cdc399815005181a80e240042a6604a664466ebcdd3981c8011ba730390013035004303500815330253370e666066444a666062002200426600666e00009200230390014800004d20041533025337126eb4c0d4c0d805800854cc0940044cccc8888cdc499b833370466e08cc0b803800c008004cdc019b823302e00e004483403ccdc100100099b8000648008c0d4078c0d4074dd6981a80b1bad303501b13322332303622533303300114a02a66607266ebcc0e800400c52889801181d8009ba90010023758606a64606e606e606e606e606e002606c0286eb8c0d40604cdc3811811a9991981a0008a513232325330273371e6eb8c0dcc0e0008dd7181b981c000899b8f375c606e0046eb8c0dc004c0e00a0c0dc004c0d00704ccccc88888c8c8cdc499b8133702605401a6eb4004cdc199b82005004003302a0135333039323253302c3371e6eb8c0f0c0f4008dd7181e181e800899b8f375c60780046eb8c0f0004c0f40b4c0f00184dd400288009ba848000c0d0074dd6981a00a8009bad3034019375a6068030a666064646464a6604c66e3cdd7181b181b8011bae3036303700113371e6eb8c0d8008dd7181b000981b813981b000981980d899b83337040026eb4c0cc05ccdc09bad3033017375a6066030200266e04cc09c028c0c8068cc09c010c0c806858c0d0008c0ac004dd51817981800c9bab32302f30303031001302e302f001302f00133028375a605800e0146eacc8c0b0c0b4c0b8004c0acc0b0004c0b0004cc094dd6981480280399911919192999816191919299981799b87480080084c8c8c94ccc0c8cdc3a400000429404cdd79ba7004374e002606a00460580026ea801c4c8c8c94ccc0c8cdc3a400400429404cdd79ba7004374e002606a00460580026ea801cc0c8008c0a4004dd500088010b1919191919299981819b87480000084c8c8c8c94ccc0d0cdc3a4000004264646464a66607066e1d20020021613374a9000000981d80118190009baa0013035001163037002302e00137540026062002266e95200202b3033002302a0013754002605a605c605e0026058605c00a6eacc8c8c94ccc0b4cdc3a40040042c2a66605a66e3cdd7181700080309817181798180038b181800118138009baa00132302b302d001302a302c003375c60500166050014660466eb4c09c004010c09c004c098004c098040dd618118011bac3022002302230220013022302000a3020001301f001301e001301d001301c001301b001301a00130190013019004301800114985920aca597c9282533300b0011480004ccc044cdd7980698090009ba9006375a602a60246eacc054c04800520002233301100200100314a066e952000330013752004660026ea40080215d0245002232333004003375c601c0026eb8c038c03c004c03c004888cccc01000920002333300500248001d69bab00100323002375200244446601444a66600e002200a2a66601a66ebcc024c0380040184c010c044c0380044c008c03c00400555cfa5eb8155ce91299980299b8800248000584cc00c008004c0048894ccc014cdc3801240002600c00226600666e04009200230070012323002233002002001230022330020020015734ae855d1118011baa0015573c1', + }; constructor(requestConfig: RequestConfig = {}) { super(); @@ -167,7 +173,7 @@ export class TeddySwap extends BaseDex { return (1 - (Number(reserveIn) / Number(reserveIn + swapInAmount))) * 100; } - public async buildSwapOrder(liquidityPool: LiquidityPool, swapParameters: DatumParameters, spendUtxos: UTxO[] = []): Promise { + public async buildSwapOrder(liquidityPool: LiquidityPool, swapParameters: DatumParameters, spendUtxos: SpendUTxO[] = []): Promise { const batcherFee: SwapFee | undefined = this.swapOrderFees().find((fee: SwapFee) => fee.id === 'batcherFee'); const deposit: SwapFee | undefined = this.swapOrderFees().find((fee: SwapFee) => fee.id === 'deposit'); const minReceive = swapParameters.MinReceive as bigint; @@ -222,8 +228,29 @@ export class TeddySwap extends BaseDex { ]; } - public buildCancelSwapOrder(txOutputs: UTxO[], returnAddress: string): Promise { - throw new Error('Method not implemented.'); + public async buildCancelSwapOrder(txOutputs: UTxO[], returnAddress: string): Promise { + const relevantUtxo: UTxO | undefined = txOutputs.find((utxo: UTxO) => { + return utxo.address === this.orderAddress; + }); + + if (! relevantUtxo) { + return Promise.reject('Unable to find relevant UTxO for cancelling the swap order.'); + } + + return [ + { + address: returnAddress, + addressType: AddressType.Base, + assetBalances: relevantUtxo.assetBalances, + isInlineDatum: false, + spendUtxos: [{ + utxo: relevantUtxo, + redeemer: this.cancelDatum, + validator: this.orderScript, + signer: returnAddress, + }], + } + ]; } public swapOrderFees(): SwapFee[] { diff --git a/src/dex/vyfinance.ts b/src/dex/vyfinance.ts index c416e08..ded5ce3 100644 --- a/src/dex/vyfinance.ts +++ b/src/dex/vyfinance.ts @@ -1,14 +1,15 @@ import { LiquidityPool } from './models/liquidity-pool'; import { BaseDataProvider } from '@providers/data/base-data-provider'; -import { Token } from './models/asset'; +import { Asset, Token } from './models/asset'; import { BaseDex } from './base-dex'; -import { DatumParameters, PayToAddress, RequestConfig, SwapFee, UTxO } from '@app/types'; +import { DatumParameters, PayToAddress, RequestConfig, SpendUTxO, SwapFee, UTxO } from '@app/types'; import { DefinitionBuilder } from '@app/definition-builder'; import { correspondingReserves } from '@app/utils'; import { AddressType, DatumParameterKey } from '@app/constants'; import order from '@dex/definitions/vyfinance/order'; import { BaseApi } from '@dex/api/base-api'; import { VyfinanceApi } from '@dex/api/vyfinance-api'; +import { Data, Script } from 'lucid-cardano'; /** * VyFinance constants. @@ -21,6 +22,15 @@ export class VyFinance extends BaseDex { public static readonly identifier: string = 'VyFinance'; public readonly api: BaseApi; + /** + * On-Chain constants. + */ + public readonly cancelDatum: string = 'd87a80'; + public readonly orderScript: Script = { + type: 'PlutusV1', + script: '590a8c010000332323232322232322322323253353330093333573466e1cd55cea803a40004646424660020060046464646666ae68cdc3a800a40184642444444460020106eb4d5d09aab9e500323333573466e1d4009200a232122222223002008375a6ae84d55cf280211999ab9a3370ea00690041190911111118018041bad357426aae7940148cccd5cd19b875004480188c848888888c010020dd69aba135573ca00c46666ae68cdc3a802a400842444444400a46666ae68cdc3a8032400446424444444600c0106464646666ae68cdc39aab9d5002480008cc8848cc00400c008dd69aba15002375a6ae84d5d1280111931a99ab9c01d01c01b01a135573ca00226ea8004d5d09aab9e500823333573466e1d401d2000232122222223007008375a6ae84d55cf280491931a99ab9c01a019018017016015014013012011135573aa00226ea8004d5d09aba25008375c6ae85401c8c98d4cd5ce0078070068061999ab9a3370ea0089001109100111999ab9a3370ea00a9000109100091931a99ab9c01000f00e00d00c3333573466e1cd55cea8012400046644246600200600464646464646464646464646666ae68cdc39aab9d500a480008cccccccccc888888888848cccccccccc00402c02802402001c01801401000c008d5d0a80519a80b90009aba1500935742a0106ae85401cd5d0a8031aba1500535742a00866a02eeb8d5d0a8019aba15002357426ae8940088c98d4cd5ce00d80d00c80c09aba25001135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aab9e5001137540026ae854008c8c8c8cccd5cd19b875001480188c848888c010014c8c8c8c8c8c8cccd5cd19b8750014803084888888800c8cccd5cd19b875002480288488888880108cccd5cd19b875003480208cc8848888888cc004024020dd71aba15005375a6ae84d5d1280291999ab9a3370ea00890031199109111111198010048041bae35742a00e6eb8d5d09aba2500723333573466e1d40152004233221222222233006009008301b35742a0126eb8d5d09aba2500923333573466e1d40192002232122222223007008301c357426aae79402c8cccd5cd19b875007480008c848888888c014020c074d5d09aab9e500c23263533573804003e03c03a03803603403203002e26aae7540104d55cf280189aab9e5002135573ca00226ea8004d5d09aab9e500323333573466e1d400920042321222230020053011357426aae7940108cccd5cd19b875003480088c848888c004014c8c8c8cccd5cd19b8735573aa004900011991091980080180119191999ab9a3370e6aae75400520002375c6ae84d55cf280111931a99ab9c01c01b01a019137540026ae854008dd69aba135744a004464c6a66ae7006406005c0584d55cf280089baa001357426aae7940148cccd5cd19b875004480008c848888c00c014dd71aba135573ca00c464c6a66ae7005805405004c0480440404d55cea80089baa001357426ae8940088c98d4cd5ce007807006806080689931a99ab9c4901035054350000d00c135573ca00226ea80044d55ce9baa001135573ca00226ea800448c88c008dd60009900099180080091191999aab9f0022122002233221223300100400330053574200660046ae8800c01cc0080088c8c8c8c8cccd5cd19b875001480088ccc888488ccc00401401000cdd69aba15004375a6ae85400cdd69aba135744a00646666ae68cdc3a8012400046424460040066464646666ae68cdc3a800a400446424460020066eb8d5d09aab9e500323333573466e1d400920002321223002003375c6ae84d55cf280211931a99ab9c00f00e00d00c00b135573aa00226ea8004d5d09aab9e500623263533573801401201000e00c26aae75400c4d5d1280089aab9e5001137540029309000a481035054310033232323322323232323232323232332223222253350021350012232350032222222222533533355301512001321233001225335002210031001002501e25335333573466e3c0300040540504d40800045407c00c84054404cd4c8c8d4cc8848cc00400c008ccdc624000030004a66a666ae68cdc7a800a4410000b00a150151350165001223355011002001133371802e02e0026a00a4400444004260086a6464646464a66a6666666ae900148cccd5cd19b8735573aa00a900011999aab9f500525019233335573ea00a4a03446666aae7d40149406c8cccd55cf9aba2500625335323232323333333574800846666ae68cdc39aab9d5004480008cccd55cfa8021281191999aab9f500425024233335573e6ae89401494cd4c088d5d0a80390a99a99a811119191919191999999aba400623333573466e1d40092002233335573ea00c4a05e46666aae7d4018940c08cccd55cfa8031281891999aab9f35744a00e4a66a605a6ae854028854cd4c0b8d5d0a80510a99a98179aba1500a21350361223330010050040031503415033150322503203303203103023333573466e1d400d2000233335573ea00e4a06046666aae7cd5d128041299a98171aba150092135033122300200315031250310320312502f02c02b2502d2502d2502d2502d02e135573aa00826ae8940044d5d1280089aab9e5001137540026ae85401c84d40a048cc00400c0085409854094940940980940909408807c940849408494084940840884d5d1280089aab9e5001137540026ae854024854cd4ccd54054070cd54054070060d5d0a80490a99a99a80d00e9aba150092135020123330010040030021501e1501d1501c2501c01d01c01b01a250180152501725017250172501701821001135626135744a00226ae8940044d55cf280089baa00135001223500222222222225335009132635335738921035054380001f01b22100222200232001355011225335001100422135002225335333573466e3c00801c02402040244c01800c488008488004c8004d5403488448894cd40044d400c88004884ccd401488008c010008ccd54c01c480040140100044488c88ccccccd5d2000aa8029299a98019bab002213500f0011500d55005550055500500e3200135500e223233335573e00446a01e2440044a66a600c6aae754008854cd4c018d55cf280190a99a98031aba200521350123212233001003004335500b003002150101500f1500e00f135742002224a0102244246600200600446666666ae900049401c9401c9401c8d4020dd6801128038040911919191999999aba400423333573466e1d40092000233335573ea0084a01846666aae7cd5d128029299a98049aba15006213500f3500f0011500d2500d00e00d23333573466e1d400d2002233335573ea00a46a01ca01a4a01a01c4a0180120104a0144a0144a0144a01401626aae7540084d55cf280089baa00123232323333333574800846666ae68cdc3a8012400446666aae7d4010940288cccd55cf9aba2500525335300a35742a00c426a01a24460020062a0164a01601801646666ae68cdc3a801a400046666aae7d40149402c8cccd55cf9aba2500625335300b35742a00e426a01c24460040062a0184a01801a0184a01400e00c4a0104a0104a0104a01001226aae7540084d55cf280089baa0014988ccccccd5d20009280192801928019280191a8021bae002004121223002003112200112001480e0448c8c00400488cc00cc00800800522011c', + }; + constructor(requestConfig: RequestConfig = {}) { super(); @@ -72,7 +82,7 @@ export class VyFinance extends BaseDex { return (1 - estimatedReceive / ((Number(swapInAmount) - swapFee) * (reserveOut / reserveIn))) * 100; } - public async buildSwapOrder(liquidityPool: LiquidityPool, swapParameters: DatumParameters, spendUtxos: UTxO[] = []): Promise { + public async buildSwapOrder(liquidityPool: LiquidityPool, swapParameters: DatumParameters, spendUtxos: SpendUTxO[] = []): Promise { const isDoubleSidedSwap: boolean = (swapParameters.SwapInTokenPolicyId as string) !== '' && (swapParameters.SwapOutTokenPolicyId as string) !== ''; const swapDirection: number = (swapParameters.SwapInTokenPolicyId as string) === '' || isDoubleSidedSwap ? SWAP_ACTION_EXPECT_ASSET @@ -119,13 +129,28 @@ export class VyFinance extends BaseDex { return Promise.reject('Unable to find relevant UTxO for cancelling the swap order.'); } + const pool: LiquidityPool | undefined = (await this.api.liquidityPools()) + .find((pool: LiquidityPool) => [pool.marketOrderAddress, pool.limitOrderAddress].includes(relevantUtxo.address)); + + if (! pool) { + return Promise.reject('Unable to find relevant liquidity pool for cancelling the swap order.'); + } + + const script: Script = this.orderScript; + script.script += `${pool.extra.nft.policyId}0001`; + return [ { address: returnAddress, addressType: AddressType.Base, assetBalances: relevantUtxo.assetBalances, isInlineDatum: false, - spendUtxos: [relevantUtxo], + spendUtxos: [{ + utxo: relevantUtxo, + redeemer: this.cancelDatum, + validator: script, + signer: returnAddress, + }], } ]; } diff --git a/src/dex/wingriders.ts b/src/dex/wingriders.ts index c0a51e6..a7c6665 100644 --- a/src/dex/wingriders.ts +++ b/src/dex/wingriders.ts @@ -6,7 +6,7 @@ import { DefinitionConstr, DefinitionField, PayToAddress, - RequestConfig, + RequestConfig, SpendUTxO, SwapFee, UTxO } from '@app/types'; @@ -20,6 +20,7 @@ import order from '@dex/definitions/wingriders/order'; import { BaseApi } from '@dex/api/base-api'; import { WingRidersApi } from '@dex/api/wingriders-api'; import pool from "@dex/definitions/wingriders/pool"; +import { Script } from 'lucid-cardano'; /** * WingRiders constants. @@ -37,6 +38,11 @@ export class WingRiders extends BaseDex { */ public readonly orderAddress: string = 'addr1wxr2a8htmzuhj39y2gq7ftkpxv98y2g67tg8zezthgq4jkg0a4ul4'; public readonly poolValidityAsset: string = '026a18d04a0c642759bb3d83b12e3344894e5c1c7b2aeb1a2113a5704c'; + public readonly cancelDatum: string = 'd87a80'; + public readonly orderScript: Script = { + type: 'PlutusV1', + script: '590370010000332332233322232323332223332223233223232323232332233222232322323225335301533225335301a00221333573466e3c02cdd7299a9a8101980924004a66a6a040660249000299a9a8101980924000a66a6a04066024900019a980b8900098099bac5335350203301248000d4d54054c0440088800858884008004588854cd4d4088004588854cd4d409000440088858588854cd4d4088004588854cd4d4090004588854cd4d409800440188858588854cd4d4088004588854cd4d409000440108858588854cd4d4088004400888580680644cc88d4c03400888d4c0440088888cc05cdd70019918139bac0015335350273301948000d4d54070c06001c88008588854cd4d40a4004588854cd4d40ac004588854cd4d40b4004588854cd4d40bc004588854cd4d40c4004588854cd4d40cc004588854cd4d40d400458884008cccd5cd19b8735573aa010900011980699191919191999ab9a3370e6aae75401120002333301535742a0086ae85400cd5d0a8011aba135744a004464c6a605266ae700900a80680644d5d1280089aba25001135573ca00226ea8004d5d0a8041aba135744a010464c6a604666ae7007809005004c004cccd5cd19b8750024800880688cccd5cd19b875003480008c8c074004dd69aba135573ca00a464c6a604466ae7007408c04c0480440044084584d55cea80089baa001135573ca00226ea80048848cc00400c0088004888848cccc00401401000c0088004c8004d540548894cd4d404c00440308854cd4c034ccd5cd19b8f00400200f00e100f13300500400125335350103300248000004588854cd4d4048004588854cd4d40500044cd54028010008885888c8d4d54018cd5401cd55cea80098021aab9e5001225335300b333573466e1c0140080340304004584dd5000990009aa809111999aab9f0012501223350113574200460066ae8800800d26112212330010030021120013200135500e2212253353500d0021622153353007333573466e1c00d2000009008100213353006120010013370200690010910010910009000909118010018910009000a490350543100320013550062233335573e0024a00c466a00a6eb8d5d080118019aba2002007112200212212233001004003120011200120011123230010012233003300200200148811ce6c90a5923713af5786963dee0fdffd830ca7e0c86a041d9e5833e910001', + }; private _assetAddresses: AssetAddress[] = []; @@ -194,7 +200,7 @@ export class WingRiders extends BaseDex { * 100; } - public async buildSwapOrder(liquidityPool: LiquidityPool, swapParameters: DatumParameters, spendUtxos: UTxO[] = []): Promise { + public async buildSwapOrder(liquidityPool: LiquidityPool, swapParameters: DatumParameters, spendUtxos: SpendUTxO[] = []): Promise { const agentFee: SwapFee | undefined = this.swapOrderFees().find((fee: SwapFee) => fee.id === 'agentFee'); const oil: SwapFee | undefined = this.swapOrderFees().find((fee: SwapFee) => fee.id === 'oil'); @@ -267,7 +273,12 @@ export class WingRiders extends BaseDex { addressType: AddressType.Base, assetBalances: relevantUtxo.assetBalances, isInlineDatum: false, - spendUtxos: [relevantUtxo], + spendUtxos: [{ + utxo: relevantUtxo, + redeemer: this.cancelDatum, + validator: this.orderScript, + signer: returnAddress, + }], } ]; } diff --git a/src/providers/data/blockfrost-provider.ts b/src/providers/data/blockfrost-provider.ts index 847e739..924d084 100644 --- a/src/providers/data/blockfrost-provider.ts +++ b/src/providers/data/blockfrost-provider.ts @@ -92,6 +92,7 @@ export class BlockfrostProvider extends BaseDataProvider { txHash: response.data.hash, address: utxo.address, datumHash: utxo.data_hash, + datum: utxo.inline_datum, outputIndex: utxo.output_index, assetBalances: utxo.amount.reduce((assets: AssetBalance[], amount: any) => { assets.push({ diff --git a/src/providers/wallet/lucid-provider.ts b/src/providers/wallet/lucid-provider.ts index ec52543..f94354f 100644 --- a/src/providers/wallet/lucid-provider.ts +++ b/src/providers/wallet/lucid-provider.ts @@ -1,4 +1,12 @@ -import { AssetBalance, BlockfrostConfig, Cip30Api, KupmiosConfig, PayToAddress, UTxO, WalletOptions } from '@app/types'; +import { + AssetBalance, + BlockfrostConfig, + Cip30Api, + KupmiosConfig, + PayToAddress, + SpendUTxO, + WalletOptions +} from '@app/types'; import { DexTransaction } from '@dex/models/dex-transaction'; import { BaseWalletProvider } from './base-wallet-provider'; import { @@ -7,7 +15,7 @@ import { Assets, Blockfrost, Datum, Kupmios, - Lucid, OutputData, + Lucid, TxComplete, TxHash, TxSigned, @@ -91,17 +99,26 @@ export class LucidProvider extends BaseWalletProvider { // Include UTxOs to spend if (payToAddress.spendUtxos && payToAddress.spendUtxos.length > 0) { - transaction.providerData.tx.collectFrom( - payToAddress.spendUtxos.map((utxo: UTxO) => { - return { - txHash: utxo.txHash, - outputIndex: utxo.outputIndex, - address: utxo.address, - datumHash: utxo.datumHash, - assets: this.paymentFromAssets(utxo.assetBalances) - }; - }) - ); + payToAddress.spendUtxos.forEach((spendUtxo: SpendUTxO) => { + transaction.providerData.tx.collectFrom([ + { + txHash: spendUtxo.utxo.txHash, + outputIndex: spendUtxo.utxo.outputIndex, + address: spendUtxo.utxo.address, + datumHash: spendUtxo.utxo.datum ? null : spendUtxo.utxo.datumHash, + datum: spendUtxo.utxo.datum, + assets: this.paymentFromAssets(spendUtxo.utxo.assetBalances), + } + ], spendUtxo.redeemer); + + if (spendUtxo.validator) { + transaction.providerData.tx.attachSpendingValidator(spendUtxo.validator); + } + + if (spendUtxo.signer) { + transaction.providerData.tx.addSigner(spendUtxo.signer); + } + }); } switch (payToAddress.addressType) { diff --git a/src/requests/cancel-swap-request.ts b/src/requests/cancel-swap-request.ts index c0bdc14..97dcfaa 100644 --- a/src/requests/cancel-swap-request.ts +++ b/src/requests/cancel-swap-request.ts @@ -61,7 +61,9 @@ export class CancelSwapRequest { cancelTransaction.status = TransactionStatus.Building; cancelTransaction.attachMetadata(MetadataKey.Message, { - msg: `[${this._dexter.config.metadataMsgBranding}] ${this._dexName} Cancel Swap` + msg: [ + `[${this._dexter.config.metadataMsgBranding}] ${this._dexName} Cancel Swap` + ] }); // Build transaction diff --git a/src/requests/swap-request.ts b/src/requests/swap-request.ts index 6b2ded9..9dc2362 100644 --- a/src/requests/swap-request.ts +++ b/src/requests/swap-request.ts @@ -2,7 +2,7 @@ import { LiquidityPool } from '@dex/models/liquidity-pool'; import { Token } from '@dex/models/asset'; import { Dexter } from '@app/dexter'; import { tokensMatch } from '@app/utils'; -import { DatumParameters, PayToAddress, SwapFee, UTxO } from '@app/types'; +import { DatumParameters, PayToAddress, SpendUTxO, SwapFee, UTxO } from '@app/types'; import { DatumParameterKey, MetadataKey, TransactionStatus } from '@app/constants'; import { DexTransaction } from '@dex/models/dex-transaction'; @@ -213,7 +213,15 @@ export class SwapRequest { }; return this._dexter.availableDexs[this._liquidityPool.dex] - .buildSwapOrder(this._liquidityPool, defaultSwapParameters, this._withUtxos); + .buildSwapOrder( + this._liquidityPool, + defaultSwapParameters, + this._withUtxos.map((utxo: UTxO) => { + return { + utxo, + } + }) as SpendUTxO[] + ); } public submit(): DexTransaction { diff --git a/src/types.ts b/src/types.ts index 7cd05b2..91fcea3 100644 --- a/src/types.ts +++ b/src/types.ts @@ -2,6 +2,7 @@ import { AddressType, DatumParameterKey, TransactionStatus } from './constants'; import { Token } from '@dex/models/asset'; import { BaseDex } from '@dex/base-dex'; import { LiquidityPool } from '@dex/models/liquidity-pool'; +import { Script } from 'lucid-cardano'; export interface DexterConfig { shouldFetchMetadata?: boolean, @@ -47,6 +48,7 @@ export type UTxO = { txHash: string, address: string, datumHash: string, + datum?: string, outputIndex: number, assetBalances: AssetBalance[], }; @@ -82,11 +84,18 @@ export type WalletOptions = { accountIndex?: number, } +export type SpendUTxO = { + utxo: UTxO, + redeemer?: string, + validator?: Script, + signer?: string, +}; + export type PayToAddress = { address: string, addressType: AddressType, assetBalances: AssetBalance[], - spendUtxos?: UTxO[], + spendUtxos?: SpendUTxO[], datum?: string, isInlineDatum: boolean, }; diff --git a/tests/spectrum.test.ts b/tests/spectrum.test.ts index c05dd42..a988be0 100644 --- a/tests/spectrum.test.ts +++ b/tests/spectrum.test.ts @@ -10,7 +10,7 @@ import { PayToAddress, AddressType, } from '../src'; -import { Spectrum } from '../src/dex/spectrum'; +import { Spectrum } from '../src'; describe('Spectrum', () => {