From 3a0c5f006dd9cb7fed408adf2a656f227bea870a Mon Sep 17 00:00:00 2001 From: Sluder Date: Mon, 22 Jan 2024 14:02:03 -0500 Subject: [PATCH] Split cancel orders --- README.md | 17 ++++ docs/requests/split-cancel-swap-request.md | 39 +++++++++ src/dexter.ts | 15 ++++ src/index.ts | 3 +- src/requests/cancel-swap-request.ts | 34 +++++--- src/requests/split-cancel-swap-request.ts | 99 ++++++++++++++++++++++ src/types.ts | 5 ++ 7 files changed, 199 insertions(+), 13 deletions(-) create mode 100644 docs/requests/split-cancel-swap-request.md create mode 100644 src/requests/split-cancel-swap-request.ts diff --git a/README.md b/README.md index c3761ee..fa28d47 100644 --- a/README.md +++ b/README.md @@ -221,6 +221,22 @@ dexter.newCancelSwapRequest() ``` +
+ +
+newSplitCancelSwapRequest(): SplitCancelSwapRequest Create new request for cancelling multiple swap orders. + +For available methods on the `SplitCancelSwapRequest` instance, please see those specific +[docs](https://github.com/IndigoProtocol/dexter/blob/master/docs/requests/split-cancel-swap-request.md). + +##### Using + +```js +dexter.newSplitCancelSwapRequest() + ... +``` +
+ ### More Docs - [Data Providers](https://github.com/IndigoProtocol/dexter/blob/master/docs/providers/data.md) @@ -229,5 +245,6 @@ dexter.newCancelSwapRequest() - [Creating a Swap Request](https://github.com/IndigoProtocol/dexter/blob/master/docs/requests/swap-request.md) - [Creating a Split Swap Request](https://github.com/IndigoProtocol/dexter/blob/master/docs/requests/split-swap-request.md) - [Creating a Cancel Swap Request](https://github.com/IndigoProtocol/dexter/blob/master/docs/requests/cancel-swap-request.md) +- [Creating a Split Cancel Swap Request](https://github.com/IndigoProtocol/dexter/blob/master/docs/requests/split-cancel-swap-request.md) - [Listening for transaction events](https://github.com/IndigoProtocol/dexter/blob/master/docs/dex-transaction.md) - [Commonly returned models](https://github.com/IndigoProtocol/dexter/blob/master/docs/models.md) diff --git a/docs/requests/split-cancel-swap-request.md b/docs/requests/split-cancel-swap-request.md new file mode 100644 index 0000000..b90e64f --- /dev/null +++ b/docs/requests/split-cancel-swap-request.md @@ -0,0 +1,39 @@ +

+

Split Cancel Swap Request

+

+ +Request a split cancel order request in order to split your cancel order into chunks on different DEXs. + +### Obtaining +```js +dexter.newSplitCancelSwapRequest() + ... +``` + +### SwapRequest API + +
+forTransactions(SplitCancelSwapMapping[]): SplitSwapRequest Set which transactions to cancel. + +##### Using + +```js +dexter.newSplitCancelSwapRequest() + .forTransactions([{ txHash: '{Tx Hash}', dex: 'Minswap' }]) + ... +``` +
+ +
+ +
+submit(): DexTransaction Finally submit your split cancel orders on-chain. + +##### Using + +```js +dexter.newSplitCancelSwapRequest() + ... + .submit() +``` +
diff --git a/src/dexter.ts b/src/dexter.ts index c6c3f9a..92d9749 100644 --- a/src/dexter.ts +++ b/src/dexter.ts @@ -17,6 +17,7 @@ import axiosRetry from "axios-retry"; import { SplitSwapRequest } from '@requests/split-swap-request'; import { TeddySwap } from '@dex/teddyswap'; import { Spectrum } from '@dex/spectrum'; +import { SplitCancelSwapRequest } from '@requests/split-cancel-swap-request'; export class Dexter { @@ -135,4 +136,18 @@ export class Dexter { return new CancelSwapRequest(this); } + /** + * New request for a split cancel swap order. + */ + public newSplitCancelSwapRequest(): SplitCancelSwapRequest { + if (! this.walletProvider) { + throw new Error('Wallet provider must be set before requesting a split cancel order.'); + } + if (! this.walletProvider.isWalletLoaded) { + throw new Error('Wallet must be loaded before requesting a split cancel order.'); + } + + return new SplitCancelSwapRequest(this); + } + } diff --git a/src/index.ts b/src/index.ts index 946a0e7..aca9736 100644 --- a/src/index.ts +++ b/src/index.ts @@ -25,10 +25,11 @@ export * from './providers/asset-metadata/token-registry-provider'; /** * Request exports. */ +export * from './requests/fetch-request'; export * from './requests/swap-request'; export * from './requests/split-swap-request'; -export * from './requests/fetch-request'; export * from './requests/cancel-swap-request'; +export * from './requests/split-cancel-swap-request'; /** * DEX exports. diff --git a/src/requests/cancel-swap-request.ts b/src/requests/cancel-swap-request.ts index 97dcfaa..0f8b6f3 100644 --- a/src/requests/cancel-swap-request.ts +++ b/src/requests/cancel-swap-request.ts @@ -26,6 +26,23 @@ export class CancelSwapRequest { return this; } + + public getPaymentsToAddresses(): Promise { + if (! this._dexter.walletProvider) { + throw new Error('Wallet provider must be set before submitting a swap order.'); + } + + const returnAddress: string = this._dexter.walletProvider.address(); + + return (this._dexter.dataProvider as BaseDataProvider).transactionUtxos(this._txHash) + .then((utxos: UTxO[]) => { + return this._dexter.availableDexs[this._dexName].buildCancelSwapOrder(utxos, returnAddress); + }) + .catch(() => { + throw new Error('Unable to grab UTxOs for the provided Tx hash. Ensure the one provided is a valid Tx hash.') + }); + } + public cancel(): DexTransaction { if (! this._dexter.walletProvider) { throw new Error('Wallet provider must be set before submitting a swap order.'); @@ -38,20 +55,13 @@ export class CancelSwapRequest { } const cancelTransaction: DexTransaction = this._dexter.walletProvider.createTransaction(); - const returnAddress: string = this._dexter.walletProvider.address(); - (this._dexter.dataProvider as BaseDataProvider).transactionUtxos(this._txHash) - .then((utxos: UTxO[]) => { - this._dexter.availableDexs[this._dexName].buildCancelSwapOrder(utxos, returnAddress) - .then((payToAddresses: PayToAddress[]) => { - this.sendCancelOrder(cancelTransaction, payToAddresses); - }) - .catch((error) => { - throw new Error(`Unable to cancel swap order. ${error}`) - }); + this.getPaymentsToAddresses() + .then((payToAddresses: PayToAddress[]) => { + this.sendCancelOrder(cancelTransaction, payToAddresses); }) - .catch(() => { - throw new Error('Unable to grab UTxOs for the provided Tx hash. Ensure the one provided is a valid Tx hash.') + .catch((error) => { + throw new Error(`Unable to cancel swap order. ${error}`) }); return cancelTransaction; diff --git a/src/requests/split-cancel-swap-request.ts b/src/requests/split-cancel-swap-request.ts new file mode 100644 index 0000000..daacb35 --- /dev/null +++ b/src/requests/split-cancel-swap-request.ts @@ -0,0 +1,99 @@ +import { Dexter } from '@app/dexter'; +import { CancelSwapRequest } from '@requests/cancel-swap-request'; +import { PayToAddress, SplitCancelSwapMapping } from '@app/types'; +import { DexTransaction } from '@dex/models/dex-transaction'; +import { MetadataKey, TransactionStatus } from '@app/constants'; + +export class SplitCancelSwapRequest { + + private _dexter: Dexter; + private _cancelRequests: CancelSwapRequest[] = []; + + constructor(dexter: Dexter) { + this._dexter = dexter; + } + + public forTransactions(mappings: SplitCancelSwapMapping[]): SplitCancelSwapRequest { + this._cancelRequests = mappings.map((mapping: SplitCancelSwapMapping) => { + return this._dexter.newCancelSwapRequest() + .forTransaction(mapping.txHash) + .forDex(mapping.dex); + }); + + return this; + } + + public submit(): DexTransaction { + if (! this._dexter.walletProvider) { + throw new Error('Wallet provider must be set before submitting a cancel swap order.'); + } + if (! this._dexter.walletProvider.isWalletLoaded) { + throw new Error('Wallet must be loaded before submitting a cancel swap order.'); + } + if (this._cancelRequests.length === 0) { + throw new Error('Cancel requests were never initialized.'); + } + + const cancelTransaction: DexTransaction = this._dexter.walletProvider.createTransaction(); + + Promise.all(this._cancelRequests.map((cancelRequest: CancelSwapRequest) => cancelRequest.getPaymentsToAddresses())) + .then((payToAddresses: PayToAddress[][]) => { + this.sendSplitCancelSwapOrder(cancelTransaction, payToAddresses.flat()); + }); + + return cancelTransaction; + } + + private sendSplitCancelSwapOrder(cancelTransaction: DexTransaction, payToAddresses: PayToAddress[]) { + cancelTransaction.status = TransactionStatus.Building; + + cancelTransaction.attachMetadata(MetadataKey.Message, { + msg: [ + `[${this._dexter.config.metadataMsgBranding}] Split Cancel Swap` + ] + }); + + // Build transaction + cancelTransaction.payToAddresses(payToAddresses) + .then(() => { + cancelTransaction.status = TransactionStatus.Signing; + + // Sign transaction + cancelTransaction.sign() + .then(() => { + cancelTransaction.status = TransactionStatus.Submitting; + + // Submit transaction + cancelTransaction.submit() + .then(() => { + cancelTransaction.status = TransactionStatus.Submitted; + }) + .catch((error) => { + cancelTransaction.error = { + step: TransactionStatus.Submitting, + reason: 'Failed submitting transaction.', + reasonRaw: error, + }; + cancelTransaction.status = TransactionStatus.Errored; + }); + }) + .catch((error) => { + cancelTransaction.error = { + step: TransactionStatus.Signing, + reason: 'Failed to sign transaction.', + reasonRaw: error, + }; + cancelTransaction.status = TransactionStatus.Errored; + }); + }) + .catch((error) => { + cancelTransaction.error = { + step: TransactionStatus.Building, + reason: 'Failed to build transaction.', + reasonRaw: error, + }; + cancelTransaction.status = TransactionStatus.Errored; + }); + } + +} diff --git a/src/types.ts b/src/types.ts index 91fcea3..04568c2 100644 --- a/src/types.ts +++ b/src/types.ts @@ -118,6 +118,11 @@ export type SwapOutAmountMapping = { liquidityPool: LiquidityPool, } +export type SplitCancelSwapMapping = { + txHash: string, + dex: string, +} + export type DexTransactionError = { step: TransactionStatus, reason: string,