Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sync / Gateway development -> staging #373

Merged
merged 44 commits into from
Dec 26, 2024
Merged
Show file tree
Hide file tree
Changes from 33 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
b4cd139
(wip) add back robotter's solana chain connector
fengtality Jul 26, 2024
7e380a9
(wip) update token list
fengtality Jul 26, 2024
696d8aa
(fix) resolved conflicts
fengtality Jul 31, 2024
0475e17
fixed conflicts
fengtality Aug 20, 2024
10db292
(wip) init orca files
fengtality Aug 21, 2024
a862249
(wip) skeleton running
fengtality Aug 21, 2024
ea8dc47
(wip) dummy position route working
fengtality Aug 21, 2024
7ff8704
(wip) update sol libs
fengtality Aug 21, 2024
906463d
feat: make the uniswap tests work on sepolia
flanagansteve Sep 10, 2024
8c153ed
Merge branch 'development' into feat/sepolia-tests
fengtality Sep 24, 2024
e40daa2
Merge branch 'development' into feat/sepolia-tests
nikspz Oct 21, 2024
813ad2b
bump dev version 2.2.0
Oct 29, 2024
95e2b16
Merge pull request #367 from hummingbot/update-dev-version-2.2.0
rapcmia Oct 29, 2024
6cf45ed
(fix) fix poll route for base approvals
fengtality Nov 28, 2024
38d2a89
Merge pull request #370 from hummingbot/fix/poll-retries
cardosofede Nov 28, 2024
b354c70
(fix) change v2 pool fetch
fengtality Nov 28, 2024
01d4c01
Merge branch 'development' into fix/pancake-router
fengtality Nov 28, 2024
c554d8e
Merge pull request #371 from hummingbot/fix/pancake-router
cardosofede Dec 2, 2024
e23066a
(fix) update for latest dev
fengtality Dec 4, 2024
96fe163
(feat) updated solana controller
fengtality Dec 4, 2024
03859ab
delete unused middleware
fengtality Dec 4, 2024
17ad60a
added community jupiter connector
fengtality Dec 5, 2024
c9d214c
Merge branch 'development' into feat/sepolia-tests
nikspz Dec 10, 2024
5a17fd4
Merge pull request #358 from flanagansteve/feat/sepolia-tests
nikspz Dec 10, 2024
dbeb75a
(wip) new jupiter controller
fengtality Dec 10, 2024
fd28cac
(wip) just solana controller errors left
fengtality Dec 10, 2024
0fae86b
(wip) builds
fengtality Dec 11, 2024
9398b28
(wip) jupiter trade route
fengtality Dec 11, 2024
9becbe6
(wip) fixed price fn
fengtality Dec 12, 2024
8d21e66
(wip) jupiter trade working
fengtality Dec 12, 2024
8ecabc9
(feat) jupiter connector working
fengtality Dec 13, 2024
3b7dc0f
Merge branch 'development' into solana-test
cardosofede Dec 16, 2024
6427959
Merge pull request #374 from hummingbot/solana-test
cardosofede Dec 16, 2024
994b475
(fix) solana tx
fengtality Dec 18, 2024
4b2cef5
Merge branch 'development' into fix/solana-tx
fengtality Dec 18, 2024
5377ff8
(fix) remove logging
fengtality Dec 19, 2024
a2013bc
Merge branch 'fix/solana-tx' of github.com:hummingbot/gateway into fi…
fengtality Dec 19, 2024
6be2b2d
Merge pull request #375 from hummingbot/fix/solana-tx
fengtality Dec 19, 2024
fd2a8fb
(wip) jupiter estimateGas
fengtality Dec 20, 2024
f86367e
Merge branch 'development' into fix/solana-tx
fengtality Dec 20, 2024
033a0ed
Merge pull request #376 from hummingbot/fix/solana-tx
cardosofede Dec 20, 2024
47d6fa6
(fix) jupiter fees
fengtality Dec 25, 2024
a392323
Merge pull request #378 from hummingbot/fix/solana-fees
fengtality Dec 26, 2024
fbe3937
Merge branch 'staging' into development
fengtality Dec 26, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "hummingbot-gateway",
"version": "dev-2.0.2",
"version": "dev-2.2.0",
"description": "Middleware that helps Hummingbot clients access standardized DEX API endpoints on different blockchain networks",
"main": "index.js",
"license": "Apache-2.0",
Expand Down Expand Up @@ -51,6 +51,12 @@
"@pancakeswap/v3-periphery": "^1.0.2",
"@pancakeswap/v3-sdk": "^3.7.0",
"@pangolindex/sdk": "^1.1.0",
"@coral-xyz/anchor": "^0.29.0",
"@solana/web3.js": "^1.95.8",
"@solana/spl-token": "0.4.8",
"@solana/spl-token-registry": "^0.2.4574",
"@solflare-wallet/utl-sdk": "^1.4.0",
"@jup-ag/api": "^6.0.29",
"@sushiswap/sdk": "^5.0.0-canary.116",
"@taquito/rpc": "^17.0.0",
"@taquito/signer": "^17.0.0",
Expand Down Expand Up @@ -115,7 +121,6 @@
"@babel/runtime": "^7.0",
"@connectis/diff-test-coverage": "^1.5.1",
"@improbable-eng/grpc-web": "^0.13.0",
"@solana/web3.js": "^1.58.0",
"@types/app-root-path": "^1.2.4",
"@types/big.js": "^6.1.3",
"@types/bs58": "^4.0.1",
Expand Down
15 changes: 13 additions & 2 deletions src/amm/amm.controllers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ import {
poolPrice as uniswapV3PoolPrice,
estimateGas as uniswapEstimateGas,
} from '../connectors/uniswap/uniswap.controllers';
import {
price as jupiterPrice,
trade as jupiterTrade,
} from '../connectors/jupiter/jupiter.controllers';
import {
price as carbonPrice,
trade as carbonTrade,
Expand All @@ -50,15 +54,18 @@ import {
Uniswapish,
UniswapLPish,
} from '../services/common-interfaces';
import { Solanaish } from '../chains/solana/solana';
import { Algorand } from '../chains/algorand/algorand';
import { Tinyman } from '../connectors/tinyman/tinyman';
import { Plenty } from '../connectors/plenty/plenty';
import { Osmosis } from '../chains/osmosis/osmosis';
import { Solana } from '../chains/solana/solana';
import { Jupiter } from '../connectors/jupiter/jupiter';
import { Carbonamm } from '../connectors/carbon/carbonAMM';

export async function price(req: PriceRequest): Promise<PriceResponse> {
const chain = await getInitializedChain<
Algorand | Ethereumish | Tezosish | Osmosis
Algorand | Ethereumish | Tezosish | Osmosis | Solana
>(req.chain, req.network);
if (chain instanceof Osmosis){
return chain.controller.price(chain as unknown as Osmosis, req);
Expand All @@ -73,6 +80,8 @@ export async function price(req: PriceRequest): Promise<PriceResponse> {

if (connector instanceof Plenty) {
return plentyPrice(<Tezosish>chain, connector, req);
} else if (connector instanceof Jupiter) {
return jupiterPrice(<Solanaish>chain, connector, req);
} else if (connector instanceof Carbonamm) {
return carbonPrice(<Ethereumish>chain, connector, req);
} else if ('routerAbi' in connector) {
Expand All @@ -84,7 +93,7 @@ export async function price(req: PriceRequest): Promise<PriceResponse> {

export async function trade(req: TradeRequest): Promise<TradeResponse> {
const chain = await getInitializedChain<
Algorand | Ethereumish | Tezosish | Osmosis
Algorand | Ethereumish | Tezosish | Osmosis | Solana
>(req.chain, req.network);
if (chain instanceof Osmosis){
return chain.controller.trade(chain as unknown as Osmosis, req);
Expand All @@ -99,6 +108,8 @@ export async function trade(req: TradeRequest): Promise<TradeResponse> {

if (connector instanceof Plenty) {
return plentyTrade(<Tezosish>chain, connector, req);
} else if (connector instanceof Jupiter) {
return jupiterTrade(<Solanaish>chain, connector, req);
} else if (connector instanceof Carbonamm) {
return carbonTrade(<Ethereumish>chain, connector, req);
} else if ('routerAbi' in connector) {
Expand Down
2 changes: 1 addition & 1 deletion src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ export const startSwagger = async () => {

export const startGateway = async () => {
const port = ConfigManagerV2.getInstance().get('server.port');
const gateway_version="dev-2.0.2"
const gateway_version="dev-2.2.0"
if (!ConfigManagerV2.getInstance().get('server.id')) {
ConfigManagerV2.getInstance().set(
'server.id',
Expand Down
18 changes: 9 additions & 9 deletions src/chains/cosmos/cosmos-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,15 +218,15 @@ export class CosmosBase {
}

async getLatestBasePrice(): Promise<number> {
var eipPrice = this.manualGasPrice;
if (this.useEIP1559DynamicBaseFeeInsteadOfManualGasPrice){
const eipPrice = await getEIP1559DynamicBaseFee(this.rpcAddressDynamicBaseFee);
if (eipPrice != ''){
this.manualGasPrice = Number(eipPrice);
let eipPrice = this.manualGasPrice;
if (this.useEIP1559DynamicBaseFeeInsteadOfManualGasPrice) {
const dynamicPrice = await getEIP1559DynamicBaseFee(this.rpcAddressDynamicBaseFee);
if (dynamicPrice != '') {
eipPrice = Number(dynamicPrice);
}
}
}
this.manualGasPrice = eipPrice;
return this.manualGasPrice
return this.manualGasPrice;
}

async loadTokens(
Expand All @@ -248,12 +248,12 @@ export class CosmosBase {
tokenListType: TokenListType
): Promise<CosmosAsset[]> {
let tokens: CosmosAsset[] = [];
let tokensJson = [];
let tokensJson: { assets: any[] };

if (tokenListType === 'URL') {
({ data: tokensJson } = await axios.get(tokenListSource));
} else {
(tokensJson = JSON.parse(await fs.readFile(tokenListSource, 'utf8')));
tokensJson = JSON.parse(await fs.readFile(tokenListSource, 'utf8'));
}
for (var tokenAssetIdx=0; tokenAssetIdx<tokensJson.assets.length; tokenAssetIdx++){
var tokenAsset = tokensJson.assets[tokenAssetIdx];
Expand Down
30 changes: 23 additions & 7 deletions src/chains/ethereum/evm.controllers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,14 +131,30 @@ export class EVMController {
validatePollRequest(req);

const currentBlock = await ethereumish.getCurrentBlockNumber();
const txData = await ethereumish.getTransaction(req.txHash);
let txData = await ethereumish.getTransaction(req.txHash);
let txBlock, txReceipt, txStatus;
if (!txData) {
// tx not found, didn't reach the mempool or it never existed
txBlock = -1;
txReceipt = null;
txStatus = -1;
} else {
const MAX_RETRIES = 3;
const RETRY_DELAY_MS = 1000;
let retryCount = 0;

while (retryCount < MAX_RETRIES) {
await new Promise(resolve => setTimeout(resolve, RETRY_DELAY_MS));
txData = await ethereumish.getTransaction(req.txHash);
if (txData) break;
retryCount++;
}

if (!txData) {
// tx not found after retries
logger.info(`Transaction ${req.txHash} not found in mempool or does not exist after ${MAX_RETRIES} retries.`);
txBlock = -1;
txReceipt = null;
txStatus = -1;
}
}

if (txData) {
txReceipt = await ethereumish.getTransactionReceipt(req.txHash);
if (txReceipt === null) {
// tx is in the mempool
Expand Down Expand Up @@ -195,7 +211,7 @@ export class EVMController {
txBlock,
txStatus,
txData: toEthereumTransactionResponse(txData),
txReceipt: toEthereumTransactionReceipt(txReceipt),
txReceipt: toEthereumTransactionReceipt(txReceipt || null),
};
}

Expand Down
50 changes: 50 additions & 0 deletions src/chains/solana/solana.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { TokenListType } from '../../services/base';
import { ConfigManagerV2 } from '../../services/config-manager-v2';
interface NetworkConfig {
name: string;
nodeURLs: string;
tokenListType: TokenListType;
tokenListSource: string;
nativeCurrencySymbol: string;
}

export interface Config {
network: NetworkConfig;
tokenProgram: string;
transactionLamports: number;
lamportsToSol: number;
timeToLive: number;
}

export function getSolanaConfig(
chainName: string,
networkName: string
): Config {
return {
network: {
name: networkName,
nodeURLs: ConfigManagerV2.getInstance().get(
chainName + '.networks.' + networkName + '.nodeURLs'
),
tokenListType: ConfigManagerV2.getInstance().get(
chainName + '.networks.' + networkName + '.tokenListType'
),
tokenListSource: ConfigManagerV2.getInstance().get(
chainName + '.networks.' + networkName + '.tokenListSource'
),
nativeCurrencySymbol: ConfigManagerV2.getInstance().get(
chainName + '.networks.' + networkName + '.nativeCurrencySymbol'
),
},
tokenProgram: ConfigManagerV2.getInstance().get(
chainName + '.tokenProgram'
),
transactionLamports: ConfigManagerV2.getInstance().get(
chainName + '.transactionLamports'
),
lamportsToSol: ConfigManagerV2.getInstance().get(
chainName + '.lamportsToSol'
),
timeToLive: ConfigManagerV2.getInstance().get(chainName + '.timeToLive'),
};
}
19 changes: 19 additions & 0 deletions src/chains/solana/solana.constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
export const constants = {
retry: {
all: {
maxNumberOfRetries: 0, // 0 means no retries
delayBetweenRetries: 0, // 0 means no delay (milliseconds)
},
},
timeout: {
all: 0, // 0 means no timeout (milliseconds)
},
parallel: {
all: {
batchSize: 0, // 0 means no batching (group all)
delayBetweenBatches: 0, // 0 means no delay (milliseconds)
},
},
};

export default constants;
75 changes: 75 additions & 0 deletions src/chains/solana/solana.controllers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// import { tokenValueToString } from '../../services/base';
import {
BalanceRequest,
TokensRequest,
PollRequest,
} from '../../network/network.requests';
import { CustomTransactionResponse } from '../../services/common-interfaces';
import {
HttpException,
LOAD_WALLET_ERROR_CODE,
LOAD_WALLET_ERROR_MESSAGE,
} from '../../services/error-handler';
import { TokenInfo } from '../ethereum/ethereum-base';

import { Keypair, TransactionResponse } from '@solana/web3.js';
import { Solanaish } from './solana';
import { getNotNullOrThrowError } from './solana.helpers';

export class SolanaController {

static async balances(solanaish: Solanaish, req: BalanceRequest) {
let wallet: Keypair;
try {
wallet = await solanaish.getWallet(req.address);
} catch (err) {
throw new HttpException(
500,
LOAD_WALLET_ERROR_MESSAGE + err,
LOAD_WALLET_ERROR_CODE
);
}

const balances = await solanaish.getBalance(wallet, req.tokenSymbols);

return { balances };
}

static async poll(solanaish: Solanaish, req: PollRequest) {
const currentBlock = await solanaish.getCurrentBlockNumber();
const txData = getNotNullOrThrowError<TransactionResponse>(
await solanaish.getTransaction(req.txHash as any)
);
const txStatus = await solanaish.getTransactionStatusCode(txData);

return {
currentBlock: currentBlock,
txHash: req.txHash,
txBlock: txData.slot,
txStatus: txStatus,
txData: txData as unknown as CustomTransactionResponse | null,
};
}

static async getTokens(solanaish: Solanaish, req: TokensRequest) {
let tokens: TokenInfo[] = [];

if (!req.tokenSymbols) {
tokens = solanaish.storedTokenList;
} else {
for (const symbol of req.tokenSymbols as string[]) {
const token = solanaish.getTokenBySymbol(symbol);
if (token) {
tokens.push(token);
}
}
}

return { tokens };
}
}

export const balances = SolanaController.balances;
export const poll = SolanaController.poll;
export const getTokens = SolanaController.getTokens;
export let priorityFeeMultiplier: number = 1;
Loading
Loading