indigoprotocol / dexter Goto Github PK
View Code? Open in Web Editor NEWCustomizable Typescript SDK for interacting with Cardano DEXs
License: MIT License
Customizable Typescript SDK for interacting with Cardano DEXs
License: MIT License
I attempted to use Blockfrost as a Data Provider with an API fallback option, however when monitoring Blockfrost traffic in the dashboard, I cannot see the requests flowing through, also I can see all pools returned which leads me to believe it is possibly using the API DataProvider as mentioned in issue #5
I opted in to request data from Blockfrost using the following code:
const dexter: Dexter = new Dexter(dexterConfig, requestConfig).withDataProvider(blockfrostProvider); const request = dexter.newFetchRequest().forDexs(VyFinance.name);
My test in question was to query AGIX Pools for DEX provider VYFI.
const pools = await request.getLiquidityPools('lovelace', new Asset('f43a62fdc3965df486de8a0d32fe800963589c41b38946602a0dc535', '41474958', 8));
When getting liquidity pools for Minswap, it appears the prices are incorrect, this could possibly be due to a precision issue, as I have noticed the assetB has lost its decimal value of 6 (I tested with token MIN which has 6 decimals).
I can see the price calculation is using the assets decimal precision so both these issues could potentially be tied together.
Issue 1 - Liquidity pool for MIN, price shows: 8.8649. Minswap UI Shows: 0.088649.
Issue 2 - Liquidity pool, LP Token Asset Decimals show 0, but should show 6
I think both of these issues could be causing other ones I have experienced, such as building a swap requests returning incorrect swapOutToken decimals, and incorrect estimatedReceive amounts.
const buyFromAdaPools = await request.getLiquidityPools('lovelace', new Asset(tokenDetails?.policyId ?? '', tokenDetails?.assetName ?? '', tokenDetails?.decimals));
let pools =(await dexter.newFetchRequest() .forAllDexs() .getLiquidityPools(djed, iusd))
This will correctly filter for Minswap and SundaeSwap but not for VyFinance.
And no pools for Muesliswap are showing up. (As referenced here: #17)
Submit as package to https://www.npmjs.com/ .
Update README to point to the npm package repository vs. github.
Kupo
All
Pool response is inconsistent poolid and poolfeepercent arent populated particularly on sundae & minswap
let sellToken: Token = 'lovelace'
let buyToken: Token = new Asset('1d7f33bd23d85e1a25d87d86fac4f199c3197a2f7afeb662a0f34e1e', '776f726c646d6f62696c65746f6b656e', 6);
let tokenPairs: Array<Token[]> = [];
tokenPairs.push([sellToken, buyToken]);
let liquidityPools: LiquidityPool[] = await dexter.newFetchRequest().onAllDexs()
.forTokenPairs(tokenPairs).getLiquidityPools();
Blockfrost
SundaeSwap
When using the following code to cancel a swap request, that was sitting in Sundaeswap as out of range.
dexter.newCancelSwapRequest().forTransaction(transactionId).forDex(dexName).cancel();
The below error was received, I subscribed to the onSigning and logged out the error below.
I can replicate this each time on Sundae, I haven't tested any other dex as of yet, will update this when I do.
EDIT: this also happens on Minswap each time too.
When going from a utxo to liquidityPool using the method liquidityPoolFromUtxo
for Muesli & Sundaeswap I have noticed the pool returned always has a 0 poolFeePercent
. This means later when we act on the on the SwapRequest, calling estimatedReceive
which takes into account the poolFeePercent for the estimated output calculation , the amount is then incorrect.
Screenshot below comparing wingriders to minswap.
This is also not present on Sundaeswap,
Blockfrost
WingRiders
When doing a dexter fetch request for Dex of Wingriders, with a fixed swap in amount.
I have noticed when submitting the orders, they are pending to be batched in the Wingriders UI, these orders are not processed because they immeditely appear out of range, as a result it requires manual interaction to manually reclaim these orders in the UI, this is wingriders specific and other dex's work fine.
The minimum receive does in fact have the amount with the default 1% slippage so visually this looks fine.
I am also refreshing the pool state before an order is placed, thinking back I had Wingriders orders processing immediately when loading all the pools again and without the refresh pool state method being used, so this could be a factor here.
I have been testing doing multiple DEXS for multiple Assets, Last night I was Blockfrost project banned due to excessive requests despite a 1 min during poll between a small amount of assets and dexs, despite having a paid Developer plan.
I reached out to Blockfrost and they have advised that a ban will be automatically put in place when receiving 429 responses and not acting upon these in their API response. They have recommended an approach to this could be to implement a backoff mechanism or use their SDK which this backoff mechanism is already implemented.
I can see when we getLiquidityPools
here when logging out the exception in the catch I have Error: Request failed with status code 429
dexter/src/requests/fetch-request.ts
Line 57 in 5b8530c
After further testing I can see sometimes the pools are returned empty when looping through tokens and requests, so this might explain some of the other issues I have raised with concurrent requests receiving no data sometimes, referenced here #16 . I believe here blockfrost could potentially be sending us one of these status codes, then the data is parsed as empty occasionally.
I've created a suggestion here #25 for potentially loading the pools as a one off which could help reduce requests to Blockfrost potentially reducing any auto bans, if it's possible this could massively reduce users blockfrost requests and force the calling application to hold its pool data.
I think also dexter may need to cater for the Blockfrost status responses in the blockfrost-provider
Blockfrost have said they have an auto-ban mechanism in place for these requests when they flood the API. Because of the blockfrost UTXOS paginated request these requests easily mount up and I can see after querying just 2 Assets and 3 Dexs I start receiving no results.
@Sluder @codybutz @karleitner keen to hear thoughts on this :) also happy to jump on anything if I can help in anyway!
Custom
All
Trying to play with Dexter a bit ans can't figure this out, getting an error when trying to swap a token... can't figure it out what I'm doing wrong. I'm able to swap 'lovelace' to token but a token to 'lovelace' gives me this error, no matter the DEX.
var sellSwap: SwapRequest = dexter.newSwapRequest()
.forLiquidityPool( outPool )
.withSwapInToken( _token )
.withSwapInAmount( _tokenAmount )
.withSlippagePercent(5);
submitSellTx = sellSwap.submit();
file:///home/catad83/node_modules/@indigo-labs/dexter/build/dex/wingriders.js:115
const swapOutNumerator = swapInAmount * reserveOut * poolFeeModifier;
^
TypeError: Cannot mix BigInt and other types, use explicit conversions
at WingRiders.estimatedReceive (file:///home/catad83/node_modules/@indigo-labs/dexter/build/dex/wingriders.js:115:47)
at SwapRequest.getEstimatedReceive (file:///home/node_modules/@indigo-labs/dexter/build/requests/swap-request.js:107:68)
at SwapRequest.getMinimumReceive (file:///home/catad83/node_modules/@indigo-labs/dexter/build/requests/swap-request.js:110:46)
at SwapRequest.getPaymentsToAddresses (file:///home/catad83/node_modules/@indigo-labs/dexter/build/requests/swap-request.js:148:50)
at SwapRequest.submit (file:///home/catad83/node_modules/@indigo-labs/dexter/build/requests/swap-request.js:168:14)
at runBot (file:///home/catad83/production/bot.js:421:37)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
Thrown at:
at estimatedReceive (file:///home/catad83/node_modules/@indigo-labs/dexter/build/dex/wingriders.js:115:47)
at getEstimatedReceive (file:///home/catad83/node_modules/@indigo-labs/dexter/build/requests/swap-request.js:107:68)
at getMinimumReceive (file:///home/catad83/node_modules/@indigo-labs/dexter/build/requests/swap-request.js:110:46)
at getPaymentsToAddresses (file:///home/catad83/node_modules/@indigo-labs/dexter/build/requests/swap-request.js:148:50)
at submit (file:///home/catad83/node_modules/@indigo-labs/dexter/build/requests/swap-request.js:168:14)
at runBot (file:///home/catad83/production/bot.js:421:37)
at processTicksAndRejections (node:internal/process/task_queues:95:5)
Node.js v18.18.0
These are the arguments calling the swap with, from a trace:
outPool is: LiquidityPool {
identifier: '',
poolFeePercent: 0.35,
extra: {},
dex: 'WingRiders',
assetA: 'lovelace',
assetB: Asset {
policyId: 'dda5fdb1002f7389b33e036b6afee82a8189becb6cba852e8b79b4fb',
nameHex: '0014df1047454e53',
decimals: 0
},
reserveA: 41430452927n,
reserveB: 51824311338n,
address: 'addr1z8nvjzjeydcn4atcd93aac8allvrpjn7pjr2qsweukpnayf9eea0hzqqmpthdx6a549h44qzkua3066hggf08xvtg44s2qz7al',
marketOrderAddress: 'addr1wxr2a8htmzuhj39y2gq7ftkpxv98y2g67tg8zezthgq4jkg0a4ul4',
limitOrderAddress: 'addr1wxr2a8htmzuhj39y2gq7ftkpxv98y2g67tg8zezthgq4jkg0a4ul4',
lpToken: Asset {
policyId: '026a18d04a0c642759bb3d83b12e3344894e5c1c7b2aeb1a2113a570',
nameHex: '84eaa43491009c3a9f4e257370352e84ea7246ee8a27d9d3d9e458141d9bcf97',
decimals: 0
}
}
_token: Asset
{
policyId: 'dda5fdb1002f7389b33e036b6afee82a8189becb6cba852e8b79b4fb',
nameHex: '0014df1047454e53',
decimals: 6
}
_tokenAmount is bigint: 324203162
No matter what data provider you use, VyFi will always use their API for liquidity pools. This is due to their pools not easily identifiable on-chain. So using Blockfrost or Kupo won't have an effect.
Blockfrost
All
I'm getting error TypeError: transaction.providerData.tx.sign
is not a function when call swapRequest.submit
. even I set the lucid wallet provider to the dexter
I found that, transaction.providerData.tx
has type of Tx
in lucid-cardano, but Tx
doesn't have any function named sign
Found using Blockfrost as the data provider, but test using API as well
I've been doing some testing with request performance, and have enabled keepalive
in Axios, as a result I am seeing a significant performance improvement on request times particularly when using multiple requests in a short period of time.
Would be great if we can opt into this for Axios in the RequestConfig
Happy to do a PR :)
When querying Minswap using the Blockfrost Data provider, no data is returned.
Example code, querying Minswap for asset AGIX.
const dexter: Dexter = new Dexter(dexterConfig, requestConfig).withDataProvider(blockfrostProvider);
const request = dexter.newFetchRequest().forDexs([Minswap.name]);
const pools = await request.getLiquidityPools('lovelace', new Asset('f43a62fdc3965df486de8a0d32fe800963589c41b38946602a0dc535', '41474958', 8));
This seems to be Minswap provider specific, for example Sundae returns data using Blockfrost.
Kupo
WingRiders
Hi,
I'm running into the same issue as #48 But I have enough lovelace in my wallet.
file:///Users/nick/code/testing/node_modules/@indigo-labs/dexter/build/providers/wallet/lucid-provider.js:95
return transaction.providerData.tx.sign().complete()
^
TypeError: transaction.providerData.tx.sign is not a function
at LucidProvider.signTransaction (file:///Users/nick/code/test/node_modules/@indigo-labs/dexter/build/providers/wallet/lucid-provider.js:95:44)
at DexTransaction.sign (file:///Users/nick/code/test/node_modules/@indigo-labs/dexter/build/dex/models/dex-transaction.js:44:37)
at Timeout._onTimeout (file:///Users/nick/code/test/build/src/index.js:248:40)
at listOnTimeout (node:internal/timers:569:17)
at process.processTimers (node:internal/timers:512:7)
Here's my build code:
const swapRequest: SwapRequest = new Dexter(dexterConfig, requestConfig)
.withDataProvider(kupoProvider)
.withWalletProvider(lucidProvider)
.newSwapRequest()
.forLiquidityPool(pool)
.withSwapInToken('lovelace')
.withSwapInAmount(1_000_000n)
.withSlippagePercent(20);
const submitted = swapRequest.submit();
logger.info(TX Status: ${submitted.status});
logger.info(TX Hash ${submitted.hash});
let complete = await submitted.sign();
logger.info(`TX Status: ${submitted.status}`);
logger.info(`TX Hash ${submitted.hash}`)
User may not need LP token information for example, so this makes a lot of unneeded requests
Just give a try to dexter but got the following error: Error [ERR_REQUIRE_ESM]: require() of ES Module not supported using the readme example, even though I used the import statement import { DexterConfig, RequestConfig, Dexter, LiquidityPool } from "@indigo-labs/dexter";
This is my tsconfig.
{ "compilerOptions": { "module": "CommonJS", "moduleResolution": "node", "pretty": true, "resolveJsonModule": true, "sourceMap": true, "target": "es2021", "outDir": "./dist", "baseUrl": "./", "experimentalDecorators": true, "strict": true, "strictPropertyInitialization": false, "allowSyntheticDefaultImports": true }, "include": ["src/**/*.ts", "test/**/*.spec.ts", "src/index.ts"], "exclude": ["node_modules"] }
Blockfrost
All
Append '/' in proxy URL if not provided
--es-module-specifier-resolution=node
Incompatible with node v20.x
Blockfrost
All
In loadDefinition
of DefinitionBuilder:
public async loadDefinition(definition: DefinitionConstr): Promise<DefinitionBuilder> {
this._definition = definition;
return this;
}
this._definition
is referenced to the definition
pass in to function and will be modified when we call buildSwapOrder
for the first time. It leads to a behaviour that when you call buildSwapOrder
second time in one dex, we receive an error on these lines (eg: minswap)
await datumBuilder.loadDefinition(order)
.then((builder: DefinitionBuilder) => {
builder.pushParameters(swapParameters);
});
Because the order
definition was changed in first call (because it is a reference).
I change this._definition = definition;
to deep copy object and it worked.
Hi Team
Very excited to use this tool we are testing out the new Dexter SDK using NextJs and TypeScript, having a issue importing the lib. See Error screenshot. The code we are using is the basic setup code on the git and it seems to be erroring on line 16 when creating the Dexter object refer to Code screenshot, and also package screenshot. Error indicates files are missing not sure please advise if this is known issue or you have a quick fix.
For the Kupo data provider, this is especially needed since requests can fail gracefully. From the kupo changelog :
The server now returns an error 503 Service Unavailable when too many requests are pilling up. Note that the server can handle a relatively heavy load for most patterns but, for large addresses (such as the contract addresses of big marketplaces or DEXes), a single query can take a few seconds. If the server has exhausted all its available resources to serve additional requests, it'll fail gracefully with an error 503 and let the client handle requeuing of the request if necessary.
Apply to any other outside requests
Blockfrost
All
When using withSwapInToken(asset)
assets being IBTC or IUSD, I get the following: Input token doesn't exist in the set liquidity pool.
This works for all other tokens fine. I have checked all DEXS and the same error is raised.
I think this could be related to how these asset share the same policyid, with different names.
Blockfrost
All
I'm having issues with how Dexter is set up.
I created a minimal reproduction of this error in a separate repository.
https://github.com/NickJorens/dexter
npx tsc
node build/src/index.js
Any help or insights are greatly appreciated.
submit()
is called, so default to market but include asLimit()
& asMarket()
to switch between the twoGetting liquiditypools and then filtering them based on a their A or B asset isn't possible due to them not having the correct decimals. They're all 0.
When doing a request for Muesliswap dex, no pools are returned, when using Blockfrost, and shouldFallbackToApi
is enabled.
Test I was using is ADA/AGIX.
const request = dexter.newFetchRequest().forDexs([MuesliSwap.name]);
const poolsForToken = await request.getLiquidityPools('lovelace', new Asset(token?.policyId, token?.assetName, token?.decimals));
Blockfrost
All
Attempting to dynamically load the Dexter module inside a .js or .cjs file results in the following error:
Error [ERR_MODULE_NOT_FOUND]: Cannot find module 'E:\Data\Dev\project\discord\node_modules\@indigo-labs\dexter\build\constants' imported from E:\Data\Dev\project\discord\node_modules\@indigo-labs\dexter\build\index.js
I believe this is because all files imported within Dexter don't include their filetypes in their import paths. I'd like to avoid having to convert my entire existing project to TS, so if there's a workaround to get this going on plain JS that'd be great.
Code to repro:
await import("@indigo-labs/dexter")
.then((DexterLib) => {
//...
})
Platform: Windows
Node version: v18.13.0
flip()
needs to adjust the swap out amountWhen building a new swap request, and calling getEstimatedReceive
I receive 'The number 0.05 cannot be converted to a BigInt because it is not an integer'
This occurs randomly, and for me was occurring when using the Sundaeswap Dex on the second pool returned.
The pool this errors on has a poolFeePercentage of 0.0005
which is much lower than the others that succeed.
const buyTokenSwapRequest = dexter.newSwapRequest().forLiquidityPool(pool).withSwapInToken('lovelace').withSwapInAmount(BigInt(amount)); const amountOfTokenToReceive = buyTokenSwapRequest.getEstimatedReceive()
I think this could potentially be because this is the first pool with a poolFeePercentage when * 100 the result is still a decimal.
Will occur when wallet submitting the swap tx has received the funds
Suggestion - Is it possible that we could potentially add an option to get all the pools addresses for say 5 assets (MIN,AGIX,INDY etc for DEX's Minswap, Sundaeswap etc first, so our consuming application can re-use this data going forwards with potentially a get poolById going forwards for price querying per asset. This could help reduce requests to blockfrost if this is achievable and could potentially reduce the likelihood for autobans/rate limiting when calling out to get all the pools and filtering again.
Would be good to hear thoughts on this! If it is achievable or not :)
Give the ability to pass multiple assets when fetching pools, or at least attempt to remove duplicate calls when getting pools for two assets like iUSD & iBTC
I'm looking for the pool with DJED/iUSD but It's not showing up when running this code below.
Possible bug?
const dexter: Dexter = new Dexter(dexterConfig)
.withDataProvider(
new BlockfrostProvider({
projectId: "[REDACTED]",
url: "https://cardano-mainnet.blockfrost.io/api/v0",
})
)
.withMetadataProvider(new TokenRegistryProvider());
const djed = new Asset(
"8db269c3ec630e06ae29f74bc39edd1f87c819f1056206e879a1cd61",
"446a65644d6963726f555344",
6
);
const iusd = new Asset(
"f66d78b4a3cb3d37afa0ec36461e51ecbde00f26c8f0a68f94b69880",
"69555344",
6
);
console.log(djed);
// Basic fetch example
(
await dexter
.newFetchRequest()
.forDexs(WingRiders.name)
.getLiquidityPools(djed)
).forEach((pool: LiquidityPool) => {
console.log(pool);
});
Deno support
The package can't be resolved within the deno ecosystem ( due to its current Node based imports - no file extension ?).
I don't know the exact extent of what changes would need to occur in order to become fully deno compliant but I hope this is something that others might benefit from as well.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.