feat: upgrade to alex amm pool v2-1

This commit is contained in:
Kyle Fang
2024-06-16 14:47:55 +00:00
parent ebafbacba8
commit 716516508e
35 changed files with 4202 additions and 6815 deletions

View File

@@ -26,26 +26,21 @@ export enum Currency {
The AlexSDK class includes the following functions: The AlexSDK class includes the following functions:
```typescript ```javascript
export declare class AlexSDK { export declare class AlexSDK {
getFeeRate(from: Currency, to: Currency): Promise<bigint>; getFeeRate(from: Currency, to: Currency): Promise<bigint>;
getRouter(from: Currency, to: Currency): Promise<Currency[]>; getRouter(from: Currency, to: Currency): Promise<Currency[]>;
getAmountTo(from: Currency, fromAmount: bigint, to: Currency): Promise<bigint>; getAmountTo(from: Currency, fromAmount: bigint, to: Currency): Promise<bigint>;
runSwap(stxAddress: string, currencyX: Currency, currencyY: Currency, fromAmount: bigint, minDy: bigint, router: Currency[]): TxToBroadCast; runSwap(stxAddress: string, currencyX: Currency, currencyY: Currency, fromAmount: bigint, minDy: bigint, router: Currency[]): TxToBroadCast;
getCurrencyFrom(address: string): Currency | undefined; getCurrencyFrom(address: string): Currency | undefined;
getLatestPrices(): Promise< }
Partial<{
[currency in Currency]: number;
}>
>
}
``` ```
### getFee ### getFee
Rate Rate
Get the swap fee (liquidity provider fee) between two currencies. Get the swap fee (liquidity provider fee) between two currencies.
```typescript ```javascript
async function getFeeRate(from: Currency, to: Currency): Promise<bigint>; async function getFeeRate(from: Currency, to: Currency): Promise<bigint>;
``` ```
@@ -53,7 +48,7 @@ async function getFeeRate(from: Currency, to: Currency): Promise<bigint>;
Get the router path for swapping between two currencies. Get the router path for swapping between two currencies.
```typescript ```javascript
async function getRouter(from: Currency, to: Currency): Promise<Currency[]>; async function getRouter(from: Currency, to: Currency): Promise<Currency[]>;
``` ```
@@ -61,7 +56,7 @@ async function getRouter(from: Currency, to: Currency): Promise<Currency[]>;
Get the amount of destination currency that will be received when swapping from one currency to another. Get the amount of destination currency that will be received when swapping from one currency to another.
```typescript ```javascript
async function getAmountTo(from: Currency, fromAmount: bigint, to: Currency): Promise<bigint>; async function getAmountTo(from: Currency, fromAmount: bigint, to: Currency): Promise<bigint>;
``` ```
@@ -69,7 +64,7 @@ async function getAmountTo(from: Currency, fromAmount: bigint, to: Currency): Pr
Perform a swap between two currencies using the specified route and amount. Perform a swap between two currencies using the specified route and amount.
```typescript ```javascript
function runSwap(stxAddress: string, currencyX: Currency, currencyY: Currency, fromAmount: bigint, minDy: bigint, router: Currency[]): TxToBroadCast; function runSwap(stxAddress: string, currencyX: Currency, currencyY: Currency, fromAmount: bigint, minDy: bigint, router: Currency[]): TxToBroadCast;
``` ```
@@ -77,51 +72,10 @@ function runSwap(stxAddress: string, currencyX: Currency, currencyY: Currency, f
Get the corresponding currency for a given address. Get the corresponding currency for a given address.
```typescript ```javascript
function getCurrencyFrom(address: string): Currency | undefined; function getCurrencyFrom(address: string): Currency | undefined;
``` ```
### getAddressFrom
Get the corresponding currency for a given address.
```typescript
function getAddressFrom(currency: Exclude<Currency, Currency.STX>): string;
```
### isAlexSwapTransaction
### getLatestPrices
Get a list of token prices from Alex's price endpoint
```typescript
getLatestPrices(): Promise<
Partial<{
[currency in Currency]: number;
}>
>
```
It will do it's best to find the price, and where it can't, it will return undefined.
Check if a transaction is a swap transaction from Alex
```typescript
function isAlexSwapTransaction(deployer: string, contractName: string, functionName: string): boolean;
```
### broadcastSponsoredTx
Broadcast a sponsored transaction to Alex's sponsored tx services
```typescript
function broadcastSponsoredTx(txRaw: string): Promise<string>;
````
### isSponsoredSwapEnabled
Check if alex's swap sponsor service is activated
```typescript
function isSponsoredSwapEnabled(): Promise<boolean>;
````
## Installation ## Installation
You can install Alex-SDK using npm: You can install Alex-SDK using npm:
@@ -134,7 +88,7 @@ npm install alex-sdk
To use the AlexSDK, you can import it into your project and instantiate a new object: To use the AlexSDK, you can import it into your project and instantiate a new object:
```typescript ```javascript
import { AlexSDK, Currency } from 'alex-sdk'; import { AlexSDK, Currency } from 'alex-sdk';
const alex = new AlexSDK(); const alex = new AlexSDK();

View File

@@ -1,5 +1,5 @@
{ {
"version": "0.1.28", "version": "2.1.0-beta.5",
"license": "MIT", "license": "MIT",
"main": "dist/index.js", "main": "dist/index.js",
"typings": "dist/index.d.ts", "typings": "dist/index.d.ts",
@@ -11,18 +11,18 @@
"node": ">=10" "node": ">=10"
}, },
"scripts": { "scripts": {
"start": "tsdx watch", "start": "dts watch",
"build": "tsdx build", "build": "dts build",
"test": "tsdx test", "prepare": "pnpm run build",
"lint": "tsdx lint", "test": "dts test",
"prepare": "tsdx build", "lint": "dts lint",
"size": "size-limit", "size": "size-limit",
"gen:contract": "rm -rf src/generated/smartContract/*.ts && node ./scripts/gen-contract.ts", "gen:contract": "rm -rf src/generated/smartContract/* && tsx ./scripts/gen-contract.ts",
"analyze": "size-limit --why" "analyze": "size-limit --why"
}, },
"husky": { "husky": {
"hooks": { "hooks": {
"pre-commit": "tsdx lint" "pre-commit": "dts lint"
} }
}, },
"prettier": { "prettier": {
@@ -45,24 +45,26 @@
} }
], ],
"dependencies": { "dependencies": {
"clarity-codegen": "^0.3.5" "clarity-codegen": "^0.5.2"
}, },
"peerDependencies": { "peerDependencies": {
"@stacks/network": "*", "@stacks/network": "^6.3.0",
"@stacks/transactions": "*" "@stacks/transactions": "^6.2.0"
}, },
"devDependencies": { "devDependencies": {
"@size-limit/preset-small-lib": "^8.2.4", "@size-limit/preset-small-lib": "^8.2.4",
"@stacks/network": "^6.3.0", "@stacks/network": "^6.3.0",
"@stacks/stacks-blockchain-api-types": "^7.1.7", "@stacks/stacks-blockchain-api-types": "^7.11.0",
"@stacks/transactions": "^6.2.0", "@stacks/transactions": "^6.2.0",
"@types/node": "^20.1.0", "@types/jest": "^29.5.12",
"@types/node": "^20.14.2",
"esm": "^3.2.25", "esm": "^3.2.25",
"husky": "^8.0.3", "husky": "^8.0.3",
"prettier": "^2.8.4", "prettier": "^2.8.4",
"size-limit": "^8.2.4", "size-limit": "^8.2.4",
"tsdx": "^0.14.1", "dts-cli": "^2.0.5",
"tslib": "^2.5.0", "tslib": "^2.6.3",
"typescript": "^4.9.5" "tsx": "^4.15.5",
"typescript": "^5.4.5"
} }
} }

7247
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,18 +1,10 @@
const { generateContracts } = require('clarity-codegen/lib/generate'); import { generateContracts } from 'clarity-codegen/lib/generate';
const path = require('path'); import * as path from 'path';
const API_HOST = 'https://stacks-node-api.alexlab.co'; const API_HOST = 'https://stacks-node-api.alexlab.co';
const CONTRACT_DEPLOYER = 'SP3K8BC0PPEVCV7NZ6QSRWPQ2JE9E5B6N3PA0KBR9'; const CONTRACT_DEPLOYER = 'SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM';
const contracts = [ const contracts = ['amm-pool-v2-01'];
'swap-helper-v1-02',
'swap-helper-v1-03',
'amm-swap-pool',
'amm-swap-pool-v1-1',
'token-amm-swap-pool',
'swap-helper-bridged',
'swap-helper-bridged-v1-1',
];
(async function main() { (async function main() {
await generateContracts( await generateContracts(

View File

@@ -1,125 +1,90 @@
import { Currency } from './currency'; import { createCurrency, Currency } from './currency';
import { getLiquidityProviderFee } from './helpers/FeeHelper';
import { AMMSwapPool } from './utils/ammPool';
import { getRoute } from './helpers/RouteHelper';
import { getYAmountFromXAmount } from './helpers/RateHelper';
import { runSpot, TxToBroadCast } from './helpers/SwapHelper'; import { runSpot, TxToBroadCast } from './helpers/SwapHelper';
import { getLiquidityProviderFee } from './helpers/FeeHelper';
import { PoolData, PriceData, TokenMapping } from './types';
import { import {
fetchBalanceForAccount, fetchBalanceForAccount,
findCurrencyByNativeAddress, getMappingData,
getCurrencyNativeAddress, getPoolData,
} from './utils/currencyUtils'; getPrices,
import { fetchLatestPrices } from './utils/currencyPrice'; } from './utils/fetchData';
import { assignConfig, AssignConfigParams, configs } from './config'; import { getRoute } from './helpers/RouteHelper';
import { AlexContracts } from './generated/smartContract/contracts_Alex'; import { getYAmountFromXAmount } from './helpers/RateHelper';
import { import { fromEntries } from './utils/utils';
broadcastSponsoredTx,
isSponsoredSwapEnabled,
} from './utils/sponsoredTx';
import {
fetchSwappableCurrency,
fetchTokenList,
TokenInfo,
} from './utils/tokenlist';
export { SponsoredTxError, SponsoredTxErrorCode } from './utils/sponsoredTx';
export class AlexSDK { export class AlexSDK {
static configure(config: AssignConfigParams) { tokenMappings?: Promise<TokenMapping[]>;
assignConfig(config); pools?: Promise<PoolData[]>;
private async getTokenMappings(): Promise<TokenMapping[]> {
if (this.tokenMappings == null) {
this.tokenMappings = getMappingData();
}
return this.tokenMappings;
} }
getBalances(stxAddress: string): Promise<{ [currency in Currency]: bigint }> { private async getPools(): Promise<PoolData[]> {
return fetchBalanceForAccount(stxAddress); if (this.pools == null) {
this.pools = getPoolData();
}
return this.pools;
} }
getFeeRate(from: Currency, to: Currency): Promise<bigint> { private async getPrices(): Promise<PriceData[]> {
return getLiquidityProviderFee( return getPrices(await this.getTokenMappings());
from,
to,
AMMSwapPool.ammTokens,
AMMSwapPool.ammV1_1Tokens
);
} }
getRouter(from: Currency, to: Currency): Promise<Currency[]> { async getListAllCurrency(): Promise<Currency[]> {
return getRoute(from, to, AMMSwapPool.ammTokens, AMMSwapPool.ammV1_1Tokens); const mappings = await this.getTokenMappings();
return mappings.map((x) => x.token).map(createCurrency);
} }
getAmountTo( async getFeeRate(from: Currency, to: Currency): Promise<bigint> {
return getLiquidityProviderFee(from, to, await this.getPools());
}
async getRouter(from: Currency, to: Currency): Promise<Currency[]> {
return getRoute(from, to, await this.getPools());
}
async getAmountTo(
from: Currency, from: Currency,
fromAmount: bigint, fromAmount: bigint,
to: Currency to: Currency
): Promise<bigint> { ): Promise<bigint> {
return getYAmountFromXAmount( return getYAmountFromXAmount(from, to, fromAmount, await this.getPools());
from,
to,
fromAmount,
AMMSwapPool.ammTokens,
AMMSwapPool.ammV1_1Tokens
);
} }
runSwap( async runSwap(
stxAddress: string, stxAddress: string,
currencyX: Currency, currencyX: Currency,
currencyY: Currency, currencyY: Currency,
fromAmount: bigint, fromAmount: bigint,
minDy: bigint, minDy: bigint
router: Currency[] ): Promise<TxToBroadCast> {
): TxToBroadCast {
return runSpot( return runSpot(
stxAddress, stxAddress,
currencyX, currencyX,
currencyY, currencyY,
fromAmount, fromAmount,
minDy, minDy,
router, await this.getPools(),
AMMSwapPool.ammTokens, await this.getTokenMappings()
AMMSwapPool.ammV1_1Tokens
); );
} }
getCurrencyFrom(address: string): Currency | undefined { async getLatestPrices(): Promise<
return findCurrencyByNativeAddress(address);
}
getAddressFrom(currency: Exclude<Currency, Currency.STX>): string {
return getCurrencyNativeAddress(currency);
}
getLatestPrices(): Promise<
Partial<{ Partial<{
[currency in Currency]: number; [currency in Currency]: number;
}> }>
> { > {
return fetchLatestPrices(); const priceData = await this.getPrices();
return fromEntries(priceData.map((x) => [x.token, x.price]));
} }
isAlexSwapTransaction( async getBalances(
deployer: string, stxAddress: string
contractName: string, ): Promise<Partial<{ [currency in Currency]: bigint }>> {
functionName: string return fetchBalanceForAccount(stxAddress, await this.getTokenMappings());
): boolean {
if (deployer !== configs.CONTRACT_DEPLOYER) {
return false;
}
// @ts-ignore
return AlexContracts[contractName][functionName] != null;
}
broadcastSponsoredTx(txRaw: string): Promise<string> {
return broadcastSponsoredTx(txRaw);
}
isSponsoredSwapEnabled(): Promise<boolean> {
return isSponsoredSwapEnabled().catch(() => false);
}
fetchTokenList(): Promise<TokenInfo[]> {
return fetchTokenList();
}
fetchSwappableCurrency(): Promise<TokenInfo[]> {
return fetchSwappableCurrency();
} }
} }

View File

@@ -1,229 +1,6 @@
import { Currency } from './currency';
const CONTRACT_DEPLOYER = 'SP3K8BC0PPEVCV7NZ6QSRWPQ2JE9E5B6N3PA0KBR9';
const API_HOST = 'https://stacks-blockchain-lb.alexlab.co';
const IS_MAINNET = true;
const SPONSORED_TX_EXECUTOR = 'https://sponsor-tx.alexlab.co/v1/graphql';
const NATIVE_TOKEN_MAPPING: {
[P in Exclude<Currency, Currency.STX>]: {
decimals: number;
assetIdentifier: string;
};
} = {
[Currency.ALEX]: {
assetIdentifier:
'SP3K8BC0PPEVCV7NZ6QSRWPQ2JE9E5B6N3PA0KBR9.age000-governance-token::alex',
decimals: 1e8,
},
[Currency.sUSDT]: {
assetIdentifier:
'SP3K8BC0PPEVCV7NZ6QSRWPQ2JE9E5B6N3PA0KBR9.token-susdt::bridged-usdt',
decimals: 1e8,
},
[Currency.ATALEXV2]: {
assetIdentifier:
'SP3K8BC0PPEVCV7NZ6QSRWPQ2JE9E5B6N3PA0KBR9.auto-alex-v2::auto-alex-v2',
decimals: 1e8,
},
[Currency.XUSD]: {
assetIdentifier:
'SP2TZK01NKDC89J6TA56SA47SDF7RTHYEQ79AAB9A.Wrapped-USD::wrapped-usd',
decimals: 1e8,
},
[Currency.XBTC]: {
assetIdentifier:
'SP3DX3H4FEYZJZ586MFBS25ZW3HZDMEW92260R2PR.Wrapped-Bitcoin::wrapped-bitcoin',
decimals: 1e8,
},
[Currency.DIKO]: {
assetIdentifier:
'SP2C2YFP12AJZB4MABJBAJ55XECVS7E4PMMZ89YZR.arkadiko-token::diko',
decimals: 1e6,
},
[Currency.USDA]: {
assetIdentifier:
'SP2C2YFP12AJZB4MABJBAJ55XECVS7E4PMMZ89YZR.usda-token::usda',
decimals: 1e6,
},
[Currency.BANANA]: {
assetIdentifier:
'SP2KAF9RF86PVX3NEE27DFV1CQX0T4WGR41X3S45C.btc-monkeys-bananas::BANANA',
decimals: 1e6,
},
[Currency.SLIME]: {
assetIdentifier:
'SP125J1ADVYWGWB9NQRCVGKYAG73R17ZNMV17XEJ7.slime-token::SLIME',
decimals: 1e6,
},
[Currency.MIA]: {
assetIdentifier:
'SP1H1733V5MZ3SZ9XRW9FKYGEZT0JDGEB8Y634C7R.miamicoin-token-v2::miamicoin',
decimals: 1e6,
},
[Currency.NYCC]: {
assetIdentifier:
'SPSCWDV3RKV5ZRN1FQD84YE1NQFEDJ9R1F4DYQ11.newyorkcitycoin-token-v2::newyorkcitycoin',
decimals: 1e6,
},
[Currency.CORGI]: {
decimals: 1e6,
assetIdentifier: `SP3NE50GEXFG9SZGTT51P40X2CKYSZ5CC4ZTZ7A2G.welshcorgicoin-token::welshcorgicoin`,
},
[Currency.VIBES]: {
decimals: 1e8,
assetIdentifier: `SP27BB1Y2DGSXZHS7G9YHKTSH6KQ6BD3QG0AN3CR9.vibes-token::vibes-token`,
},
[Currency.BRC20_DB20]: {
decimals: 1e8,
assetIdentifier: `SP3K8BC0PPEVCV7NZ6QSRWPQ2JE9E5B6N3PA0KBR9.brc20-db20::brc20-db20`,
},
[Currency.BRC20_ORMM]: {
decimals: 1e8,
assetIdentifier: `SP3K8BC0PPEVCV7NZ6QSRWPQ2JE9E5B6N3PA0KBR9.brc20-ormm::brc20-ormm`,
},
[Currency.BRC20_CHAX]: {
decimals: 1e8,
assetIdentifier: `SP3K8BC0PPEVCV7NZ6QSRWPQ2JE9E5B6N3PA0KBR9.brc20-chax::brc20-chax`,
},
[Currency.BRC20_ORDG]: {
decimals: 1e8,
assetIdentifier: `SP3K8BC0PPEVCV7NZ6QSRWPQ2JE9E5B6N3PA0KBR9.brc20-ordg::brc20-ordg`,
},
[Currency.BRC20_REOS]: {
decimals: 1e8,
assetIdentifier: `SP3K8BC0PPEVCV7NZ6QSRWPQ2JE9E5B6N3PA0KBR9.brc20-reos::brc20-reos`,
},
[Currency.BRC20_ORNJ]: {
decimals: 1e8,
assetIdentifier: `SP3K8BC0PPEVCV7NZ6QSRWPQ2JE9E5B6N3PA0KBR9.brc20-ornj::brc20-ornj`,
},
[Currency.STX20_STXS]: {
decimals: 1e8,
assetIdentifier: `SP3K8BC0PPEVCV7NZ6QSRWPQ2JE9E5B6N3PA0KBR9.stx20-stxs::stx20-stxs`,
},
[Currency.aBTC]: {
decimals: 1e8,
assetIdentifier: `SP3K8BC0PPEVCV7NZ6QSRWPQ2JE9E5B6N3PA0KBR9.token-abtc::bridged-btc`,
},
[Currency.sLUNR]: {
decimals: 1e8,
assetIdentifier: `SP3K8BC0PPEVCV7NZ6QSRWPQ2JE9E5B6N3PA0KBR9.token-slunr::bridged-lunr`,
},
[Currency.BRC20_CHAX]: {
decimals: 1e8,
assetIdentifier: `SP3K8BC0PPEVCV7NZ6QSRWPQ2JE9E5B6N3PA0KBR9.brc20-chax::brc20-chax`,
},
[Currency.LEO]: {
decimals: 1e6,
assetIdentifier: 'SP1AY6K3PQV5MRT6R4S671NWW2FRVPKM0BR162CT6.leo-token::leo',
},
[Currency.MEGA]: {
decimals: 1e2,
assetIdentifier: 'SP3D6PV2ACBPEKYJTCMH7HEN02KP87QSP8KTEH335.mega::mega',
},
[Currency.GUS]: {
decimals: 1e6,
assetIdentifier: 'SP1JFFSYTSH7VBM54K29ZFS9H4SVB67EA8VT2MYJ9.gus-token::gus',
},
[Currency.BRC20_ORMM]: {
decimals: 1e8,
assetIdentifier: `SP3K8BC0PPEVCV7NZ6QSRWPQ2JE9E5B6N3PA0KBR9.brc20-ormm::brc20-ormm`,
},
[Currency.BRC20_ORDG]: {
decimals: 1e8,
assetIdentifier: `SP3K8BC0PPEVCV7NZ6QSRWPQ2JE9E5B6N3PA0KBR9.brc20-ordg::brc20-ordg`,
},
[Currency.LONG]: {
assetIdentifier:
'SP265WBWD4NH7TVPYQTVD23X3607NNK4484DTXQZ3.longcoin::longcoin',
decimals: 1e6,
},
[Currency.WNOTHING]: {
assetIdentifier:
'SP32AEEF6WW5Y0NMJ1S8SBSZDAY8R5J32NBZFPKKZ.wrapped-nothing-v8::wrapped-nthng',
decimals: 1,
},
[Currency.AEWBTC]: {
assetIdentifier:
'SP3Y2ZSH8P7D50B0VBTSX11S7XSG24M1VB9YFQA4K.token-aewbtc::aeWBTC',
decimals: 1e8,
},
[Currency.MAX]: {
assetIdentifier: 'SP7V1SE7EA3ZG3QTWSBA2AAG8SRHEYJ06EBBD1J2.max-token::max',
decimals: 1e6,
},
[Currency.PLAY]: {
assetIdentifier: 'SP1PW804599BZ46B4A0FYH86ED26XPJA7SFYNK1XS.play::play',
decimals: 1e6,
},
[Currency.AEUSDC]: {
assetIdentifier:
'SP3Y2ZSH8P7D50B0VBTSX11S7XSG24M1VB9YFQA4K.token-aeusdc::aeUSDC',
decimals: 1e6,
},
[Currency.PEPE]: {
assetIdentifier:
'SP1Z92MPDQEWZXW36VX71Q25HKF5K2EPCJ304F275.tokensoft-token-v4k68639zxz::tokensoft-token',
decimals: 1e3,
},
[Currency.MICK]: {
assetIdentifier:
'SP2Y8T3TR3FKH3Y2FPZVNQAEKNJXKWVS4RVQF48JE.stakemouse::stakemouse',
decimals: 1e6,
},
[Currency.NOPE]: {
assetIdentifier: 'SP32AEEF6WW5Y0NMJ1S8SBSZDAY8R5J32NBZFPKKZ.nope::NOT',
decimals: 1,
},
[Currency.FAST]: {
assetIdentifier: 'SP3951VNPC55BMS9RCF6SKRZP4K3Q2PQ2RSM1DD1V.fast::fast',
decimals: 1e6,
},
[Currency.FRODO]: {
assetIdentifier:
'SPPK49DG7WR1J5D50GZ4W7DYYWM5MAXSX0ZA9VEJ.FrodoSaylorKeanuPepe10Inu-token-v69::FrodoSaylorKeanuPepe10Inu',
decimals: 1e6,
},
[Currency.PICSUM]: {
assetIdentifier: `${CONTRACT_DEPLOYER}.token-picsum-404::picsum-404`,
decimals: 1e8,
},
[Currency.WIF]: {
assetIdentifier: `SP3WPNAEBYMX06RQNNYTH5PTJ1FRGX5A13ZZMZ01D.dogwifhat-token::wif`,
decimals: 1e6,
},
[Currency.LQSTX]: {
assetIdentifier: `ST1HTBVD3JG9C05J7HBJTHGR0GGW7KXW28M5JS8QE.token-lqstx::lqstx`,
decimals: 1e6,
},
[Currency.sSKO]: {
assetIdentifier: `SP3K8BC0PPEVCV7NZ6QSRWPQ2JE9E5B6N3PA0KBR9.token-ssko::token-ssko`,
decimals: 1e8,
},
};
export const configs = { export const configs = {
IS_MAINNET, CONTRACT_DEPLOYER: 'SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM',
CONTRACT_DEPLOYER, API_HOST: "https://api.alexgo.io",
API_HOST, STACKS_API_HOST: "https://api.hiro.so",
NATIVE_TOKEN_MAPPING, READONLY_CALL_API_HOST: "https://stacks-node.alexlab.co",
SPONSORED_TX_EXECUTOR,
}; };
type AlexConfig = typeof configs;
export type AssignConfigParams = Partial<
Omit<AlexConfig, 'NATIVE_TOKEN_MAPPING'>
> & {
NATIVE_TOKEN_MAPPING: Partial<AlexConfig['NATIVE_TOKEN_MAPPING']>;
};
export function assignConfig(newConfigs: AssignConfigParams) {
Object.assign(configs, newConfigs, {
NATIVE_TOKEN_MAPPING: {
...NATIVE_TOKEN_MAPPING,
...newConfigs.NATIVE_TOKEN_MAPPING,
},
});
}

View File

@@ -1,47 +1,7 @@
export enum Currency { export type Currency = `${string}.${string}` & { readonly brand: unique symbol };
STX = 'token-wstx',
ALEX = 'age000-governance-token', export function createCurrency(value: string): Currency {
USDA = 'token-wusda', return value as Currency;
BANANA = 'token-wban',
XBTC = 'token-wbtc',
DIKO = 'token-wdiko',
SLIME = 'token-wslm',
XUSD = 'token-wxusd',
MIA = 'token-wmia',
NYCC = 'token-wnycc',
CORGI = 'token-wcorgi',
ATALEXV2 = 'auto-alex-v2',
sUSDT = 'token-susdt',
VIBES = 'token-wvibes',
aBTC = 'token-abtc',
sLUNR = 'token-slunr',
LEO = "token-wleo",
MEGA = "token-wmega-v2",
GUS = "token-wgus",
LONG = "token-wlong",
WNOTHING = "token-wnthng",
LQSTX = "token-wlqstx",
AEWBTC = "token-waewbtc",
MAX = "token-wmax",
PLAY = "token-wplay",
AEUSDC = "token-waeusdc",
PEPE = "token-wpepe",
MICK = "token-wmick",
NOPE = "token-wnope",
FAST = "token-wfast",
FRODO = "token-wfrodo",
PICSUM = "token-wpicsum",
WIF = "token-wwif",
BRC20_DB20 = "brc20-db20",
BRC20_ORMM = "brc20-ormm",
BRC20_CHAX = "brc20-chax",
BRC20_ORDG = "brc20-ordg",
BRC20_REOS = "brc20-reos",
BRC20_ORNJ = "brc20-ornj",
STX20_STXS = "stx20-stxs",
sSKO = "token-ssko",
} }
export const STXCurrency = createCurrency('SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.token-wstx-v2')

View File

@@ -1,21 +1,22 @@
import { import {
defineContract, defineContract,
principalT, traitT,
uintT, uintT,
optionalT, optionalT,
responseSimpleT, responseSimpleT,
tupleT, tupleT,
principalT,
booleanT, booleanT,
noneT noneT
} from "../smartContractHelpers/codegenImport" } from "../smartContractHelpers/codegenImport"
export const ammSwapPoolV11 = defineContract({ export const ammPoolV201 = defineContract({
"amm-swap-pool-v1-1": { "amm-pool-v2-01": {
'add-to-position': { 'add-to-position': {
input: [ input: [
{ name: 'token-x-trait', type: principalT }, { name: 'token-x-trait', type: traitT },
{ name: 'token-y-trait', type: principalT }, { name: 'token-y-trait', type: traitT },
{ name: 'factor', type: uintT }, { name: 'factor', type: uintT },
{ name: 'dx', type: uintT }, { name: 'dx', type: uintT },
{ name: 'max-dy', type: optionalT(uintT, ) } { name: 'max-dy', type: optionalT(uintT, ) }
@@ -25,14 +26,14 @@ export const ammSwapPoolV11 = defineContract({
}, },
'create-pool': { 'create-pool': {
input: [ input: [
{ name: 'token-x-trait', type: principalT }, { name: 'token-x-trait', type: traitT },
{ name: 'token-y-trait', type: principalT }, { name: 'token-y-trait', type: traitT },
{ name: 'factor', type: uintT }, { name: 'factor', type: uintT },
{ name: 'pool-owner', type: principalT }, { name: 'pool-owner', type: principalT },
{ name: 'dx', type: uintT }, { name: 'dx', type: uintT },
{ name: 'dy', type: uintT } { name: 'dy', type: uintT }
], ],
output: responseSimpleT(booleanT, ), output: responseSimpleT(tupleT({ dx: uintT, dy: uintT, supply: uintT }, ), ),
mode: 'public' mode: 'public'
}, },
pause: { pause: {
@@ -42,19 +43,14 @@ export const ammSwapPoolV11 = defineContract({
}, },
'reduce-position': { 'reduce-position': {
input: [ input: [
{ name: 'token-x-trait', type: principalT }, { name: 'token-x-trait', type: traitT },
{ name: 'token-y-trait', type: principalT }, { name: 'token-y-trait', type: traitT },
{ name: 'factor', type: uintT }, { name: 'factor', type: uintT },
{ name: 'percent', type: uintT } { name: 'percent', type: uintT }
], ],
output: responseSimpleT(tupleT({ dx: uintT, dy: uintT }, ), ), output: responseSimpleT(tupleT({ dx: uintT, dy: uintT }, ), ),
mode: 'public' mode: 'public'
}, },
'set-contract-owner': {
input: [ { name: 'owner', type: principalT } ],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
'set-end-block': { 'set-end-block': {
input: [ input: [
{ name: 'token-x', type: principalT }, { name: 'token-x', type: principalT },
@@ -85,16 +81,6 @@ export const ammSwapPoolV11 = defineContract({
output: responseSimpleT(booleanT, ), output: responseSimpleT(booleanT, ),
mode: 'public' mode: 'public'
}, },
'set-fee-rebate': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: uintT },
{ name: 'fee-rebate', type: uintT }
],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
'set-max-in-ratio': { 'set-max-in-ratio': {
input: [ input: [
{ name: 'token-x', type: principalT }, { name: 'token-x', type: principalT },
@@ -135,16 +121,6 @@ export const ammSwapPoolV11 = defineContract({
output: responseSimpleT(booleanT, ), output: responseSimpleT(booleanT, ),
mode: 'public' mode: 'public'
}, },
'set-pool-owner': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: uintT },
{ name: 'pool-owner', type: principalT }
],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
'set-start-block': { 'set-start-block': {
input: [ input: [
{ name: 'token-x', type: principalT }, { name: 'token-x', type: principalT },
@@ -155,11 +131,6 @@ export const ammSwapPoolV11 = defineContract({
output: responseSimpleT(booleanT, ), output: responseSimpleT(booleanT, ),
mode: 'public' mode: 'public'
}, },
'set-switch-threshold': {
input: [ { name: 'new-threshold', type: uintT } ],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
'set-threshold-x': { 'set-threshold-x': {
input: [ input: [
{ name: 'token-x', type: principalT }, { name: 'token-x', type: principalT },
@@ -182,8 +153,8 @@ export const ammSwapPoolV11 = defineContract({
}, },
'swap-helper': { 'swap-helper': {
input: [ input: [
{ name: 'token-x-trait', type: principalT }, { name: 'token-x-trait', type: traitT },
{ name: 'token-y-trait', type: principalT }, { name: 'token-y-trait', type: traitT },
{ name: 'factor', type: uintT }, { name: 'factor', type: uintT },
{ name: 'dx', type: uintT }, { name: 'dx', type: uintT },
{ name: 'min-dy', type: optionalT(uintT, ) } { name: 'min-dy', type: optionalT(uintT, ) }
@@ -193,9 +164,9 @@ export const ammSwapPoolV11 = defineContract({
}, },
'swap-helper-a': { 'swap-helper-a': {
input: [ input: [
{ name: 'token-x-trait', type: principalT }, { name: 'token-x-trait', type: traitT },
{ name: 'token-y-trait', type: principalT }, { name: 'token-y-trait', type: traitT },
{ name: 'token-z-trait', type: principalT }, { name: 'token-z-trait', type: traitT },
{ name: 'factor-x', type: uintT }, { name: 'factor-x', type: uintT },
{ name: 'factor-y', type: uintT }, { name: 'factor-y', type: uintT },
{ name: 'dx', type: uintT }, { name: 'dx', type: uintT },
@@ -206,10 +177,10 @@ export const ammSwapPoolV11 = defineContract({
}, },
'swap-helper-b': { 'swap-helper-b': {
input: [ input: [
{ name: 'token-x-trait', type: principalT }, { name: 'token-x-trait', type: traitT },
{ name: 'token-y-trait', type: principalT }, { name: 'token-y-trait', type: traitT },
{ name: 'token-z-trait', type: principalT }, { name: 'token-z-trait', type: traitT },
{ name: 'token-w-trait', type: principalT }, { name: 'token-w-trait', type: traitT },
{ name: 'factor-x', type: uintT }, { name: 'factor-x', type: uintT },
{ name: 'factor-y', type: uintT }, { name: 'factor-y', type: uintT },
{ name: 'factor-z', type: uintT }, { name: 'factor-z', type: uintT },
@@ -221,11 +192,11 @@ export const ammSwapPoolV11 = defineContract({
}, },
'swap-helper-c': { 'swap-helper-c': {
input: [ input: [
{ name: 'token-x-trait', type: principalT }, { name: 'token-x-trait', type: traitT },
{ name: 'token-y-trait', type: principalT }, { name: 'token-y-trait', type: traitT },
{ name: 'token-z-trait', type: principalT }, { name: 'token-z-trait', type: traitT },
{ name: 'token-w-trait', type: principalT }, { name: 'token-w-trait', type: traitT },
{ name: 'token-v-trait', type: principalT }, { name: 'token-v-trait', type: traitT },
{ name: 'factor-x', type: uintT }, { name: 'factor-x', type: uintT },
{ name: 'factor-y', type: uintT }, { name: 'factor-y', type: uintT },
{ name: 'factor-z', type: uintT }, { name: 'factor-z', type: uintT },
@@ -238,8 +209,8 @@ export const ammSwapPoolV11 = defineContract({
}, },
'swap-x-for-y': { 'swap-x-for-y': {
input: [ input: [
{ name: 'token-x-trait', type: principalT }, { name: 'token-x-trait', type: traitT },
{ name: 'token-y-trait', type: principalT }, { name: 'token-y-trait', type: traitT },
{ name: 'factor', type: uintT }, { name: 'factor', type: uintT },
{ name: 'dx', type: uintT }, { name: 'dx', type: uintT },
{ name: 'min-dy', type: optionalT(uintT, ) } { name: 'min-dy', type: optionalT(uintT, ) }
@@ -249,8 +220,8 @@ export const ammSwapPoolV11 = defineContract({
}, },
'swap-y-for-x': { 'swap-y-for-x': {
input: [ input: [
{ name: 'token-x-trait', type: principalT }, { name: 'token-x-trait', type: traitT },
{ name: 'token-y-trait', type: principalT }, { name: 'token-y-trait', type: traitT },
{ name: 'factor', type: uintT }, { name: 'factor', type: uintT },
{ name: 'dy', type: uintT }, { name: 'dy', type: uintT },
{ name: 'min-dx', type: optionalT(uintT, ) } { name: 'min-dx', type: optionalT(uintT, ) }
@@ -324,11 +295,6 @@ export const ammSwapPoolV11 = defineContract({
output: responseSimpleT(tupleT({ 'balance-x': uintT, 'balance-y': uintT }, ), ), output: responseSimpleT(tupleT({ 'balance-x': uintT, 'balance-y': uintT }, ), ),
mode: 'readonly' mode: 'readonly'
}, },
'get-contract-owner': {
input: [],
output: responseSimpleT(principalT, ),
mode: 'readonly'
},
'get-end-block': { 'get-end-block': {
input: [ input: [
{ name: 'token-x', type: principalT }, { name: 'token-x', type: principalT },
@@ -444,6 +410,7 @@ export const ammSwapPoolV11 = defineContract({
output: responseSimpleT(uintT, ), output: responseSimpleT(uintT, ),
mode: 'readonly' mode: 'readonly'
}, },
'get-max-ratio-limit': { input: [], output: uintT, mode: 'readonly' },
'get-oracle-average': { 'get-oracle-average': {
input: [ input: [
{ name: 'token-x', type: principalT }, { name: 'token-x', type: principalT },
@@ -676,39 +643,14 @@ export const ammSwapPoolV11 = defineContract({
output: responseSimpleT(uintT, ), output: responseSimpleT(uintT, ),
mode: 'readonly' mode: 'readonly'
}, },
'is-blocklisted-or-default': {
input: [ { name: 'sender', type: principalT } ],
output: booleanT,
mode: 'readonly'
},
'is-dao-or-extension': { input: [], output: responseSimpleT(booleanT, ), mode: 'readonly' },
'is-paused': { input: [], output: booleanT, mode: 'readonly' }, 'is-paused': { input: [], output: booleanT, mode: 'readonly' },
'pools-data-map': { paused: { input: noneT, output: booleanT, mode: 'variable' }
input: tupleT({ factor: uintT, 'token-x': principalT, 'token-y': principalT }, ),
output: optionalT(tupleT({
'balance-x': uintT,
'balance-y': uintT,
'end-block': uintT,
'fee-rate-x': uintT,
'fee-rate-y': uintT,
'fee-rebate': uintT,
'max-in-ratio': uintT,
'max-out-ratio': uintT,
'oracle-average': uintT,
'oracle-enabled': booleanT,
'oracle-resilient': uintT,
'pool-id': uintT,
'pool-owner': principalT,
'start-block': uintT,
'threshold-x': uintT,
'threshold-y': uintT,
'total-supply': uintT
}, ), ),
mode: 'mapEntry'
},
'pools-id-map': {
input: uintT,
output: optionalT(tupleT({ factor: uintT, 'token-x': principalT, 'token-y': principalT }, ), ),
mode: 'mapEntry'
},
'contract-owner': { input: noneT, output: principalT, mode: 'variable' },
paused: { input: noneT, output: booleanT, mode: 'variable' },
'pool-nonce': { input: noneT, output: uintT, mode: 'variable' },
'switch-threshold': { input: noneT, output: uintT, mode: 'variable' }
} }
} as const) } as const)

View File

@@ -1,685 +0,0 @@
import {
defineContract,
principalT,
uintT,
optionalT,
responseSimpleT,
tupleT,
booleanT,
noneT
} from "../smartContractHelpers/codegenImport"
export const ammSwapPool = defineContract({
"amm-swap-pool": {
'add-to-position': {
input: [
{ name: 'token-x-trait', type: principalT },
{ name: 'token-y-trait', type: principalT },
{ name: 'factor', type: uintT },
{ name: 'dx', type: uintT },
{ name: 'max-dy', type: optionalT(uintT, ) }
],
output: responseSimpleT(tupleT({ dx: uintT, dy: uintT, supply: uintT }, ), ),
mode: 'public'
},
'create-pool': {
input: [
{ name: 'token-x-trait', type: principalT },
{ name: 'token-y-trait', type: principalT },
{ name: 'factor', type: uintT },
{ name: 'pool-owner', type: principalT },
{ name: 'dx', type: uintT },
{ name: 'dy', type: uintT }
],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
pause: {
input: [ { name: 'new-paused', type: booleanT } ],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
'reduce-position': {
input: [
{ name: 'token-x-trait', type: principalT },
{ name: 'token-y-trait', type: principalT },
{ name: 'factor', type: uintT },
{ name: 'percent', type: uintT }
],
output: responseSimpleT(tupleT({ dx: uintT, dy: uintT }, ), ),
mode: 'public'
},
'set-contract-owner': {
input: [ { name: 'owner', type: principalT } ],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
'set-end-block': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: uintT },
{ name: 'new-end-block', type: uintT }
],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
'set-fee-rate-x': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: uintT },
{ name: 'fee-rate-x', type: uintT }
],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
'set-fee-rate-y': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: uintT },
{ name: 'fee-rate-y', type: uintT }
],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
'set-fee-rebate': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: uintT },
{ name: 'fee-rebate', type: uintT }
],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
'set-max-in-ratio': {
input: [ { name: 'new-max-in-ratio', type: uintT } ],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
'set-max-out-ratio': {
input: [ { name: 'new-max-out-ratio', type: uintT } ],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
'set-oracle-average': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: uintT },
{ name: 'new-oracle-average', type: uintT }
],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
'set-oracle-enabled': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: uintT },
{ name: 'enabled', type: booleanT }
],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
'set-pool-owner': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: uintT },
{ name: 'pool-owner', type: principalT }
],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
'set-start-block': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: uintT },
{ name: 'new-start-block', type: uintT }
],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
'set-switch-threshold': {
input: [ { name: 'new-threshold', type: uintT } ],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
'set-threshold-x': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: uintT },
{ name: 'new-threshold', type: uintT }
],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
'set-threshold-y': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: uintT },
{ name: 'new-threshold', type: uintT }
],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
'swap-helper': {
input: [
{ name: 'token-x-trait', type: principalT },
{ name: 'token-y-trait', type: principalT },
{ name: 'factor', type: uintT },
{ name: 'dx', type: uintT },
{ name: 'min-dy', type: optionalT(uintT, ) }
],
output: responseSimpleT(uintT, ),
mode: 'public'
},
'swap-helper-a': {
input: [
{ name: 'token-x-trait', type: principalT },
{ name: 'token-y-trait', type: principalT },
{ name: 'token-z-trait', type: principalT },
{ name: 'factor-x', type: uintT },
{ name: 'factor-y', type: uintT },
{ name: 'dx', type: uintT },
{ name: 'min-dz', type: optionalT(uintT, ) }
],
output: responseSimpleT(uintT, ),
mode: 'public'
},
'swap-helper-b': {
input: [
{ name: 'token-x-trait', type: principalT },
{ name: 'token-y-trait', type: principalT },
{ name: 'token-z-trait', type: principalT },
{ name: 'token-w-trait', type: principalT },
{ name: 'factor-x', type: uintT },
{ name: 'factor-y', type: uintT },
{ name: 'factor-z', type: uintT },
{ name: 'dx', type: uintT },
{ name: 'min-dw', type: optionalT(uintT, ) }
],
output: responseSimpleT(uintT, ),
mode: 'public'
},
'swap-helper-c': {
input: [
{ name: 'token-x-trait', type: principalT },
{ name: 'token-y-trait', type: principalT },
{ name: 'token-z-trait', type: principalT },
{ name: 'token-w-trait', type: principalT },
{ name: 'token-v-trait', type: principalT },
{ name: 'factor-x', type: uintT },
{ name: 'factor-y', type: uintT },
{ name: 'factor-z', type: uintT },
{ name: 'factor-w', type: uintT },
{ name: 'dx', type: uintT },
{ name: 'min-dv', type: optionalT(uintT, ) }
],
output: responseSimpleT(uintT, ),
mode: 'public'
},
'swap-x-for-y': {
input: [
{ name: 'token-x-trait', type: principalT },
{ name: 'token-y-trait', type: principalT },
{ name: 'factor', type: uintT },
{ name: 'dx', type: uintT },
{ name: 'min-dy', type: optionalT(uintT, ) }
],
output: responseSimpleT(tupleT({ dx: uintT, dy: uintT }, ), ),
mode: 'public'
},
'swap-y-for-x': {
input: [
{ name: 'token-x-trait', type: principalT },
{ name: 'token-y-trait', type: principalT },
{ name: 'factor', type: uintT },
{ name: 'dy', type: uintT },
{ name: 'min-dx', type: optionalT(uintT, ) }
],
output: responseSimpleT(tupleT({ dx: uintT, dy: uintT }, ), ),
mode: 'public'
},
'check-pool-status': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: uintT }
],
output: responseSimpleT(booleanT, ),
mode: 'readonly'
},
'fee-helper': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: uintT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'fee-helper-a': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'token-z', type: principalT },
{ name: 'factor-x', type: uintT },
{ name: 'factor-y', type: uintT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'fee-helper-b': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'token-z', type: principalT },
{ name: 'token-w', type: principalT },
{ name: 'factor-x', type: uintT },
{ name: 'factor-y', type: uintT },
{ name: 'factor-z', type: uintT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'fee-helper-c': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'token-z', type: principalT },
{ name: 'token-w', type: principalT },
{ name: 'token-v', type: principalT },
{ name: 'factor-x', type: uintT },
{ name: 'factor-y', type: uintT },
{ name: 'factor-z', type: uintT },
{ name: 'factor-w', type: uintT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'get-balances': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: uintT }
],
output: responseSimpleT(tupleT({ 'balance-x': uintT, 'balance-y': uintT }, ), ),
mode: 'readonly'
},
'get-contract-owner': {
input: [],
output: responseSimpleT(principalT, ),
mode: 'readonly'
},
'get-end-block': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: uintT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'get-fee-rate-x': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: uintT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'get-fee-rate-y': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: uintT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'get-fee-rebate': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: uintT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'get-helper': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: uintT },
{ name: 'dx', type: uintT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'get-helper-a': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'token-z', type: principalT },
{ name: 'factor-x', type: uintT },
{ name: 'factor-y', type: uintT },
{ name: 'dx', type: uintT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'get-helper-b': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'token-z', type: principalT },
{ name: 'token-w', type: principalT },
{ name: 'factor-x', type: uintT },
{ name: 'factor-y', type: uintT },
{ name: 'factor-z', type: uintT },
{ name: 'dx', type: uintT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'get-helper-c': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'token-z', type: principalT },
{ name: 'token-w', type: principalT },
{ name: 'token-v', type: principalT },
{ name: 'factor-x', type: uintT },
{ name: 'factor-y', type: uintT },
{ name: 'factor-z', type: uintT },
{ name: 'factor-w', type: uintT },
{ name: 'dx', type: uintT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'get-invariant': {
input: [
{ name: 'balance-x', type: uintT },
{ name: 'balance-y', type: uintT },
{ name: 't', type: uintT }
],
output: uintT,
mode: 'readonly'
},
'get-max-in-ratio': { input: [], output: uintT, mode: 'readonly' },
'get-max-out-ratio': { input: [], output: uintT, mode: 'readonly' },
'get-oracle-average': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: uintT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'get-oracle-enabled': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: uintT }
],
output: responseSimpleT(booleanT, ),
mode: 'readonly'
},
'get-oracle-instant': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: uintT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'get-oracle-resilient': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: uintT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'get-pool-details': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: uintT }
],
output: responseSimpleT(tupleT({
'balance-x': uintT,
'balance-y': uintT,
'end-block': uintT,
'fee-rate-x': uintT,
'fee-rate-y': uintT,
'fee-rebate': uintT,
'oracle-average': uintT,
'oracle-enabled': booleanT,
'oracle-resilient': uintT,
'pool-id': uintT,
'pool-owner': principalT,
'start-block': uintT,
'threshold-x': uintT,
'threshold-y': uintT,
'total-supply': uintT
}, ), ),
mode: 'readonly'
},
'get-pool-details-by-id': {
input: [ { name: 'pool-id', type: uintT } ],
output: responseSimpleT(tupleT({ factor: uintT, 'token-x': principalT, 'token-y': principalT }, ), ),
mode: 'readonly'
},
'get-pool-exists': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: uintT }
],
output: optionalT(tupleT({
'balance-x': uintT,
'balance-y': uintT,
'end-block': uintT,
'fee-rate-x': uintT,
'fee-rate-y': uintT,
'fee-rebate': uintT,
'oracle-average': uintT,
'oracle-enabled': booleanT,
'oracle-resilient': uintT,
'pool-id': uintT,
'pool-owner': principalT,
'start-block': uintT,
'threshold-x': uintT,
'threshold-y': uintT,
'total-supply': uintT
}, ), ),
mode: 'readonly'
},
'get-pool-owner': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: uintT }
],
output: responseSimpleT(principalT, ),
mode: 'readonly'
},
'get-position-given-burn': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: uintT },
{ name: 'token', type: uintT }
],
output: responseSimpleT(tupleT({ dx: uintT, dy: uintT }, ), ),
mode: 'readonly'
},
'get-position-given-mint': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: uintT },
{ name: 'token', type: uintT }
],
output: responseSimpleT(tupleT({ dx: uintT, dy: uintT }, ), ),
mode: 'readonly'
},
'get-price': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: uintT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'get-start-block': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: uintT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'get-switch-threshold': { input: [], output: uintT, mode: 'readonly' },
'get-threshold-x': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: uintT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'get-threshold-y': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: uintT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'get-token-given-position': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: uintT },
{ name: 'dx', type: uintT },
{ name: 'max-dy', type: optionalT(uintT, ) }
],
output: responseSimpleT(tupleT({ dy: uintT, token: uintT }, ), ),
mode: 'readonly'
},
'get-x-given-price': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: uintT },
{ name: 'price', type: uintT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'get-x-given-y': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: uintT },
{ name: 'dy', type: uintT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'get-x-in-given-y-out': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: uintT },
{ name: 'dy', type: uintT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'get-y-given-price': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: uintT },
{ name: 'price', type: uintT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'get-y-given-x': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: uintT },
{ name: 'dx', type: uintT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'get-y-in-given-x-out': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'factor', type: uintT },
{ name: 'dx', type: uintT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'is-paused': { input: [], output: booleanT, mode: 'readonly' },
'pools-data-map': {
input: tupleT({ factor: uintT, 'token-x': principalT, 'token-y': principalT }, ),
output: optionalT(tupleT({
'balance-x': uintT,
'balance-y': uintT,
'end-block': uintT,
'fee-rate-x': uintT,
'fee-rate-y': uintT,
'fee-rebate': uintT,
'oracle-average': uintT,
'oracle-enabled': booleanT,
'oracle-resilient': uintT,
'pool-id': uintT,
'pool-owner': principalT,
'start-block': uintT,
'threshold-x': uintT,
'threshold-y': uintT,
'total-supply': uintT
}, ), ),
mode: 'mapEntry'
},
'pools-id-map': {
input: uintT,
output: optionalT(tupleT({ factor: uintT, 'token-x': principalT, 'token-y': principalT }, ), ),
mode: 'mapEntry'
},
'MAX-IN-RATIO': { input: noneT, output: uintT, mode: 'variable' },
'MAX-OUT-RATIO': { input: noneT, output: uintT, mode: 'variable' },
'contract-owner': { input: noneT, output: principalT, mode: 'variable' },
paused: { input: noneT, output: booleanT, mode: 'variable' },
'pool-nonce': { input: noneT, output: uintT, mode: 'variable' },
'switch-threshold': { input: noneT, output: uintT, mode: 'variable' }
}
} as const)

View File

@@ -1,142 +0,0 @@
import {
defineContract,
principalT,
uintT,
optionalT,
responseSimpleT,
listT
} from "../smartContractHelpers/codegenImport"
export const swapHelperBridgedV11 = defineContract({
"swap-helper-bridged-v1-1": {
'swap-helper-from-amm': {
input: [
{ name: 'token-x-trait', type: principalT },
{ name: 'token-y-trait', type: principalT },
{ name: 'token-z-trait', type: principalT },
{ name: 'factor-x', type: uintT },
{ name: 'dx', type: uintT },
{ name: 'min-dz', type: optionalT(uintT, ) }
],
output: responseSimpleT(uintT, ),
mode: 'public'
},
'swap-helper-to-amm': {
input: [
{ name: 'token-x-trait', type: principalT },
{ name: 'token-y-trait', type: principalT },
{ name: 'token-z-trait', type: principalT },
{ name: 'factor-y', type: uintT },
{ name: 'dx', type: uintT },
{ name: 'min-dz', type: optionalT(uintT, ) }
],
output: responseSimpleT(uintT, ),
mode: 'public'
},
'fee-helper-from-amm': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'token-z', type: principalT },
{ name: 'factor-x', type: uintT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'fee-helper-to-amm': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'token-z', type: principalT },
{ name: 'factor-y', type: uintT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'get-helper-from-amm': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'token-z', type: principalT },
{ name: 'factor-x', type: uintT },
{ name: 'dx', type: uintT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'get-helper-to-amm': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'token-z', type: principalT },
{ name: 'factor-y', type: uintT },
{ name: 'dx', type: uintT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'oracle-instant-helper-from-amm': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'token-z', type: principalT },
{ name: 'factor-x', type: uintT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'oracle-instant-helper-to-amm': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'token-z', type: principalT },
{ name: 'factor-y', type: uintT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'oracle-resilient-helper-from-amm': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'token-z', type: principalT },
{ name: 'factor-x', type: uintT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'oracle-resilient-helper-to-amm': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'token-z', type: principalT },
{ name: 'factor-y', type: uintT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'route-helper-from-amm': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'token-z', type: principalT },
{ name: 'factor-x', type: uintT }
],
output: responseSimpleT(listT(principalT, ), ),
mode: 'readonly'
},
'route-helper-to-amm': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'token-z', type: principalT },
{ name: 'factor-y', type: uintT }
],
output: responseSimpleT(listT(principalT, ), ),
mode: 'readonly'
}
}
} as const)

View File

@@ -1,142 +0,0 @@
import {
defineContract,
principalT,
uintT,
optionalT,
responseSimpleT,
listT
} from "../smartContractHelpers/codegenImport"
export const swapHelperBridged = defineContract({
"swap-helper-bridged": {
'swap-helper-from-amm': {
input: [
{ name: 'token-x-trait', type: principalT },
{ name: 'token-y-trait', type: principalT },
{ name: 'token-z-trait', type: principalT },
{ name: 'factor-x', type: uintT },
{ name: 'dx', type: uintT },
{ name: 'min-dz', type: optionalT(uintT, ) }
],
output: responseSimpleT(uintT, ),
mode: 'public'
},
'swap-helper-to-amm': {
input: [
{ name: 'token-x-trait', type: principalT },
{ name: 'token-y-trait', type: principalT },
{ name: 'token-z-trait', type: principalT },
{ name: 'factor-y', type: uintT },
{ name: 'dx', type: uintT },
{ name: 'min-dz', type: optionalT(uintT, ) }
],
output: responseSimpleT(uintT, ),
mode: 'public'
},
'fee-helper-from-amm': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'token-z', type: principalT },
{ name: 'factor-x', type: uintT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'fee-helper-to-amm': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'token-z', type: principalT },
{ name: 'factor-y', type: uintT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'get-helper-from-amm': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'token-z', type: principalT },
{ name: 'factor-x', type: uintT },
{ name: 'dx', type: uintT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'get-helper-to-amm': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'token-z', type: principalT },
{ name: 'factor-y', type: uintT },
{ name: 'dx', type: uintT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'oracle-instant-helper-from-amm': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'token-z', type: principalT },
{ name: 'factor-x', type: uintT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'oracle-instant-helper-to-amm': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'token-z', type: principalT },
{ name: 'factor-y', type: uintT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'oracle-resilient-helper-from-amm': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'token-z', type: principalT },
{ name: 'factor-x', type: uintT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'oracle-resilient-helper-to-amm': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'token-z', type: principalT },
{ name: 'factor-y', type: uintT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'route-helper-from-amm': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'token-z', type: principalT },
{ name: 'factor-x', type: uintT }
],
output: responseSimpleT(listT(principalT, ), ),
mode: 'readonly'
},
'route-helper-to-amm': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'token-z', type: principalT },
{ name: 'factor-y', type: uintT }
],
output: responseSimpleT(listT(principalT, ), ),
mode: 'readonly'
}
}
} as const)

View File

@@ -1,82 +0,0 @@
import {
defineContract,
principalT,
uintT,
optionalT,
responseSimpleT,
listT,
tupleT
} from "../smartContractHelpers/codegenImport"
export const swapHelperV102 = defineContract({
"swap-helper-v1-02": {
'swap-helper': {
input: [
{ name: 'token-x-trait', type: principalT },
{ name: 'token-y-trait', type: principalT },
{ name: 'dx', type: uintT },
{ name: 'min-dy', type: optionalT(uintT, ) }
],
output: responseSimpleT(uintT, ),
mode: 'public'
},
'fee-helper': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'get-given-helper': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'dy', type: uintT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'get-helper': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'dx', type: uintT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'oracle-instant-helper': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'oracle-resilient-helper': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'route-helper': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT }
],
output: responseSimpleT(listT(principalT, ), ),
mode: 'readonly'
},
'fwp-oracle-resilient-map': {
input: tupleT({ 'token-x': principalT, 'token-y': principalT }, ),
output: optionalT(uintT, ),
mode: 'mapEntry'
}
}
} as const)

View File

@@ -1,87 +0,0 @@
import {
defineContract,
principalT,
uintT,
optionalT,
responseSimpleT,
listT,
tupleT
} from "../smartContractHelpers/codegenImport"
export const swapHelperV103 = defineContract({
"swap-helper-v1-03": {
'swap-helper': {
input: [
{ name: 'token-x-trait', type: principalT },
{ name: 'token-y-trait', type: principalT },
{ name: 'dx', type: uintT },
{ name: 'min-dy', type: optionalT(uintT, ) }
],
output: responseSimpleT(uintT, ),
mode: 'public'
},
'fee-helper': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'get-given-helper': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'dy', type: uintT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'get-helper': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT },
{ name: 'dx', type: uintT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'oracle-instant-helper': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'oracle-resilient-helper': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'route-helper': {
input: [
{ name: 'token-x', type: principalT },
{ name: 'token-y', type: principalT }
],
output: responseSimpleT(listT(principalT, ), ),
mode: 'readonly'
},
'fwp-oracle-resilient-map': {
input: tupleT({ 'token-x': principalT, 'token-y': principalT }, ),
output: optionalT(uintT, ),
mode: 'mapEntry'
},
'simple-oracle-resilient-map': {
input: tupleT({ 'token-x': principalT, 'token-y': principalT }, ),
output: optionalT(uintT, ),
mode: 'mapEntry'
}
}
} as const)

View File

@@ -1,306 +0,0 @@
import {
defineContract,
principalT,
responseSimpleT,
booleanT,
uintT,
stringAsciiT,
optionalT,
stringT,
listT,
tupleT,
bufferT,
noneT
} from "../smartContractHelpers/codegenImport"
export const tokenAmmSwapPool = defineContract({
"token-amm-swap-pool": {
'add-approved-contract': {
input: [ { name: 'new-approved-contract', type: principalT } ],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
burn: {
input: [
{ name: 'token-id', type: uintT },
{ name: 'amount', type: uintT },
{ name: 'sender', type: principalT }
],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
'burn-fixed': {
input: [
{ name: 'token-id', type: uintT },
{ name: 'amount', type: uintT },
{ name: 'sender', type: principalT }
],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
mint: {
input: [
{ name: 'token-id', type: uintT },
{ name: 'amount', type: uintT },
{ name: 'recipient', type: principalT }
],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
'mint-fixed': {
input: [
{ name: 'token-id', type: uintT },
{ name: 'amount', type: uintT },
{ name: 'recipient', type: principalT }
],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
'set-approved-contract': {
input: [
{ name: 'owner', type: principalT },
{ name: 'approved', type: booleanT }
],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
'set-contract-owner': {
input: [ { name: 'owner', type: principalT } ],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
'set-decimals': {
input: [ { name: 'new-decimals', type: uintT } ],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
'set-name': {
input: [ { name: 'new-name', type: stringAsciiT } ],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
'set-symbol': {
input: [ { name: 'new-symbol', type: stringAsciiT } ],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
'set-token-uri': {
input: [ { name: 'new-uri', type: optionalT(stringT, ) } ],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
'set-transferrable': {
input: [ { name: 'new-transferrable', type: booleanT } ],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
transfer: {
input: [
{ name: 'token-id', type: uintT },
{ name: 'amount', type: uintT },
{ name: 'sender', type: principalT },
{ name: 'recipient', type: principalT }
],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
'transfer-fixed': {
input: [
{ name: 'token-id', type: uintT },
{ name: 'amount', type: uintT },
{ name: 'sender', type: principalT },
{ name: 'recipient', type: principalT }
],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
'transfer-many': {
input: [
{
name: 'transfers',
type: listT(tupleT({
amount: uintT,
recipient: principalT,
sender: principalT,
'token-id': uintT
}, ), )
}
],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
'transfer-many-fixed': {
input: [
{
name: 'transfers',
type: listT(tupleT({
amount: uintT,
recipient: principalT,
sender: principalT,
'token-id': uintT
}, ), )
}
],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
'transfer-many-memo': {
input: [
{
name: 'transfers',
type: listT(tupleT({
amount: uintT,
memo: bufferT,
recipient: principalT,
sender: principalT,
'token-id': uintT
}, ), )
}
],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
'transfer-many-memo-fixed': {
input: [
{
name: 'transfers',
type: listT(tupleT({
amount: uintT,
memo: bufferT,
recipient: principalT,
sender: principalT,
'token-id': uintT
}, ), )
}
],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
'transfer-memo': {
input: [
{ name: 'token-id', type: uintT },
{ name: 'amount', type: uintT },
{ name: 'sender', type: principalT },
{ name: 'recipient', type: principalT },
{ name: 'memo', type: bufferT }
],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
'transfer-memo-fixed': {
input: [
{ name: 'token-id', type: uintT },
{ name: 'amount', type: uintT },
{ name: 'sender', type: principalT },
{ name: 'recipient', type: principalT },
{ name: 'memo', type: bufferT }
],
output: responseSimpleT(booleanT, ),
mode: 'public'
},
'fixed-to-decimals': {
input: [ { name: 'amount', type: uintT } ],
output: uintT,
mode: 'readonly'
},
'get-balance': {
input: [
{ name: 'token-id', type: uintT },
{ name: 'who', type: principalT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'get-balance-fixed': {
input: [
{ name: 'token-id', type: uintT },
{ name: 'who', type: principalT }
],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'get-contract-owner': {
input: [],
output: responseSimpleT(principalT, ),
mode: 'readonly'
},
'get-decimals': {
input: [ { name: 'token-id', type: uintT } ],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'get-name': {
input: [ { name: 'token-id', type: uintT } ],
output: responseSimpleT(stringAsciiT, ),
mode: 'readonly'
},
'get-overall-balance': {
input: [ { name: 'who', type: principalT } ],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'get-overall-balance-fixed': {
input: [ { name: 'who', type: principalT } ],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'get-overall-supply': { input: [], output: responseSimpleT(uintT, ), mode: 'readonly' },
'get-overall-supply-fixed': { input: [], output: responseSimpleT(uintT, ), mode: 'readonly' },
'get-symbol': {
input: [ { name: 'token-id', type: uintT } ],
output: responseSimpleT(stringAsciiT, ),
mode: 'readonly'
},
'get-token-balance-owned-in-fixed': {
input: [ { name: 'owner', type: principalT } ],
output: listT(tupleT({ balance: uintT, 'token-id': uintT }, ), ),
mode: 'readonly'
},
'get-token-owned': {
input: [ { name: 'owner', type: principalT } ],
output: listT(uintT, ),
mode: 'readonly'
},
'get-token-uri': {
input: [ { name: 'token-id', type: uintT } ],
output: responseSimpleT(optionalT(stringT, ), ),
mode: 'readonly'
},
'get-total-supply': {
input: [ { name: 'token-id', type: uintT } ],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'get-total-supply-fixed': {
input: [ { name: 'token-id', type: uintT } ],
output: responseSimpleT(uintT, ),
mode: 'readonly'
},
'get-transferrable': { input: [], output: responseSimpleT(booleanT, ), mode: 'readonly' },
'approved-contracts': {
input: principalT,
output: optionalT(booleanT, ),
mode: 'mapEntry'
},
'token-balances': {
input: tupleT({ owner: principalT, 'token-id': uintT }, ),
output: optionalT(uintT, ),
mode: 'mapEntry'
},
'token-owned': {
input: principalT,
output: optionalT(listT(uintT, ), ),
mode: 'mapEntry'
},
'token-supplies': { input: uintT, output: optionalT(uintT, ), mode: 'mapEntry' },
'contract-owner': { input: noneT, output: principalT, mode: 'variable' },
'token-decimals': { input: noneT, output: uintT, mode: 'variable' },
'token-name': { input: noneT, output: stringAsciiT, mode: 'variable' },
'token-symbol': { input: noneT, output: stringAsciiT, mode: 'variable' },
'token-uri': { input: noneT, output: optionalT(stringT, ), mode: 'variable' },
transferrable: { input: noneT, output: booleanT, mode: 'variable' }
}
} as const)

View File

@@ -1,20 +1,8 @@
import { defineContract } from "../smartContractHelpers/codegenImport"; import { defineContract } from "../smartContractHelpers/codegenImport";
import { swapHelperV102 } from "./contract_swap-helper-v1-02" import { ammPoolV201 } from "./contract_Alex_amm-pool-v2-01"
import { swapHelperV103 } from "./contract_swap-helper-v1-03"
import { ammSwapPool } from "./contract_amm-swap-pool"
import { ammSwapPoolV11 } from "./contract_amm-swap-pool-v1-1"
import { tokenAmmSwapPool } from "./contract_token-amm-swap-pool"
import { swapHelperBridged } from "./contract_swap-helper-bridged"
import { swapHelperBridgedV11 } from "./contract_swap-helper-bridged-v1-1"
export const AlexContracts = defineContract({ export const AlexContracts = defineContract({
...swapHelperV102, ...ammPoolV201
...swapHelperV103,
...ammSwapPool,
...ammSwapPoolV11,
...tokenAmmSwapPool,
...swapHelperBridged,
...swapHelperBridgedV11
}); });

View File

@@ -1,36 +1 @@
import {
ClarityType,
contractPrincipalCV,
PrincipalCV,
standardPrincipalCV,
} from '@stacks/transactions';
import { addressResult, contractResult, transcoders } from 'clarity-codegen';
import type { Decoder } from 'clarity-codegen/lib/runtime/types';
import { configs } from '../../config';
export * from 'clarity-codegen'; export * from 'clarity-codegen';
export function principalCV(principal: string): PrincipalCV {
if (principal.includes('.')) {
const [address, contractName] = principal.split('.');
return contractPrincipalCV(address!, contractName!);
}
if (principal.startsWith('SP') || principal.startsWith('ST')) {
return standardPrincipalCV(principal);
}
return contractPrincipalCV(configs.CONTRACT_DEPLOYER, principal);
}
export const principleResult: Decoder<string> = (result) => {
if (result.type === ClarityType.PrincipalStandard) {
return addressResult(result);
} else if (result.type === ClarityType.PrincipalContract) {
return contractResult(result).split('.')[1];
}
throw new Error(`Expected principal, got ${result.type}`);
};
export const principalT = transcoders({
encode: principalCV,
decode: principleResult,
});

View File

@@ -1,145 +1,58 @@
import { AMMSwapPool } from '../utils/ammPool';
import { unwrapResponse } from 'clarity-codegen'; import { unwrapResponse } from 'clarity-codegen';
import { readonlyCall } from '../utils/readonlyCallExecutor'; import { readonlyCall } from '../utils/readonlyCallExecutor';
import { Currency } from '../currency'; import { Currency } from '../currency';
import { AlexSDK } from '../alexSDK'; import { AlexSDK } from '../alexSDK';
import { PoolData, TokenMapping } from '../types';
import { resolveAmmRoute } from '../utils/ammRouteResolver';
export async function getLiquidityProviderFee( export async function getLiquidityProviderFee(
tokenX: Currency, tokenX: Currency,
tokenY: Currency, tokenY: Currency,
ammPools: AMMSwapPool.PoolTokens[], pools: PoolData[]
ammV1_1Pools: AMMSwapPool.PoolTokens[]
): Promise<bigint> { ): Promise<bigint> {
const ammV1_1Route = AMMSwapPool.getRoute(tokenX, tokenY, ammV1_1Pools); const ammRoute = resolveAmmRoute(tokenX, tokenY, pools);
if (ammV1_1Route.length === 1) { if (ammRoute.length === 0) {
return await readonlyCall('amm-swap-pool-v1-1', 'fee-helper', { throw new Error('No AMM pools in route');
'token-x': tokenX,
'token-y': tokenY,
factor: AMMSwapPool.getFactor(ammV1_1Route[0]!.pool),
}).then(unwrapResponse);
} }
if (ammV1_1Route.length === 2) {
return await readonlyCall('amm-swap-pool-v1-1', 'fee-helper-a', {
'token-x': tokenX,
'token-y': ammV1_1Route[0]!.neighbour,
'token-z': ammV1_1Route[1]!.neighbour,
'factor-x': AMMSwapPool.getFactor(ammV1_1Route[0]!.pool),
'factor-y': AMMSwapPool.getFactor(ammV1_1Route[1]!.pool),
}).then(unwrapResponse);
}
if (ammV1_1Route.length === 3) {
return await readonlyCall('amm-swap-pool-v1-1', 'fee-helper-b', {
'token-x': tokenX,
'token-y': ammV1_1Route[0]!.neighbour,
'token-z': ammV1_1Route[1]!.neighbour,
'token-w': ammV1_1Route[2]!.neighbour,
'factor-x': AMMSwapPool.getFactor(ammV1_1Route[0]!.pool),
'factor-y': AMMSwapPool.getFactor(ammV1_1Route[1]!.pool),
'factor-z': AMMSwapPool.getFactor(ammV1_1Route[2]!.pool),
}).then(unwrapResponse);
}
if (ammV1_1Route.length === 4) {
return await readonlyCall('amm-swap-pool-v1-1', 'fee-helper-c', {
'token-x': tokenX,
'token-y': ammV1_1Route[0]!.neighbour,
'token-z': ammV1_1Route[1]!.neighbour,
'token-w': ammV1_1Route[2]!.neighbour,
'token-v': ammV1_1Route[3]!.neighbour,
'factor-x': AMMSwapPool.getFactor(ammV1_1Route[0]!.pool),
'factor-y': AMMSwapPool.getFactor(ammV1_1Route[1]!.pool),
'factor-z': AMMSwapPool.getFactor(ammV1_1Route[2]!.pool),
'factor-w': AMMSwapPool.getFactor(ammV1_1Route[3]!.pool),
}).then(unwrapResponse);
}
const ammRoute = AMMSwapPool.getRoute(tokenX, tokenY, ammPools);
if (ammRoute.length === 1) { if (ammRoute.length === 1) {
return await readonlyCall('amm-swap-pool', 'fee-helper', { return await readonlyCall('amm-pool-v2-01', 'fee-helper', {
'token-x': tokenX, 'token-x': tokenX,
'token-y': tokenY, 'token-y': tokenY,
factor: AMMSwapPool.getFactor(ammRoute[0]!.pool), factor: ammRoute[0]!.pool.factor,
}).then(unwrapResponse); }).then(unwrapResponse);
} }
if (ammRoute.length === 2) { if (ammRoute.length === 2) {
return await readonlyCall('amm-swap-pool', 'fee-helper-a', { return await readonlyCall('amm-pool-v2-01', 'fee-helper-a', {
'token-x': tokenX, 'token-x': tokenX,
'token-y': ammRoute[0]!.neighbour, 'token-y': ammRoute[0]!.neighbour,
'token-z': ammRoute[1]!.neighbour, 'token-z': ammRoute[1]!.neighbour,
'factor-x': AMMSwapPool.getFactor(ammRoute[0]!.pool), 'factor-x': ammRoute[0]!.pool.factor,
'factor-y': AMMSwapPool.getFactor(ammRoute[1]!.pool), 'factor-y': ammRoute[1]!.pool.factor,
}).then(unwrapResponse); }).then(unwrapResponse);
} }
if (ammRoute.length === 3) { if (ammRoute.length === 3) {
return await readonlyCall('amm-swap-pool', 'fee-helper-b', { return await readonlyCall('amm-pool-v2-01', 'fee-helper-b', {
'token-x': tokenX, 'token-x': tokenX,
'token-y': ammRoute[0]!.neighbour, 'token-y': ammRoute[0]!.neighbour,
'token-z': ammRoute[1]!.neighbour, 'token-z': ammRoute[1]!.neighbour,
'token-w': ammRoute[2]!.neighbour, 'token-w': ammRoute[2]!.neighbour,
'factor-x': AMMSwapPool.getFactor(ammRoute[0]!.pool), 'factor-x': ammRoute[0]!.pool.factor,
'factor-y': AMMSwapPool.getFactor(ammRoute[1]!.pool), 'factor-y': ammRoute[1]!.pool.factor,
'factor-z': AMMSwapPool.getFactor(ammRoute[2]!.pool), 'factor-z': ammRoute[2]!.pool.factor,
}).then(unwrapResponse); }).then(unwrapResponse);
} }
if (ammRoute.length === 4) { if (ammRoute.length === 4) {
return await readonlyCall('amm-swap-pool', 'fee-helper-c', { return await readonlyCall('amm-pool-v2-01', 'fee-helper-c', {
'token-x': tokenX, 'token-x': tokenX,
'token-y': ammRoute[0]!.neighbour, 'token-y': ammRoute[0]!.neighbour,
'token-z': ammRoute[1]!.neighbour, 'token-z': ammRoute[1]!.neighbour,
'token-w': ammRoute[2]!.neighbour, 'token-w': ammRoute[2]!.neighbour,
'token-v': ammRoute[3]!.neighbour, 'token-v': ammRoute[3]!.neighbour,
'factor-x': AMMSwapPool.getFactor(ammRoute[0]!.pool), 'factor-x': ammRoute[0]!.pool.factor,
'factor-y': AMMSwapPool.getFactor(ammRoute[1]!.pool), 'factor-y': ammRoute[1]!.pool.factor,
'factor-z': AMMSwapPool.getFactor(ammRoute[2]!.pool), 'factor-z': ammRoute[2]!.pool.factor,
'factor-w': AMMSwapPool.getFactor(ammRoute[3]!.pool), 'factor-w': ammRoute[3]!.pool.factor,
}).then(unwrapResponse); }).then(unwrapResponse);
} }
throw new Error('Too many AMM pools in route');
const reachableInAmm1_1 = AMMSwapPool.reachableInAMM(
tokenX,
tokenY,
ammV1_1Pools
);
if (reachableInAmm1_1.type === 'fromAmm') {
return await readonlyCall(
'swap-helper-bridged-v1-1',
'fee-helper-from-amm',
{
'token-x': reachableInAmm1_1.tokenX,
'token-y': reachableInAmm1_1.tokenY,
'token-z': reachableInAmm1_1.tokenZ,
'factor-x': reachableInAmm1_1.factorX,
}
).then(unwrapResponse);
}
if (reachableInAmm1_1.type === 'toAmm') {
return await readonlyCall('swap-helper-bridged-v1-1', 'fee-helper-to-amm', {
'token-x': reachableInAmm1_1.tokenX,
'token-y': reachableInAmm1_1.tokenY,
'token-z': reachableInAmm1_1.tokenZ,
'factor-y': reachableInAmm1_1.factorY,
}).then(unwrapResponse);
}
const reachableInAmm = AMMSwapPool.reachableInAMM(tokenX, tokenY, ammPools);
if (reachableInAmm.type === 'fromAmm') {
return await readonlyCall('swap-helper-bridged', 'fee-helper-from-amm', {
'token-x': reachableInAmm.tokenX,
'token-y': reachableInAmm.tokenY,
'token-z': reachableInAmm.tokenZ,
'factor-x': reachableInAmm.factorX,
}).then(unwrapResponse);
}
if (reachableInAmm.type === 'toAmm') {
return await readonlyCall('swap-helper-bridged', 'fee-helper-to-amm', {
'token-x': reachableInAmm.tokenX,
'token-y': reachableInAmm.tokenY,
'token-z': reachableInAmm.tokenZ,
'factor-y': reachableInAmm.factorY,
}).then(unwrapResponse);
}
return await readonlyCall('swap-helper-v1-03', 'fee-helper', {
'token-x': tokenX,
'token-y': tokenY,
}).then(unwrapResponse);
} }

View File

@@ -1,155 +1,62 @@
import { AMMSwapPool } from '../utils/ammPool';
import { unwrapResponse } from 'clarity-codegen'; import { unwrapResponse } from 'clarity-codegen';
import { readonlyCall } from '../utils/readonlyCallExecutor'; import { readonlyCall } from '../utils/readonlyCallExecutor';
import { Currency } from '../currency'; import { Currency } from '../currency';
import { AlexSDK } from '../alexSDK'; import { PoolData } from '../types';
import { resolveAmmRoute } from '../utils/ammRouteResolver';
export const getYAmountFromXAmount = async ( export const getYAmountFromXAmount = async (
tokenX: Currency, tokenX: Currency,
tokenY: Currency, tokenY: Currency,
fromAmount: bigint, fromAmount: bigint,
ammPools: AMMSwapPool.PoolTokens[], ammPools: PoolData[]
ammV1_1Tokens: AMMSwapPool.Pool[]
): Promise<bigint> => { ): Promise<bigint> => {
const ammV1_1Route = AMMSwapPool.getRoute(tokenX, tokenY, ammV1_1Tokens); const ammRoute = resolveAmmRoute(tokenX, tokenY, ammPools);
if (ammV1_1Route.length === 1) { if (ammRoute.length === 0) {
return await readonlyCall('amm-swap-pool-v1-1', 'get-helper', { throw new Error('No AMM pool found for the given route');
'token-x': tokenX,
'token-y': ammV1_1Route[0]!.neighbour,
dx: fromAmount,
factor: AMMSwapPool.getFactor(ammV1_1Route[0]!.pool),
}).then(unwrapResponse);
} }
if (ammV1_1Route.length === 2) {
return await readonlyCall('amm-swap-pool-v1-1', 'get-helper-a', {
'token-x': tokenX,
'token-y': ammV1_1Route[0]!.neighbour,
'token-z': ammV1_1Route[1]!.neighbour,
'factor-x': AMMSwapPool.getFactor(ammV1_1Route[0]!.pool),
'factor-y': AMMSwapPool.getFactor(ammV1_1Route[1]!.pool),
dx: fromAmount,
}).then(unwrapResponse);
}
if (ammV1_1Route.length === 3) {
return await readonlyCall('amm-swap-pool-v1-1', 'get-helper-b', {
'token-x': tokenX,
'token-y': ammV1_1Route[0]!.neighbour,
'token-z': ammV1_1Route[1]!.neighbour,
'token-w': ammV1_1Route[2]!.neighbour,
'factor-x': AMMSwapPool.getFactor(ammV1_1Route[0]!.pool),
'factor-y': AMMSwapPool.getFactor(ammV1_1Route[1]!.pool),
'factor-z': AMMSwapPool.getFactor(ammV1_1Route[2]!.pool),
dx: fromAmount,
}).then(unwrapResponse);
}
if (ammV1_1Route.length === 4) {
return await readonlyCall('amm-swap-pool-v1-1', 'get-helper-c', {
'token-x': tokenX,
'token-y': ammV1_1Route[0]!.neighbour,
'token-z': ammV1_1Route[1]!.neighbour,
'token-w': ammV1_1Route[2]!.neighbour,
'token-v': ammV1_1Route[3]!.neighbour,
'factor-x': AMMSwapPool.getFactor(ammV1_1Route[0]!.pool),
'factor-y': AMMSwapPool.getFactor(ammV1_1Route[1]!.pool),
'factor-z': AMMSwapPool.getFactor(ammV1_1Route[2]!.pool),
'factor-w': AMMSwapPool.getFactor(ammV1_1Route[3]!.pool),
dx: fromAmount,
}).then(unwrapResponse);
}
const ammRoute = AMMSwapPool.getRoute(tokenX, tokenY, ammPools);
if (ammRoute.length === 1) { if (ammRoute.length === 1) {
return await readonlyCall('amm-swap-pool', 'get-helper', { return await readonlyCall('amm-pool-v2-01', 'get-helper', {
'token-x': tokenX, 'token-x': tokenX,
'token-y': ammRoute[0]!.neighbour, 'token-y': ammRoute[0]!.neighbour,
dx: fromAmount, dx: fromAmount,
factor: AMMSwapPool.getFactor(ammRoute[0]!.pool), factor: ammRoute[0]!.pool.factor,
}).then(unwrapResponse); }).then(unwrapResponse);
} }
if (ammRoute.length === 2) { if (ammRoute.length === 2) {
return await readonlyCall('amm-swap-pool', 'get-helper-a', { return await readonlyCall('amm-pool-v2-01', 'get-helper-a', {
'token-x': tokenX, 'token-x': tokenX,
'token-y': ammRoute[0]!.neighbour, 'token-y': ammRoute[0]!.neighbour,
'token-z': ammRoute[1]!.neighbour, 'token-z': ammRoute[1]!.neighbour,
'factor-x': AMMSwapPool.getFactor(ammRoute[0]!.pool), 'factor-x': ammRoute[0]!.pool.factor,
'factor-y': AMMSwapPool.getFactor(ammRoute[1]!.pool), 'factor-y': ammRoute[1]!.pool.factor,
dx: fromAmount, dx: fromAmount,
}).then(unwrapResponse); }).then(unwrapResponse);
} }
if (ammRoute.length === 3) { if (ammRoute.length === 3) {
return await readonlyCall('amm-swap-pool', 'get-helper-b', { return await readonlyCall('amm-pool-v2-01', 'get-helper-b', {
'token-x': tokenX, 'token-x': tokenX,
'token-y': ammRoute[0]!.neighbour, 'token-y': ammRoute[0]!.neighbour,
'token-z': ammRoute[1]!.neighbour, 'token-z': ammRoute[1]!.neighbour,
'token-w': ammRoute[2]!.neighbour, 'token-w': ammRoute[2]!.neighbour,
'factor-x': AMMSwapPool.getFactor(ammRoute[0]!.pool), 'factor-x': ammRoute[0]!.pool.factor,
'factor-y': AMMSwapPool.getFactor(ammRoute[1]!.pool), 'factor-y': ammRoute[1]!.pool.factor,
'factor-z': AMMSwapPool.getFactor(ammRoute[2]!.pool), 'factor-z': ammRoute[2]!.pool.factor,
dx: fromAmount, dx: fromAmount,
}).then(unwrapResponse); }).then(unwrapResponse);
} }
if (ammRoute.length === 4) { if (ammRoute.length === 4) {
return await readonlyCall('amm-swap-pool', 'get-helper-c', { return await readonlyCall('amm-pool-v2-01', 'get-helper-c', {
'token-x': tokenX, 'token-x': tokenX,
'token-y': ammRoute[0]!.neighbour, 'token-y': ammRoute[0]!.neighbour,
'token-z': ammRoute[1]!.neighbour, 'token-z': ammRoute[1]!.neighbour,
'token-w': ammRoute[2]!.neighbour, 'token-w': ammRoute[2]!.neighbour,
'token-v': ammRoute[3]!.neighbour, 'token-v': ammRoute[3]!.neighbour,
'factor-x': AMMSwapPool.getFactor(ammRoute[0]!.pool), 'factor-x': ammRoute[0]!.pool.factor,
'factor-y': AMMSwapPool.getFactor(ammRoute[1]!.pool), 'factor-y': ammRoute[1]!.pool.factor,
'factor-z': AMMSwapPool.getFactor(ammRoute[2]!.pool), 'factor-z': ammRoute[2]!.pool.factor,
'factor-w': AMMSwapPool.getFactor(ammRoute[3]!.pool), 'factor-w': ammRoute[3]!.pool.factor,
dx: fromAmount, dx: fromAmount,
}).then(unwrapResponse); }).then(unwrapResponse);
} }
const reachableInAMMV1_1 = AMMSwapPool.reachableInAMM( throw new Error('Too many AMM pools in route');
tokenX,
tokenY,
ammV1_1Tokens
);
if (reachableInAMMV1_1.type === 'fromAmm') {
return await readonlyCall(
'swap-helper-bridged-v1-1',
'get-helper-from-amm',
{
dx: fromAmount,
'token-x': reachableInAMMV1_1.tokenX,
'token-y': reachableInAMMV1_1.tokenY,
'token-z': reachableInAMMV1_1.tokenZ,
'factor-x': reachableInAMMV1_1.factorX,
}
).then(unwrapResponse);
}
if (reachableInAMMV1_1.type === 'toAmm') {
return await readonlyCall('swap-helper-bridged-v1-1', 'get-helper-to-amm', {
dx: fromAmount,
'token-x': reachableInAMMV1_1.tokenX,
'token-y': reachableInAMMV1_1.tokenY,
'token-z': reachableInAMMV1_1.tokenZ,
'factor-y': reachableInAMMV1_1.factorY,
}).then(unwrapResponse);
}
const reachableInAMM = AMMSwapPool.reachableInAMM(tokenX, tokenY, ammPools);
if (reachableInAMM.type === 'fromAmm') {
return await readonlyCall('swap-helper-bridged', 'get-helper-from-amm', {
dx: fromAmount,
'token-x': reachableInAMM.tokenX,
'token-y': reachableInAMM.tokenY,
'token-z': reachableInAMM.tokenZ,
'factor-x': reachableInAMM.factorX,
}).then(unwrapResponse);
}
if (reachableInAMM.type === 'toAmm') {
return await readonlyCall('swap-helper-bridged', 'get-helper-to-amm', {
dx: fromAmount,
'token-x': reachableInAMM.tokenX,
'token-y': reachableInAMM.tokenY,
'token-z': reachableInAMM.tokenZ,
'factor-y': reachableInAMM.factorY,
}).then(unwrapResponse);
}
return await readonlyCall('swap-helper-v1-03', 'get-helper', {
'token-x': tokenX,
'token-y': tokenY,
dx: fromAmount,
}).then(unwrapResponse);
}; };

View File

@@ -1,83 +1,15 @@
import { AMMSwapPool } from '../utils/ammPool';
import { unwrapResponse } from 'clarity-codegen';
import { readonlyCall } from '../utils/readonlyCallExecutor';
import { Currency } from '../currency'; import { Currency } from '../currency';
import { PoolData } from '../types';
import { resolveAmmRoute } from '../utils/ammRouteResolver';
export async function getRoute( export async function getRoute(
from: Currency, from: Currency,
to: Currency, to: Currency,
ammPools: AMMSwapPool.PoolTokens[], pools: PoolData[]
ammV1_1Tokens: AMMSwapPool.Pool[]
): Promise<Currency[]> { ): Promise<Currency[]> {
const ammV1_1Route = AMMSwapPool.getRoute(from, to, ammV1_1Tokens); const ammRoute = resolveAmmRoute(from, to, pools);
if (ammV1_1Route.length > 0) {
return [from, ...ammV1_1Route.map((a) => a.neighbour)];
}
const ammRoute = AMMSwapPool.getRoute(from, to, ammPools);
if (ammRoute.length > 0) { if (ammRoute.length > 0) {
return [from, ...ammRoute.map((a) => a.neighbour)]; return [from, ...ammRoute.map((a) => a.neighbour)];
} }
const reachableInAmmV1_1 = AMMSwapPool.reachableInAMM( throw new Error("Can't find route");
from,
to,
ammV1_1Tokens
);
if (reachableInAmmV1_1.type === 'fromAmm') {
const result = await readonlyCall(
'swap-helper-bridged-v1-1',
'route-helper-from-amm',
{
'token-x': reachableInAmmV1_1.tokenX,
'token-y': reachableInAmmV1_1.tokenY,
'token-z': reachableInAmmV1_1.tokenZ,
'factor-x': reachableInAmmV1_1.factorX,
}
).then(unwrapResponse);
return result.map((x) => x as Currency);
}
if (reachableInAmmV1_1.type === 'toAmm') {
const result = await readonlyCall(
'swap-helper-bridged-v1-1',
'route-helper-to-amm',
{
'token-x': reachableInAmmV1_1.tokenX,
'token-y': reachableInAmmV1_1.tokenY,
'token-z': reachableInAmmV1_1.tokenZ,
'factor-y': reachableInAmmV1_1.factorY,
}
).then(unwrapResponse);
return result.map((x) => x as Currency);
}
const reachableInAmm = AMMSwapPool.reachableInAMM(from, to, ammPools);
if (reachableInAmm.type === 'fromAmm') {
const result = await readonlyCall(
'swap-helper-bridged',
'route-helper-from-amm',
{
'token-x': reachableInAmm.tokenX,
'token-y': reachableInAmm.tokenY,
'token-z': reachableInAmm.tokenZ,
'factor-x': reachableInAmm.factorX,
}
).then(unwrapResponse);
return result.map((x) => x as Currency);
}
if (reachableInAmm.type === 'toAmm') {
const result = await readonlyCall(
'swap-helper-bridged',
'route-helper-to-amm',
{
'token-x': reachableInAmm.tokenX,
'token-y': reachableInAmm.tokenY,
'token-z': reachableInAmm.tokenZ,
'factor-y': reachableInAmm.factorY,
}
).then(unwrapResponse);
return result.map((x) => x as Currency);
}
const result = await readonlyCall('swap-helper-v1-03', 'route-helper', {
'token-x': from,
'token-y': to,
}).then(unwrapResponse);
return result.map((x) => x as Currency);
} }

View File

@@ -1,5 +1,3 @@
import { AMMSwapPool } from '../utils/ammPool';
import { transfer } from '../utils/postConditions';
import { import {
ClarityValue, ClarityValue,
FungibleConditionCode, FungibleConditionCode,
@@ -13,6 +11,9 @@ import {
import { AlexContracts } from '../generated/smartContract/contracts_Alex'; import { AlexContracts } from '../generated/smartContract/contracts_Alex';
import { configs } from '../config'; import { configs } from '../config';
import { Currency } from '../currency'; import { Currency } from '../currency';
import { PoolData, TokenMapping } from '../types';
import { resolveAmmRoute } from '../utils/ammRouteResolver';
import { transferFactory } from '../utils/postConditions';
export type TxToBroadCast = { export type TxToBroadCast = {
contractAddress: string; contractAddress: string;
@@ -57,197 +58,23 @@ export function runSpot(
currencyY: Currency, currencyY: Currency,
fromAmount: bigint, fromAmount: bigint,
minDy: bigint, minDy: bigint,
router: Currency[], ammPools: PoolData[],
ammPools: AMMSwapPool.PoolTokens[], mappings: TokenMapping[]
ammV1_1Pools: AMMSwapPool.PoolTokens[]
): TxToBroadCast { ): TxToBroadCast {
const middleSteps = router.slice(1, -1); const AlexVault = `${configs.CONTRACT_DEPLOYER}.amm-vault-v2-01`;
const AlexVault = `${configs.CONTRACT_DEPLOYER}.alex-vault`; const ammRoute = resolveAmmRoute(currencyX, currencyY, ammPools);
const AlexVaultV1_1 = `${configs.CONTRACT_DEPLOYER}.alex-vault-v1-1`; if (ammRoute.length === 0) {
const ammV1_1Route = AMMSwapPool.getRoute(currencyX, currencyY, ammV1_1Pools); throw new Error("Can't find AMM route");
if (ammV1_1Route.length === 1) {
return composeTx(
'amm-swap-pool-v1-1',
'swap-helper',
{
'token-x-trait': currencyX,
'token-y-trait': ammV1_1Route[0]!.neighbour,
factor: AMMSwapPool.getFactor(ammV1_1Route[0]!.pool),
dx: fromAmount,
'min-dy': minDy,
},
[
transfer(stxAddress, currencyX, fromAmount),
transfer(
AlexVaultV1_1,
currencyY,
minDy,
FungibleConditionCode.GreaterEqual
),
]
);
} }
if (ammV1_1Route.length === 2) { const transfer = transferFactory(mappings);
return composeTx(
'amm-swap-pool-v1-1',
'swap-helper-a',
{
'token-x-trait': currencyX,
'token-y-trait': ammV1_1Route[0]!.neighbour,
'token-z-trait': ammV1_1Route[1]!.neighbour,
'factor-x': AMMSwapPool.getFactor(ammV1_1Route[0]!.pool),
'factor-y': AMMSwapPool.getFactor(ammV1_1Route[1]!.pool),
dx: fromAmount,
'min-dz': minDy,
},
[
transfer(stxAddress, currencyX, fromAmount),
transfer(
AlexVaultV1_1,
ammV1_1Route[0]!.neighbour,
BigInt(0),
FungibleConditionCode.GreaterEqual
),
transfer(
stxAddress,
ammV1_1Route[0]!.neighbour,
BigInt(0),
FungibleConditionCode.GreaterEqual
),
transfer(
AlexVaultV1_1,
currencyY,
minDy,
FungibleConditionCode.GreaterEqual
),
]
);
}
if (ammV1_1Route.length === 3) {
return composeTx(
'amm-swap-pool-v1-1',
'swap-helper-b',
{
'token-x-trait': currencyX,
'token-y-trait': ammV1_1Route[0]!.neighbour,
'token-z-trait': ammV1_1Route[1]!.neighbour,
'token-w-trait': ammV1_1Route[2]!.neighbour,
'factor-x': AMMSwapPool.getFactor(ammV1_1Route[0]!.pool),
'factor-y': AMMSwapPool.getFactor(ammV1_1Route[1]!.pool),
'factor-z': AMMSwapPool.getFactor(ammV1_1Route[2]!.pool),
dx: fromAmount,
'min-dw': minDy,
},
[
transfer(stxAddress, currencyX, fromAmount),
transfer(
AlexVaultV1_1,
ammV1_1Route[0]!.neighbour,
BigInt(0),
FungibleConditionCode.GreaterEqual
),
transfer(
stxAddress,
ammV1_1Route[0]!.neighbour,
BigInt(0),
FungibleConditionCode.GreaterEqual
),
transfer(
AlexVaultV1_1,
ammV1_1Route[1]!.neighbour,
BigInt(0),
FungibleConditionCode.GreaterEqual
),
transfer(
stxAddress,
ammV1_1Route[1]!.neighbour,
BigInt(0),
FungibleConditionCode.GreaterEqual
),
transfer(
AlexVaultV1_1,
currencyY,
minDy,
FungibleConditionCode.GreaterEqual
),
]
);
}
if (ammV1_1Route.length === 4) {
return composeTx(
'amm-swap-pool-v1-1',
'swap-helper-c',
{
'token-x-trait': currencyX,
'token-y-trait': ammV1_1Route[0]!.neighbour,
'token-z-trait': ammV1_1Route[1]!.neighbour,
'token-w-trait': ammV1_1Route[2]!.neighbour,
'token-v-trait': ammV1_1Route[3]!.neighbour,
'factor-x': AMMSwapPool.getFactor(ammV1_1Route[0]!.pool),
'factor-y': AMMSwapPool.getFactor(ammV1_1Route[1]!.pool),
'factor-z': AMMSwapPool.getFactor(ammV1_1Route[2]!.pool),
'factor-w': AMMSwapPool.getFactor(ammV1_1Route[3]!.pool),
dx: fromAmount,
'min-dv': minDy,
},
[
transfer(stxAddress, currencyX, fromAmount),
transfer(
AlexVaultV1_1,
ammV1_1Route[0]!.neighbour,
BigInt(0),
FungibleConditionCode.GreaterEqual
),
transfer(
stxAddress,
ammV1_1Route[0]!.neighbour,
BigInt(0),
FungibleConditionCode.GreaterEqual
),
transfer(
AlexVaultV1_1,
ammV1_1Route[1]!.neighbour,
BigInt(0),
FungibleConditionCode.GreaterEqual
),
transfer(
stxAddress,
ammV1_1Route[1]!.neighbour,
BigInt(0),
FungibleConditionCode.GreaterEqual
),
transfer(
AlexVaultV1_1,
ammV1_1Route[2]!.neighbour,
BigInt(0),
FungibleConditionCode.GreaterEqual
),
transfer(
stxAddress,
ammV1_1Route[2]!.neighbour,
BigInt(0),
FungibleConditionCode.GreaterEqual
),
transfer(
AlexVaultV1_1,
currencyY,
minDy,
FungibleConditionCode.GreaterEqual
),
]
);
}
const ammRoute = AMMSwapPool.getRoute(currencyX, currencyY, ammPools);
if (ammRoute.length === 1) { if (ammRoute.length === 1) {
return composeTx( return composeTx(
'amm-swap-pool', 'amm-pool-v2-01',
'swap-helper', 'swap-helper',
{ {
'token-x-trait': currencyX, 'token-x-trait': currencyX,
'token-y-trait': ammRoute[0]!.neighbour, 'token-y-trait': ammRoute[0]!.neighbour,
factor: AMMSwapPool.getFactor(ammRoute[0]!.pool), factor: ammRoute[0]!.pool.factor,
dx: fromAmount, dx: fromAmount,
'min-dy': minDy, 'min-dy': minDy,
}, },
@@ -264,14 +91,14 @@ export function runSpot(
} }
if (ammRoute.length === 2) { if (ammRoute.length === 2) {
return composeTx( return composeTx(
'amm-swap-pool', 'amm-pool-v2-01',
'swap-helper-a', 'swap-helper-a',
{ {
'token-x-trait': currencyX, 'token-x-trait': currencyX,
'token-y-trait': ammRoute[0]!.neighbour, 'token-y-trait': ammRoute[0]!.neighbour,
'token-z-trait': ammRoute[1]!.neighbour, 'token-z-trait': ammRoute[1]!.neighbour,
'factor-x': AMMSwapPool.getFactor(ammRoute[0]!.pool), 'factor-x': ammRoute[0]!.pool.factor,
'factor-y': AMMSwapPool.getFactor(ammRoute[1]!.pool), 'factor-y': ammRoute[1]!.pool.factor,
dx: fromAmount, dx: fromAmount,
'min-dz': minDy, 'min-dz': minDy,
}, },
@@ -300,16 +127,16 @@ export function runSpot(
} }
if (ammRoute.length === 3) { if (ammRoute.length === 3) {
return composeTx( return composeTx(
'amm-swap-pool', 'amm-pool-v2-01',
'swap-helper-b', 'swap-helper-b',
{ {
'token-x-trait': currencyX, 'token-x-trait': currencyX,
'token-y-trait': ammRoute[0]!.neighbour, 'token-y-trait': ammRoute[0]!.neighbour,
'token-z-trait': ammRoute[1]!.neighbour, 'token-z-trait': ammRoute[1]!.neighbour,
'token-w-trait': ammRoute[2]!.neighbour, 'token-w-trait': ammRoute[2]!.neighbour,
'factor-x': AMMSwapPool.getFactor(ammRoute[0]!.pool), 'factor-x': ammRoute[0]!.pool.factor,
'factor-y': AMMSwapPool.getFactor(ammRoute[1]!.pool), 'factor-y': ammRoute[1]!.pool.factor,
'factor-z': AMMSwapPool.getFactor(ammRoute[2]!.pool), 'factor-z': ammRoute[2]!.pool.factor,
dx: fromAmount, dx: fromAmount,
'min-dw': minDy, 'min-dw': minDy,
}, },
@@ -350,7 +177,7 @@ export function runSpot(
} }
if (ammRoute.length === 4) { if (ammRoute.length === 4) {
return composeTx( return composeTx(
'amm-swap-pool', 'amm-pool-v2-01',
'swap-helper-c', 'swap-helper-c',
{ {
'token-x-trait': currencyX, 'token-x-trait': currencyX,
@@ -358,10 +185,10 @@ export function runSpot(
'token-z-trait': ammRoute[1]!.neighbour, 'token-z-trait': ammRoute[1]!.neighbour,
'token-w-trait': ammRoute[2]!.neighbour, 'token-w-trait': ammRoute[2]!.neighbour,
'token-v-trait': ammRoute[3]!.neighbour, 'token-v-trait': ammRoute[3]!.neighbour,
'factor-x': AMMSwapPool.getFactor(ammRoute[0]!.pool), 'factor-x': ammRoute[0]!.pool.factor,
'factor-y': AMMSwapPool.getFactor(ammRoute[1]!.pool), 'factor-y': ammRoute[1]!.pool.factor,
'factor-z': AMMSwapPool.getFactor(ammRoute[2]!.pool), 'factor-z': ammRoute[2]!.pool.factor,
'factor-w': AMMSwapPool.getFactor(ammRoute[3]!.pool), 'factor-w': ammRoute[3]!.pool.factor,
dx: fromAmount, dx: fromAmount,
'min-dv': minDy, 'min-dv': minDy,
}, },
@@ -412,192 +239,5 @@ export function runSpot(
] ]
); );
} }
throw new Error('Too many AMM pools in route');
const reachableInAMMV1_1 = AMMSwapPool.reachableInAMM(
currencyX,
currencyY,
ammPools
);
if (reachableInAMMV1_1.type === 'fromAmm') {
return composeTx(
'swap-helper-bridged-v1-1',
'swap-helper-from-amm',
{
'token-x-trait': reachableInAMMV1_1.tokenX,
'token-y-trait': reachableInAMMV1_1.tokenY,
'token-z-trait': reachableInAMMV1_1.tokenZ,
dx: fromAmount,
'min-dz': minDy,
'factor-x': reachableInAMMV1_1.factorX,
},
[
transfer(stxAddress, currencyX, fromAmount),
...middleSteps.flatMap((middle, index) => [
transfer(
index === 0 ? AlexVaultV1_1 : AlexVault,
middle,
BigInt(0),
FungibleConditionCode.GreaterEqual
),
transfer(
stxAddress,
middle,
BigInt(0),
FungibleConditionCode.GreaterEqual
),
]),
transfer(
AlexVault,
currencyY,
minDy,
FungibleConditionCode.GreaterEqual
),
]
);
}
if (reachableInAMMV1_1.type === 'toAmm') {
return composeTx(
'swap-helper-bridged-v1-1',
'swap-helper-to-amm',
{
'token-x-trait': reachableInAMMV1_1.tokenX,
'token-y-trait': reachableInAMMV1_1.tokenY,
'token-z-trait': reachableInAMMV1_1.tokenZ,
dx: fromAmount,
'min-dz': minDy,
'factor-y': reachableInAMMV1_1.factorY,
},
[
transfer(stxAddress, currencyX, fromAmount),
...middleSteps.flatMap((middle) => [
transfer(
AlexVault,
middle,
BigInt(0),
FungibleConditionCode.GreaterEqual
),
transfer(
stxAddress,
middle,
BigInt(0),
FungibleConditionCode.GreaterEqual
),
]),
transfer(
AlexVaultV1_1,
currencyY,
minDy,
FungibleConditionCode.GreaterEqual
),
]
);
}
const reachableInAMM = AMMSwapPool.reachableInAMM(
currencyX,
currencyY,
ammPools
);
if (reachableInAMM.type === 'fromAmm') {
return composeTx(
'swap-helper-bridged',
'swap-helper-from-amm',
{
'token-x-trait': reachableInAMM.tokenX,
'token-y-trait': reachableInAMM.tokenY,
'token-z-trait': reachableInAMM.tokenZ,
dx: fromAmount,
'min-dz': minDy,
'factor-x': reachableInAMM.factorX,
},
[
transfer(stxAddress, currencyX, fromAmount),
...middleSteps.flatMap((middle, index) => [
transfer(
index === 0 ? AlexVaultV1_1 : AlexVault,
middle,
BigInt(0),
FungibleConditionCode.GreaterEqual
),
transfer(
stxAddress,
middle,
BigInt(0),
FungibleConditionCode.GreaterEqual
),
]),
transfer(
AlexVault,
currencyY,
minDy,
FungibleConditionCode.GreaterEqual
),
]
);
}
if (reachableInAMM.type === 'toAmm') {
return composeTx(
'swap-helper-bridged',
'swap-helper-to-amm',
{
'token-x-trait': reachableInAMM.tokenX,
'token-y-trait': reachableInAMM.tokenY,
'token-z-trait': reachableInAMM.tokenZ,
dx: fromAmount,
'min-dz': minDy,
'factor-y': reachableInAMM.factorY,
},
[
transfer(stxAddress, currencyX, fromAmount),
...middleSteps.flatMap((middle) => [
transfer(
AlexVault,
middle,
BigInt(0),
FungibleConditionCode.GreaterEqual
),
transfer(
stxAddress,
middle,
BigInt(0),
FungibleConditionCode.GreaterEqual
),
]),
transfer(
AlexVaultV1_1,
currencyY,
minDy,
FungibleConditionCode.GreaterEqual
),
]
);
}
return composeTx(
'swap-helper-v1-03',
'swap-helper',
{
'token-x-trait': currencyX,
'token-y-trait': currencyY,
dx: fromAmount,
'min-dy': minDy,
},
[
transfer(stxAddress, currencyX, fromAmount),
...middleSteps.flatMap((middle) => [
transfer(
AlexVault,
middle,
BigInt(0),
FungibleConditionCode.GreaterEqual
),
transfer(
stxAddress,
middle,
BigInt(0),
FungibleConditionCode.GreaterEqual
),
]),
transfer(AlexVault, currencyY, minDy, FungibleConditionCode.GreaterEqual),
]
);
} }

View File

@@ -1,3 +1,2 @@
export * from './currency'; export {Currency, STXCurrency} from './currency';
export * from './alexSDK'; export * from './alexSDK';
export { TokenInfo } from './utils/tokenlist';

21
src/types.ts Normal file
View File

@@ -0,0 +1,21 @@
import { Currency } from './currency';
export type TokenMapping = {
token: Currency;
token_decimals: 8;
token_asset: string;
wrapped_token: string;
wrapped_token_decimals: number;
wrapped_token_asset: string;
};
export type PoolData = {
token_x: Currency;
token_y: Currency;
factor: bigint;
};
export type PriceData = {
token: Currency;
price: number
}

View File

@@ -1,301 +0,0 @@
import { AMMSwapRoute, resolveAmmRoute } from './ammRouteResolver';
import { bridgeHelperResolver } from './bridgeHelperResolver';
import { assertNever } from './utils';
import { Currency } from '../currency';
export namespace AMMSwapPool {
export enum Pool {
// AMM_SWAP_POOL
AMM_SWAP_POOL_WXUSD_WUSDA = 'token-amm-swap-pool:token-wxusd,token-wusda,0.0001e8',
AMM_SWAP_POOL_WXUSD_WUSDA_2 = 'token-amm-swap-pool:token-wxusd,token-wusda,0.005e8',
// not yet available
// AMM_SWAP_POOL_WSTX_ALEX = 'token-amm-swap-pool:token-wstx,age000-governance-token,1e8',
// AMM_SWAP_POOL_WSTX_XBTC = 'token-amm-swap-pool:token-wstx,token-wbtc,1e8',
// AMM_SWAP_POOL_ALEX_WBAN = 'token-amm-swap-pool:age000-governance-token,token-wban,1e8',
// AMM_SWAP_POOL_ALEX_WUSDA = 'token-amm-swap-pool:age000-governance-token,token-wusda,1e8',
AMM_SWAP_POOL_ALEX_WDIKO = 'token-amm-swap-pool:age000-governance-token,token-wdiko,1e8',
AMM_SWAP_POOL_WSTX_WCORGI = 'token-amm-swap-pool:token-wstx,token-wcorgi,1e8',
AMM_SWAP_POOL_WSTX_SUSDT = 'token-amm-swap-pool:token-wstx,token-susdt,1e8',
AMM_SWAP_POOL_V1_1_WSTX_XBTC = 'token-amm-swap-pool-v1-1:token-wstx,token-wbtc,1e8',
AMM_SWAP_POOL_V1_1_WSTX_SUSDT = 'token-amm-swap-pool-v1-1:token-wstx,token-susdt,1e8',
AMM_SWAP_POOL_V1_1_WSTX_ALEX = 'token-amm-swap-pool-v1-1:token-wstx,age000-governance-token,1e8',
AMM_SWAP_POOL_V1_1_ALEX_DIKO = 'token-amm-swap-pool-v1-1:age000-governance-token,token-wdiko,1e8',
AMM_SWAP_POOL_V1_1_ALEX_ATALEXV2 = 'token-amm-swap-pool-v1-1:age000-governance-token,auto-alex-v2,1e8',
AMM_SWAP_POOL_V1_1_WSTX_WVIBES = 'token-amm-swap-pool-v1-1:token-wstx,token-wvibes,1e8',
AMM_SWAP_POOL_V1_1_ALEX_BRC20DB20 = 'token-amm-swap-pool-v1-1:age000-governance-token,brc20-db20,1e8',
AMM_SWAP_POOL_V1_1_SUSDT_XUSD = 'token-amm-swap-pool-v1-1:token-susdt,token-wxusd,0.05e8',
AMM_SWAP_POOL_V1_1_WSTX_LUNAR = 'token-amm-swap-pool-v1-1:token-wstx,token-slunr,1e8',
AMM_SWAP_POOL_V1_1_SUSDT_CHAX = 'token-amm-swap-pool-v1-1:token-susdt,brc20-chax,1e8',
AMM_SWAP_POOL_V1_1_WSTX_ABTC = 'token-amm-swap-pool-v1-1:token-wstx,token-abtc,1e8',
AMM_SWAP_POOL_V1_1_WSTX_WLEO = 'token-amm-swap-pool-v1-1:token-wstx,token-wleo,1e8',
AMM_SWAP_POOL_V1_1_WSTX_WMEGA = 'token-amm-swap-pool-v1-1:token-wstx,token-wmega-v2,1e8',
AMM_SWAP_POOL_V1_1_ABTC_BRC20ORDG = 'token-amm-swap-pool-v1-1:token-abtc,brc20-ordg,1e8',
AMM_SWAP_POOL_V1_1_ABTC_BRC20ORMM = 'token-amm-swap-pool-v1-1:token-abtc,brc20-ormm,1e8',
AMM_SWAP_POOL_V1_1_WSTX_WGUS = 'token-amm-swap-pool-v1-1:token-wstx,token-wgues,1e8',
AMM_SWAP_POOL_V1_1_ABTC_BRC20ORNJ = 'token-amm-swap-pool-v1-1:token-abtc,brc20-ornj,1e8',
AMM_SWAP_POOL_V1_1_WSTX_WLONG = 'token-amm-swap-pool-v1-1:token-wstx,token-wlong,1e8',
AMM_SWAP_POOL_V1_1_WSTX_WWNOTHING = 'token-amm-swap-pool-v1-1:token-wstx,token-wnthng,1e8',
AMM_SWAP_POOL_V1_1_WSTX_WAEWBTC = 'token-amm-swap-pool-v1-1:token-wstx,token-waewbtc,1e8',
AMM_SWAP_POOL_V1_1_WSTX_WLQSTX = 'token-amm-swap-pool-v1-1:token-wstx,token-wlqstx,0.05e8',
AMM_SWAP_POOL_V1_1_WSTX_WMAX = 'token-amm-swap-pool-v1-1:token-wstx,token-wmax,1e8',
AMM_SWAP_POOL_V1_1_WSTX_WPLAY = 'token-amm-swap-pool-v1-1:token-wstx,token-wplay,1e8',
AMM_SWAP_POOL_V1_1_WSTX_WAEUSDC = 'token-amm-swap-pool-v1-1:token-wstx,token-waeusdc,1e8',
AMM_SWAP_POOL_V1_1_WSTX_WPEPE = 'token-amm-swap-pool-v1-1:token-wstx,token-wpepe,1e8',
AMM_SWAP_POOL_V1_1_WSTX_WMICK = 'token-amm-swap-pool-v1-1:token-wstx,token-wmick,1e8',
AMM_SWAP_POOL_V1_1_WSTX_WNOPE = 'token-amm-swap-pool-v1-1:token-wstx,token-wnope,1e8',
AMM_SWAP_POOL_V1_1_WSTX_WFAST = 'token-amm-swap-pool-v1-1:token-wstx,token-wfast,1e8',
AMM_SWAP_POOL_V1_1_WSTX_WFRODO = 'token-amm-swap-pool-v1-1:token-wstx,token-wfrodo,1e8',
AMM_SWAP_POOL_V1_1_WSTX_WPICSUM = 'token-amm-swap-pool-v1-1:token-wstx,token-wpicsum,1e8',
AMM_SWAP_POOL_V1_1_ABTC_WBTC = 'token-amm-swap-pool-v1-1:token-abtc,token-wbtc,0.05e8',
AMM_SWAP_POOL_V1_1_WSTX_WWIF = 'token-amm-swap-pool-v1-1:token-wstx,token-wwif,1e8',
AMM_SWAP_POOL_V1_1_WSTX_STX20STXS = 'token-amm-swap-pool-v1-1:token-wstx,stx20-stxs,1e8',
AMM_SWAP_POOL_V1_1_ABTC_BRC20DB20 = 'token-amm-swap-pool-v1-1:token-abtc,brc20-db20,1e8',
AMM_SWAP_POOL_V1_1_ABTC_SSKO = 'token-amm-swap-pool-v1-1:token-abtc,token-ssko,1e8',
}
export type SwapTokens = Currency;
export const getRoute = (
tokenX: Currency,
tokenY: Currency,
ammPools: PoolTokens[]
): AMMSwapRoute[] =>
resolveAmmRoute(
tokenX,
tokenY,
// AMM_SWAP_POOL_WXUSD_WUSDA is deprecated now, don't use it if we have AMM_SWAP_POOL_WXUSD_WUSDA_2 is available
ammPools.includes(Pool.AMM_SWAP_POOL_WXUSD_WUSDA_2)
? ammPools.filter((a) => a !== Pool.AMM_SWAP_POOL_WXUSD_WUSDA)
: ammPools
);
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
export const reachableInAMM: typeof bridgeHelperResolver = (...args) =>
bridgeHelperResolver(...args);
export const ammTokens = [
Pool.AMM_SWAP_POOL_WXUSD_WUSDA,
Pool.AMM_SWAP_POOL_WXUSD_WUSDA_2,
Pool.AMM_SWAP_POOL_ALEX_WDIKO,
Pool.AMM_SWAP_POOL_WSTX_WCORGI,
Pool.AMM_SWAP_POOL_WSTX_SUSDT,
];
export const ammV1_1Tokens = [
Pool.AMM_SWAP_POOL_V1_1_WSTX_SUSDT,
Pool.AMM_SWAP_POOL_V1_1_WSTX_XBTC,
Pool.AMM_SWAP_POOL_V1_1_WSTX_ALEX,
Pool.AMM_SWAP_POOL_V1_1_ALEX_DIKO,
Pool.AMM_SWAP_POOL_V1_1_ALEX_ATALEXV2,
Pool.AMM_SWAP_POOL_V1_1_WSTX_WVIBES,
Pool.AMM_SWAP_POOL_V1_1_ALEX_BRC20DB20,
Pool.AMM_SWAP_POOL_V1_1_SUSDT_XUSD,
Pool.AMM_SWAP_POOL_V1_1_WSTX_LUNAR,
Pool.AMM_SWAP_POOL_V1_1_SUSDT_CHAX,
Pool.AMM_SWAP_POOL_V1_1_WSTX_ABTC,
Pool.AMM_SWAP_POOL_V1_1_WSTX_WLEO,
Pool.AMM_SWAP_POOL_V1_1_WSTX_WMEGA,
Pool.AMM_SWAP_POOL_V1_1_ABTC_BRC20ORDG,
Pool.AMM_SWAP_POOL_V1_1_ABTC_BRC20ORMM,
Pool.AMM_SWAP_POOL_V1_1_WSTX_WGUS,
Pool.AMM_SWAP_POOL_V1_1_ABTC_BRC20ORNJ,
Pool.AMM_SWAP_POOL_V1_1_WSTX_WLONG,
Pool.AMM_SWAP_POOL_V1_1_WSTX_WWNOTHING,
Pool.AMM_SWAP_POOL_V1_1_WSTX_WAEWBTC,
Pool.AMM_SWAP_POOL_V1_1_WSTX_WLQSTX,
Pool.AMM_SWAP_POOL_V1_1_WSTX_WPLAY,
Pool.AMM_SWAP_POOL_V1_1_WSTX_WMAX,
Pool.AMM_SWAP_POOL_V1_1_WSTX_WAEUSDC,
Pool.AMM_SWAP_POOL_V1_1_WSTX_WPEPE,
Pool.AMM_SWAP_POOL_V1_1_WSTX_WMICK,
Pool.AMM_SWAP_POOL_V1_1_WSTX_WNOPE,
Pool.AMM_SWAP_POOL_V1_1_WSTX_WFAST,
Pool.AMM_SWAP_POOL_V1_1_WSTX_WFRODO,
Pool.AMM_SWAP_POOL_V1_1_WSTX_WPICSUM,
Pool.AMM_SWAP_POOL_V1_1_ABTC_WBTC,
Pool.AMM_SWAP_POOL_V1_1_WSTX_WWIF,
Pool.AMM_SWAP_POOL_V1_1_WSTX_STX20STXS,
Pool.AMM_SWAP_POOL_V1_1_ABTC_BRC20DB20,
Pool.AMM_SWAP_POOL_V1_1_ABTC_SSKO,
];
export type PoolTokens = Pool;
export const isPoolV1Token = (token: string): token is PoolTokens =>
ammTokens.includes(token as any);
export const isPoolV1_1Token = (token: string): token is PoolTokens =>
ammV1_1Tokens.includes(token as any);
export const fromXY = (
x: Currency,
y: Currency,
factor: number
): PoolTokens => {
if (x === Currency.XUSD && y === Currency.USDA && factor === 0.0001e8) {
return Pool.AMM_SWAP_POOL_WXUSD_WUSDA;
}
throw new Error(`Invalid AMM token: ${x} ${y}`);
};
export function breakDown(
poolToken: AMMSwapPool.PoolTokens
): [
(
| Currency.STX
| Currency.ALEX
| Currency.XUSD
| Currency.sUSDT
| Currency.aBTC
),
AMMSwapPool.SwapTokens
] {
switch (poolToken) {
case Pool.AMM_SWAP_POOL_WXUSD_WUSDA:
case Pool.AMM_SWAP_POOL_WXUSD_WUSDA_2:
return [Currency.XUSD, Currency.USDA];
// case Pool.AMM_SWAP_POOL_WSTX_ALEX:
// return [Currency.STX, Currency.ALEX];
// case Pool.AMM_SWAP_POOL_WSTX_XBTC:
// return [Currency.STX, Currency.XBTC];
// case Pool.AMM_SWAP_POOL_ALEX_WBAN:
// return [Currency.ALEX, Currency.BANANA];
// case Pool.AMM_SWAP_POOL_ALEX_WUSDA:
// return [Currency.ALEX, Currency.USDA];
case Pool.AMM_SWAP_POOL_ALEX_WDIKO:
return [Currency.ALEX, Currency.DIKO];
case Pool.AMM_SWAP_POOL_WSTX_WCORGI:
return [Currency.STX, Currency.CORGI];
case Pool.AMM_SWAP_POOL_WSTX_SUSDT:
return [Currency.STX, Currency.sUSDT];
case Pool.AMM_SWAP_POOL_V1_1_WSTX_XBTC:
return [Currency.STX, Currency.XBTC];
case Pool.AMM_SWAP_POOL_V1_1_WSTX_ALEX:
return [Currency.STX, Currency.ALEX];
case Pool.AMM_SWAP_POOL_V1_1_WSTX_SUSDT:
return [Currency.STX, Currency.sUSDT];
case Pool.AMM_SWAP_POOL_V1_1_ALEX_DIKO:
return [Currency.ALEX, Currency.DIKO];
case Pool.AMM_SWAP_POOL_V1_1_ALEX_ATALEXV2:
return [Currency.ALEX, Currency.ATALEXV2];
case Pool.AMM_SWAP_POOL_V1_1_WSTX_WVIBES:
return [Currency.STX, Currency.VIBES];
case Pool.AMM_SWAP_POOL_V1_1_ALEX_BRC20DB20:
return [Currency.ALEX, Currency.BRC20_DB20];
case Pool.AMM_SWAP_POOL_V1_1_SUSDT_XUSD:
return [Currency.sUSDT, Currency.XUSD];
case Pool.AMM_SWAP_POOL_V1_1_WSTX_LUNAR:
return [Currency.STX, Currency.sLUNR];
case Pool.AMM_SWAP_POOL_V1_1_SUSDT_CHAX:
return [Currency.sUSDT, Currency.BRC20_CHAX];
case Pool.AMM_SWAP_POOL_V1_1_WSTX_ABTC:
return [Currency.STX, Currency.aBTC];
case Pool.AMM_SWAP_POOL_V1_1_WSTX_WLEO:
return [Currency.STX, Currency.LEO];
case Pool.AMM_SWAP_POOL_V1_1_WSTX_WMEGA:
return [Currency.STX, Currency.MEGA];
case Pool.AMM_SWAP_POOL_V1_1_ABTC_BRC20ORDG:
return [Currency.aBTC, Currency.BRC20_ORDG];
case Pool.AMM_SWAP_POOL_V1_1_ABTC_BRC20ORMM:
return [Currency.aBTC, Currency.BRC20_ORMM];
case Pool.AMM_SWAP_POOL_V1_1_WSTX_WGUS:
return [Currency.STX, Currency.GUS];
case Pool.AMM_SWAP_POOL_V1_1_ABTC_BRC20ORNJ:
return [Currency.aBTC, Currency.BRC20_ORNJ];
case Pool.AMM_SWAP_POOL_V1_1_WSTX_WLONG:
return [Currency.STX, Currency.LONG];
case Pool.AMM_SWAP_POOL_V1_1_WSTX_WWNOTHING:
return [Currency.STX, Currency.WNOTHING];
case Pool.AMM_SWAP_POOL_V1_1_WSTX_WAEWBTC:
return [Currency.STX, Currency.AEWBTC];
case Pool.AMM_SWAP_POOL_V1_1_WSTX_WLQSTX:
return [Currency.STX, Currency.LQSTX];
case Pool.AMM_SWAP_POOL_V1_1_WSTX_WPLAY:
return [Currency.STX, Currency.PLAY];
case Pool.AMM_SWAP_POOL_V1_1_WSTX_WMAX:
return [Currency.STX, Currency.MAX];
case Pool.AMM_SWAP_POOL_V1_1_WSTX_WAEUSDC:
return [Currency.STX, Currency.AEUSDC];
case Pool.AMM_SWAP_POOL_V1_1_WSTX_WPEPE:
return [Currency.STX, Currency.PEPE];
case Pool.AMM_SWAP_POOL_V1_1_WSTX_WMICK:
return [Currency.STX, Currency.MICK];
case Pool.AMM_SWAP_POOL_V1_1_WSTX_WNOPE:
return [Currency.STX, Currency.NOPE];
case Pool.AMM_SWAP_POOL_V1_1_WSTX_WFAST:
return [Currency.STX, Currency.FAST];
case Pool.AMM_SWAP_POOL_V1_1_WSTX_WFRODO:
return [Currency.STX, Currency.FRODO];
case Pool.AMM_SWAP_POOL_V1_1_WSTX_WPICSUM:
return [Currency.STX, Currency.PICSUM];
case Pool.AMM_SWAP_POOL_V1_1_ABTC_WBTC:
return [Currency.aBTC, Currency.XBTC];
case Pool.AMM_SWAP_POOL_V1_1_WSTX_WWIF:
return [Currency.STX, Currency.WIF];
case Pool.AMM_SWAP_POOL_V1_1_WSTX_STX20STXS:
return [Currency.STX, Currency.STX20_STXS];
case Pool.AMM_SWAP_POOL_V1_1_ABTC_BRC20DB20:
return [Currency.aBTC, Currency.BRC20_DB20];
case Pool.AMM_SWAP_POOL_V1_1_ABTC_SSKO:
return [Currency.aBTC, Currency.sSKO];
default:
assertNever(poolToken);
}
}
export function getFactor(poolToken: PoolTokens): bigint {
switch (poolToken) {
case Pool.AMM_SWAP_POOL_WXUSD_WUSDA:
return BigInt(0.0001e8);
case Pool.AMM_SWAP_POOL_WXUSD_WUSDA_2:
return BigInt(0.005e8);
// case Pool.AMM_SWAP_POOL_WSTX_ALEX:
// case Pool.AMM_SWAP_POOL_WSTX_XBTC:
// case Pool.AMM_SWAP_POOL_ALEX_WBAN:
// case Pool.AMM_SWAP_POOL_ALEX_WUSDA:
case Pool.AMM_SWAP_POOL_ALEX_WDIKO:
case Pool.AMM_SWAP_POOL_WSTX_WCORGI:
case Pool.AMM_SWAP_POOL_WSTX_SUSDT:
case Pool.AMM_SWAP_POOL_V1_1_WSTX_XBTC:
case Pool.AMM_SWAP_POOL_V1_1_WSTX_ALEX:
case Pool.AMM_SWAP_POOL_V1_1_WSTX_SUSDT:
case Pool.AMM_SWAP_POOL_V1_1_ALEX_DIKO:
case Pool.AMM_SWAP_POOL_V1_1_ALEX_ATALEXV2:
case Pool.AMM_SWAP_POOL_V1_1_WSTX_WVIBES:
case Pool.AMM_SWAP_POOL_V1_1_ALEX_BRC20DB20:
case Pool.AMM_SWAP_POOL_V1_1_WSTX_LUNAR:
case Pool.AMM_SWAP_POOL_V1_1_SUSDT_CHAX:
case Pool.AMM_SWAP_POOL_V1_1_WSTX_ABTC:
case Pool.AMM_SWAP_POOL_V1_1_WSTX_WLEO:
case Pool.AMM_SWAP_POOL_V1_1_WSTX_WMEGA:
case Pool.AMM_SWAP_POOL_V1_1_ABTC_BRC20ORDG:
case Pool.AMM_SWAP_POOL_V1_1_ABTC_BRC20ORMM:
case Pool.AMM_SWAP_POOL_V1_1_WSTX_WGUS:
case Pool.AMM_SWAP_POOL_V1_1_ABTC_BRC20ORNJ:
case Pool.AMM_SWAP_POOL_V1_1_WSTX_WLONG:
case Pool.AMM_SWAP_POOL_V1_1_WSTX_WWNOTHING:
case Pool.AMM_SWAP_POOL_V1_1_WSTX_WAEWBTC:
case Pool.AMM_SWAP_POOL_V1_1_WSTX_WPLAY:
case Pool.AMM_SWAP_POOL_V1_1_WSTX_WMAX:
case Pool.AMM_SWAP_POOL_V1_1_WSTX_WAEUSDC:
case Pool.AMM_SWAP_POOL_V1_1_WSTX_WPEPE:
case Pool.AMM_SWAP_POOL_V1_1_WSTX_WMICK:
case Pool.AMM_SWAP_POOL_V1_1_WSTX_WNOPE:
case Pool.AMM_SWAP_POOL_V1_1_WSTX_WFAST:
case Pool.AMM_SWAP_POOL_V1_1_WSTX_WFRODO:
case Pool.AMM_SWAP_POOL_V1_1_WSTX_WPICSUM:
case Pool.AMM_SWAP_POOL_V1_1_WSTX_WWIF:
case Pool.AMM_SWAP_POOL_V1_1_WSTX_STX20STXS:
case Pool.AMM_SWAP_POOL_V1_1_ABTC_BRC20DB20:
case Pool.AMM_SWAP_POOL_V1_1_ABTC_SSKO:
return BigInt(1e8);
case Pool.AMM_SWAP_POOL_V1_1_SUSDT_XUSD:
case Pool.AMM_SWAP_POOL_V1_1_WSTX_WLQSTX:
case Pool.AMM_SWAP_POOL_V1_1_ABTC_WBTC:
return BigInt(0.05e8);
default:
assertNever(poolToken);
}
}
}

View File

@@ -1,41 +1,36 @@
import { isNotNull } from './utils'; import { isNotNull } from './utils';
import { AMMSwapPool } from './ammPool'; import { Currency } from '../currency';
import { PoolData } from '../types';
export type AMMSwapRoute = { export type AMMSwapRoute = {
neighbour: AMMSwapPool.SwapTokens; neighbour: Currency;
pool: AMMSwapPool.PoolTokens; pool: PoolData;
}; };
function neighbours( function neighbours(token: Currency, pools: PoolData[]): AMMSwapRoute[] {
token: AMMSwapPool.SwapTokens,
pools: AMMSwapPool.PoolTokens[]
): AMMSwapRoute[] {
return pools return pools
.map((pool) => { .map((pool) => {
const [x, y] = AMMSwapPool.breakDown(pool); if (pool.token_x === token) return { neighbour: pool.token_y, pool };
if (x === token) return { neighbour: y, pool }; if (pool.token_y === token) return { neighbour: pool.token_x, pool };
if (y === token) return { neighbour: x, pool };
return null; return null;
}) })
.filter(isNotNull); .filter(isNotNull);
} }
export function resolveAmmRoute( export function resolveAmmRoute(
tokenX: AMMSwapPool.SwapTokens, tokenX: Currency,
tokenY: AMMSwapPool.SwapTokens, tokenY: Currency,
pools: AMMSwapPool.PoolTokens[] pools: PoolData[]
): AMMSwapRoute[] { ): AMMSwapRoute[] {
if (pools.length === 0) { if (pools.length === 0) {
return []; return [];
} }
const visited: { [key in AMMSwapPool.SwapTokens]?: AMMSwapRoute[] } = { const visited: { [key: string]: AMMSwapRoute[] } = {
[tokenX]: [], [tokenX]: [],
}; };
// contract only support up to 4 segments // contract only support up to 4 segments
for (let i = 0; i < 4; i++) { for (let i = 0; i < 4; i++) {
const visitedNodes = Object.keys(visited).map( const visitedNodes = Object.keys(visited).map((a) => a as Currency);
(a) => a as AMMSwapPool.SwapTokens
);
for (const a of visitedNodes) { for (const a of visitedNodes) {
for (const b of neighbours(a, pools)) { for (const b of neighbours(a, pools)) {
if (b.neighbour === tokenY) { if (b.neighbour === tokenY) {

View File

@@ -1,50 +0,0 @@
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
import { AMMSwapPool } from './ammPool';
import { Currency } from '../currency';
export function bridgeHelperResolver(
from: Currency,
to: Currency,
ammPools: AMMSwapPool.PoolTokens[]
) {
const bridgingToken = [Currency.STX, Currency.ALEX];
if (bridgingToken.includes(from) || bridgingToken.includes(to)) {
return { type: "none" as const }
}
if (bridgingToken.includes(from) || bridgingToken.includes(to)) {
return { type: "none" as const }
}
const fromPool = ammPools.find((a) => {
if (!AMMSwapPool.breakDown(a).includes(from)) return false;
const [x, y] = AMMSwapPool.breakDown(a);
return bridgingToken.includes(x === from ? y : x);
});
if (fromPool) {
const [x, y] = AMMSwapPool.breakDown(fromPool);
return {
pool: fromPool,
type: 'fromAmm' as const,
tokenX: from,
tokenY: x === from ? y : x,
factorX: AMMSwapPool.getFactor(fromPool),
tokenZ: to,
};
}
const toPool = ammPools.find((a) => {
if (!AMMSwapPool.breakDown(a).includes(to)) return false;
const [x, y] = AMMSwapPool.breakDown(a);
return bridgingToken.includes(x === to ? y : x);
});
if (toPool) {
const [x, y] = AMMSwapPool.breakDown(toPool);
return {
pool: toPool,
type: 'toAmm' as const,
tokenX: from,
tokenY: x === to ? y : x,
factorY: AMMSwapPool.getFactor(toPool),
tokenZ: to,
};
}
return { type: 'none' as const };
}

View File

@@ -1,41 +0,0 @@
import { Currency } from '../currency';
export async function fetchLatestPrices(): Promise<
Partial<{
[currency in Currency]: number;
}>
> {
const res = await fetch('https://gql.alexlab.co/v1/graphql', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
query: `
query FetchLatestPrices {
laplace_current_token_price {
avg_price_usd
token
}
}
`,
}),
}).then((a) => a.json());
const result: Partial<{ [currency in Currency]: number }> = {};
for (const value of Object.values(Currency)) {
const external = res.data.laplace_current_token_price.find(
(a: any) => a.token === value + '-external' && a.avg_price_usd != null
);
if (external) {
result[value] = external.avg_price_usd!;
} else {
const nonExternal = res.data.laplace_current_token_price.find(
(a: any) => a.token === value && a.avg_price_usd != null
);
if (nonExternal) {
result[value] = nonExternal.avg_price_usd!;
}
}
}
return result;
}

View File

@@ -1,51 +0,0 @@
import { Currency } from '../currency';
import { configs } from '../config';
import type { AddressBalanceResponse } from '@stacks/stacks-blockchain-api-types';
export function getCurrencyNativeScale(currency: Currency) {
if (currency === Currency.STX) {
return 1e6;
}
return configs.NATIVE_TOKEN_MAPPING[currency].decimals;
}
export function getCurrencyNativeAddress(currency: Currency) {
if (currency === Currency.STX) {
throw new Error('STX does not have an address');
}
return configs.NATIVE_TOKEN_MAPPING[currency].assetIdentifier;
}
export function findCurrencyByNativeAddress(
address: string
): Currency | undefined {
return Object.values(Currency)
.filter((a) => a !== Currency.STX)
.find(
(a) =>
getCurrencyNativeAddress(a).split('::')[0] === address.split('::')[0]
);
}
export async function fetchBalanceForAccount(
stxAddress: string
): Promise<{ [currency in Currency]: bigint }> {
const response: AddressBalanceResponse = await fetch(
`${configs.API_HOST}/extended/v1/address/${stxAddress}/balances`
).then((a) => a.json());
const allCurrencies = Object.values(Currency);
const balances = allCurrencies.map((a) => {
if (a === Currency.STX) return BigInt(response.stx.balance) * BigInt(100);
const fungibleToken =
response.fungible_tokens[getCurrencyNativeAddress(a)]?.balance;
if (fungibleToken == null) {
return BigInt(0);
}
return (
(BigInt(fungibleToken) * BigInt(1e8)) / BigInt(getCurrencyNativeScale(a))
);
});
return Object.fromEntries(
allCurrencies.map((a, i) => [a, balances[i]])
) as any;
}

83
src/utils/fetchData.ts Normal file
View File

@@ -0,0 +1,83 @@
import { PoolData, PriceData, TokenMapping } from '../types';
import { createCurrency, Currency, STXCurrency } from '../currency';
import type { AddressBalanceResponse } from '@stacks/stacks-blockchain-api-types';
import { configs } from '../config';
import { fromEntries, isNotNull } from './utils';
export async function getMappingData(): Promise<TokenMapping[]> {
return fetch(`${configs.API_HOST}/v2/public/token-mappings`)
.then((r) => {
if (r.ok) {
return r.json();
}
throw new Error('Failed to fetch token mappings');
})
.then((r: any) => r.data);
}
export async function getPoolData(): Promise<PoolData[]> {
return fetch(`${configs.API_HOST}/v2/public/pools`)
.then((r) => {
if (r.ok) {
return r.json();
}
throw new Error('Failed to fetch token mappings');
})
.then((x: any) =>
x.data.map(
(a: any): PoolData => ({
factor: BigInt(Math.round(a.factor * 1e8)),
token_x: a.token_x,
token_y: a.token_y,
})
)
);
}
export async function getPrices(mappings: TokenMapping[]): Promise<PriceData[]> {
return fetch(`${configs.API_HOST}/v2/public/token-prices`)
.then((r) => {
if (r.ok) {
return r.json();
}
throw new Error('Failed to fetch token mappings');
})
.then((x: any) =>
x.data.map(
(a: any): PriceData | null => {
const token = mappings.find(b => b.wrapped_token === a.contract_id)?.token;
if (token == null) {
return null
}
return ({
token,
price: a.last_price_usd,
});
}
).filter(isNotNull)
);
}
export async function fetchBalanceForAccount(
stxAddress: string,
tokenMappings: TokenMapping[]
): Promise<Partial<{ [currency in Currency]: bigint }>> {
const response: AddressBalanceResponse = await fetch(
`${configs.STACKS_API_HOST}/extended/v1/address/${stxAddress}/balances`
).then((a) => a.json());
return fromEntries(
tokenMappings.map((a) => {
if (a.token === STXCurrency) {
return [a.token, BigInt(response.stx.balance) * BigInt(100)];
}
const fungibleToken = response.fungible_tokens[a.wrapped_token]?.balance;
if (fungibleToken == null) {
return [a.token, BigInt(0)];
}
return [
a.token,
(BigInt(fungibleToken) * BigInt(1e8)) /
BigInt(10 ** a.wrapped_token_decimals),
];
})
);
}

View File

@@ -5,35 +5,31 @@ import {
FungiblePostCondition, FungiblePostCondition,
STXPostCondition, STXPostCondition,
} from '@stacks/transactions'; } from '@stacks/transactions';
import { import { Currency, STXCurrency } from '../currency';
getCurrencyNativeAddress, import { TokenMapping } from '../types';
getCurrencyNativeScale,
} from './currencyUtils';
import { Currency } from '../currency';
export function transfer( export const transferFactory =
senderAddress: string, (tokenMapping: TokenMapping[]) =>
currency: Currency, (
amount: bigint, senderAddress: string,
compare: FungibleConditionCode = FungibleConditionCode.Equal currency: Currency,
): FungiblePostCondition | STXPostCondition { amount: bigint,
const scale = getCurrencyNativeScale(currency); compare: FungibleConditionCode = FungibleConditionCode.Equal
if (currency === Currency.LQSTX) { ): FungiblePostCondition | STXPostCondition => {
// LQSTX is a rebase token, the ft-event number will not match const mapping = tokenMapping.find((m) => m.token === currency);
// The amount inputted. So we set the amount to 0, and the compare if (!mapping) {
// to GreaterEqual to ensure the condition passes. throw new Error('Token mapping not found');
amount = BigInt(0); }
compare = FungibleConditionCode.GreaterEqual; const scale = BigInt(10 ** mapping.wrapped_token_decimals);
} const nativeAmount = (amount * BigInt(scale)) / BigInt(1e8);
const nativeAmount = (amount * BigInt(scale)) / BigInt(1e8); if (currency === STXCurrency) {
if (currency === Currency.STX) { return createSTXPostCondition(senderAddress, compare, nativeAmount);
return createSTXPostCondition(senderAddress, compare, nativeAmount); }
} const assetIdentifier = `${mapping.wrapped_token}::${mapping.wrapped_token_asset}`;
const assetIdentifier = getCurrencyNativeAddress(currency); return createFungiblePostCondition(
return createFungiblePostCondition( senderAddress,
senderAddress, compare,
compare, nativeAmount,
nativeAmount, assetIdentifier
assetIdentifier );
); };
}

View File

@@ -1,10 +1,10 @@
import { import {
callReadOnlyFunction, callReadOnlyFunction,
ReadOnlyFunctionOptions,
ClarityValue, ClarityValue,
ReadOnlyFunctionOptions,
} from '@stacks/transactions'; } from '@stacks/transactions';
import { configs } from '../config'; import { configs } from '../config';
import { StacksMainnet, StacksTestnet } from '@stacks/network'; import { StacksMainnet } from '@stacks/network';
import { import {
ParameterObjOfDescriptor, ParameterObjOfDescriptor,
ReadonlyFunctionDescriptor, ReadonlyFunctionDescriptor,
@@ -25,13 +25,9 @@ const defaultReadonlyCallExecutor: ReadonlyCallExecutor = async (options) => {
return callReadOnlyFunction({ return callReadOnlyFunction({
...options, ...options,
senderAddress: configs.CONTRACT_DEPLOYER, senderAddress: configs.CONTRACT_DEPLOYER,
network: configs.IS_MAINNET network: new StacksMainnet({
? new StacksMainnet({ url: configs.READONLY_CALL_API_HOST,
url: configs.API_HOST, }),
})
: new StacksTestnet({
url: configs.API_HOST,
}),
}); });
}; };

View File

@@ -1,151 +0,0 @@
import { configs } from '../config';
export enum SponsoredTxErrorCode {
// The submitted tx payload is invalid
'invalid_tx' = 'invalid_tx',
// The requested contract / function aren't whitelisted
'operation_not_supported' = 'operation_not_supported',
// Current user already have a pending sponsored transaction
'pending_operation_exists' = 'pending_operation_exists',
// The requested tx exceed the capacity of the pool
'capacity_exceed' = 'capacity_exceed',
// Current user have pending operation, we require the submitted nonce to be immediate nonce
'invalid_nonce' = 'invalid_nonce',
// Worker failed to broadcast the tx
'broadcast_error' = 'broadcast_error',
'unknown_error' = 'unknown_error',
}
export class SponsoredTxError extends Error {
constructor(readonly code: SponsoredTxErrorCode, message: string) {
super(message);
}
}
export async function broadcastSponsoredTx(tx: string): Promise<string> {
const response = await fetch(configs.SPONSORED_TX_EXECUTOR, {
method: 'POST',
mode: 'cors',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
query: `mutation run($tx:String!) {
execute(tx:$tx)
}`,
variables: {
tx,
},
}),
});
if (!response.ok) {
throw new SponsoredTxError(
SponsoredTxErrorCode.unknown_error,
response.statusText
);
}
const result = await response.json();
if (result.data == null) {
const message = result.errors?.[0]?.message ?? 'Unknown Error';
const errorCode = result.errors?.[0]?.extensions?.code;
const code = Object.values(SponsoredTxErrorCode).includes(errorCode)
? errorCode
: SponsoredTxErrorCode.unknown_error;
throw new SponsoredTxError(code, message);
}
const {
data: { execute: txId },
} = result;
return await retry(() => tryToFetchTxId(txId), 10);
}
async function tryToFetchTxId(txId: string): Promise<string | null> {
const response = await fetch(configs.SPONSORED_TX_EXECUTOR, {
method: 'POST',
mode: 'cors',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
query: `query checkStatus($txId: bytea!) {
user_operations(where:{tx_id:{_eq:$txId}}) {
sponsor_tx_id
error
}
}`,
variables: {
txId: hexAddressToHasuraAddress(txId),
},
}),
});
if (!response.ok) {
throw new SponsoredTxError(
SponsoredTxErrorCode.unknown_error,
response.statusText
);
}
const {
data: { user_operations },
} = await response.json();
if (user_operations.length === 0) {
return null;
}
const operation = user_operations[0];
if (operation.error) {
throw new SponsoredTxError(
SponsoredTxErrorCode.broadcast_error,
operation.error
);
} else if (operation.sponsor_tx_id) {
return hasuraAddressToHex(operation.sponsor_tx_id);
}
return null;
}
async function retry<T>(
action: () => Promise<T | null>,
count = 20
): Promise<T> {
for (let i = 0; i < count; i++) {
const result = await action();
if (result === null) {
await new Promise((resolve) => setTimeout(resolve, 1000));
continue;
}
return result;
}
throw new SponsoredTxError(
SponsoredTxErrorCode.broadcast_error,
'Timeout waiting for broadcast'
);
}
function hexAddressToHasuraAddress(input: string): string {
return '\\x' + input;
}
function hasuraAddressToHex(input: string): string {
return input.replace(/\\x/, '0x').toLowerCase();
}
export async function isSponsoredSwapEnabled(): Promise<boolean> {
const response = await fetch(configs.SPONSORED_TX_EXECUTOR, {
method: 'POST',
mode: 'cors',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
query: `query {
isSwapServiceAvailable {
status
}
}`,
}),
});
if (!response.ok) {
return false;
}
const result = await response.json();
return result?.data.isSwapServiceAvailable.status === 'ok';
}

View File

@@ -1,28 +0,0 @@
import { Currency } from '../currency';
export type TokenInfo = {
type: 'fungibleToken';
id: string;
name: string;
displayPrecision: number;
icon: string;
availableInSwap: boolean;
contractAddress: string;
decimals: number;
};
export function fetchTokenList(): Promise<TokenInfo[]> {
return fetch('https://token-list.alexlab.co', {
mode: 'cors',
})
.then((res) => res.json())
.then((data) => data.tokens);
}
export async function fetchSwappableCurrency(): Promise<TokenInfo[]> {
const tokens = await fetchTokenList();
return tokens.filter(
(x) =>
x.availableInSwap && Object.values(Currency).includes(x.id as Currency)
);
}

View File

@@ -5,3 +5,12 @@ export function isNotNull<T>(input: T | undefined | null): input is T {
export function assertNever(x: never): never { export function assertNever(x: never): never {
throw new Error('Unexpected object: ' + x); throw new Error('Unexpected object: ' + x);
} }
export function fromEntries<K extends string, V>(
entries: [K, V][]
): Record<K, V> {
return entries.reduce((acc, [key, value]) => {
acc[key] = value;
return acc;
}, {} as Record<K, V>);
}

View File

@@ -1,37 +1,38 @@
import { configs } from '../src/config'; import { configs } from '../src/config';
import { Currency } from '../src/currency'; import { AlexSDK, Currency, STXCurrency } from '../src';
import { AlexSDK } from '../src/alexSDK';
describe.skip('AlexSDK', () => { const tokenAlex = 'SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.token-alex' as Currency;
const tokenDiko = 'SP102V8P0F7JX67ARQ77WEA3D3CFB5XW39REDT0AM.token-wdiko' as Currency
describe('AlexSDK', () => {
it('Get fee', async () => { it('Get fee', async () => {
const sdk = new AlexSDK(); const sdk = new AlexSDK();
const result = await sdk.getFeeRate(Currency.ALEX, Currency.STX); const result = await sdk.getFeeRate(tokenAlex, STXCurrency);
console.log(result); console.log(result);
}); });
it('Get Route', async () => { it('Get Route', async () => {
const sdk = new AlexSDK(); const sdk = new AlexSDK();
const result = await sdk.getRouter(Currency.STX, Currency.DIKO); const result = await sdk.getRouter(STXCurrency, tokenDiko);
console.log(result); console.log(result);
}); });
it('Get Rate', async () => { it('Get Rate', async () => {
const sdk = new AlexSDK(); const sdk = new AlexSDK();
const result = await sdk.getAmountTo( const result = await sdk.getAmountTo(
Currency.STX, STXCurrency,
BigInt(2) * BigInt(1e8), BigInt(2) * BigInt(1e8),
Currency.DIKO tokenDiko
); );
console.log(result); console.log(result);
}); });
it('Get Tx', async () => { it('Get Tx', async () => {
const sdk = new AlexSDK(); const sdk = new AlexSDK();
const router = await sdk.getRouter(Currency.STX, Currency.DIKO); const router = await sdk.getRouter(STXCurrency, tokenDiko);
const result = await sdk.runSwap( const result = await sdk.runSwap(
configs.CONTRACT_DEPLOYER, configs.CONTRACT_DEPLOYER,
Currency.STX, STXCurrency,
Currency.DIKO, tokenDiko,
BigInt(2) * BigInt(1e8), BigInt(2) * BigInt(1e8),
BigInt(0), BigInt(0),
router
); );
console.log(result); console.log(result);
}); });

View File

@@ -31,5 +31,6 @@
"forceConsistentCasingInFileNames": true, "forceConsistentCasingInFileNames": true,
// `tsdx build` ignores this option, but it is commonly used when type-checking separately with `tsc` // `tsdx build` ignores this option, but it is commonly used when type-checking separately with `tsc`
"noEmit": true, "noEmit": true,
"resolveJsonModule": true
} }
} }