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

Eng 1889 as a user i want to list a token on convergence rfq #292

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
19 changes: 19 additions & 0 deletions packages/cli/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,24 @@
# @convergence-rfq/cli

## 6.6.1

### Patch Changes

- Add clear cache before finding a vacant base asset index
- Updated dependencies
- @convergence-rfq/[email protected]

## 6.6.0

### Minor Changes

- Add user asset functionality, remove duplicated operation to change the existing base asset, add logic to automatically find a vacant base asset index

### Patch Changes

- Updated dependencies
- @convergence-rfq/[email protected]

## 6.5.0

### Minor Changes
Expand Down
4 changes: 2 additions & 2 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@convergence-rfq/cli",
"description": "Official Convergence CLI",
"version": "6.5.0",
"version": "6.6.1",
"license": "MIT",
"publishConfig": {
"access": "public"
Expand Down Expand Up @@ -47,7 +47,7 @@
"cli": "ts-node src/index.ts"
},
"dependencies": {
"@convergence-rfq/sdk": "6.5.0",
"@convergence-rfq/sdk": "6.6.1",
"@solana/web3.js": "^1.87.6",
"@types/cookie": "^0.5.1",
"commander": "^10.0.0"
Expand Down
4 changes: 2 additions & 2 deletions packages/cli/scripts/bootstrap.sh
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ convergence risk-engine set-risk-categories-info --new-value="0.05,1.2,0.06,0.6,
convergence risk-engine set-risk-categories-info --new-value="0.05,2.4,0.08,0.8,0.16,1.2,0.32,1.6,0.48,2.0,0.8,2.4,1.2,2.8" --category=high --rpc-endpoint=$RPC_ENDPOINT
convergence risk-engine set-risk-categories-info --new-value="0.05,5.0,0.10,1.0,0.20,1.5,0.40,2.0,0.60,2.5,1.0,3.0,1.5,3.5" --category=very-high --rpc-endpoint=$RPC_ENDPOINT

convergence protocol add-base-asset --ticker=BTC --oracle-address=$BTC_ORACLE_ADDRESS --oracle-source=switchboard --rpc-endpoint=$RPC_ENDPOINT
convergence protocol add-base-asset --ticker=SOL --oracle-address=$SOL_ORACLE_ADDRESS --oracle-source=switchboard --rpc-endpoint=$RPC_ENDPOINT
convergence protocol add-base-asset --index=0 --ticker=BTC --oracle-address=$BTC_ORACLE_ADDRESS --oracle-source=switchboard --rpc-endpoint=$RPC_ENDPOINT
convergence protocol add-base-asset --index=1 --ticker=SOL --oracle-address=$SOL_ORACLE_ADDRESS --oracle-source=switchboard --rpc-endpoint=$RPC_ENDPOINT

convergence protocol register-mint --mint=$BTC_MINT --base-asset-index=0 --rpc-endpoint=$RPC_ENDPOINT
convergence protocol register-mint --mint=$SOL_MINT --base-asset-index=1 --rpc-endpoint=$RPC_ENDPOINT
Expand Down
157 changes: 58 additions & 99 deletions packages/cli/src/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { PublicKey, LAMPORTS_PER_SOL } from '@solana/web3.js';
import {
token,
devnetAirdrops,
PriceOracle,
SpotLegInstrument,
SpotQuoteInstrument,
isRiskCategory,
Expand Down Expand Up @@ -116,6 +115,7 @@ export const initializeProtocol = async (opts: Opts) => {
protocolMakerFee: opts.protocolMakerFee,
settlementTakerFee: opts.settlementTakerFee,
settlementMakerFee: opts.settlementMakerFee,
addAssetFee: Number(opts.addAssetFee),
}),
opts
);
Expand Down Expand Up @@ -176,31 +176,16 @@ export const addPrintTradeProvider = async (opts: Opts) => {
export const addBaseAsset = async (opts: Opts) => {
const cvg = await createCvg(opts);
try {
const baseAssets = await expirationRetry(
() => cvg.protocol().getBaseAssets(),
opts
);
const { oracleSource } = opts;

let priceOracle: PriceOracle;
if (oracleSource === 'in-place') {
priceOracle = {
source: 'in-place',
price: opts.oraclePrice,
};
} else {
priceOracle = {
source: oracleSource,
address: new PublicKey(opts.oracleAddress),
};
}

const { response } = await cvg.protocol().addBaseAsset({
authority: cvg.rpc().getDefaultFeePayer(),
index: baseAssets.length,
index: opts.index && Number(opts.index),
ticker: opts.ticker,
riskCategory: opts.riskCategory,
priceOracle,
oracleSource: opts.oracleSource,
inPlacePrice: opts.inPlacePrice && Number(opts.inPlacePrice),
pythOracle: opts.pythAddress && new PublicKey(opts.pythAddress),
switchboardOracle:
opts.switchboardAddress && new PublicKey(opts.switchboardAddress),
});
logResponse(response);
} catch (e) {
Expand All @@ -219,29 +204,32 @@ export const changeBaseAssetParameters = async (opts: Opts) => {
switchboardOracle: switchboardOracleOpts,
pythOracle: pythOracleOpts,
inPlacePrice: inPlacePriceOpts,
strict: strictOpts,
}: {
index: number;
index: string;
enabled?: string;
riskCategory?: string;
oracleSource?: string;
switchboardOracle?: string;
pythOracle?: string;
inPlacePrice?: number;
inPlacePrice?: string;
strict?: string;
} = opts;

let enabled;
switch (enabledOpts) {
case undefined:
break;
case 'true':
enabled = true;
break;
case 'false':
enabled = false;
break;
default:
throw new Error('Unrecognized enabled parameter!');
}
const parseBool = (value: string | undefined, name: string) => {
switch (value) {
case undefined:
return undefined;
case 'true':
return true;
case 'false':
return false;
default:
throw new Error(`Unrecognized ${name} parameter!`);
}
};
const enabled = parseBool(enabledOpts, 'enabled');
const strict = parseBool(strictOpts, 'strict');

if (riskCategory !== undefined && !isRiskCategory(riskCategory)) {
throw new Error('Unrecognized risk category parameter!');
Expand All @@ -266,55 +254,22 @@ export const changeBaseAssetParameters = async (opts: Opts) => {
}

let inPlacePrice;
if (inPlacePriceOpts === -1) {
inPlacePrice = null;
} else if (typeof inPlacePriceOpts === 'number') {
inPlacePrice = inPlacePriceOpts;
if (inPlacePriceOpts !== undefined) {
inPlacePrice = Number(inPlacePriceOpts);
if (inPlacePrice === -1) {
inPlacePrice = null;
}
}

const { response } = await cvg.protocol().changeBaseAssetParameters({
index,
index: Number(index),
enabled,
riskCategory,
oracleSource,
switchboardOracle,
pythOracle,
inPlacePrice,
});
logResponse(response);
} catch (e) {
logError(e);
}
};

export const updateBaseAsset = async (opts: Opts) => {
const cvg = await createCvg(opts);
const {
enabled,
index,
oracleSource,
oraclePrice,
oracleAddress,
riskCategory,
} = opts;
const enabledArg = enabled === 'true' ? true : false;
if (!oraclePrice && !oracleAddress) {
throw new Error('Either oraclePrice or oracleAddress must be provided');
}
if (!riskCategory) {
throw new Error('riskCategory must be provided');
}
try {
const { response } = await cvg.protocol().updateBaseAsset({
authority: cvg.rpc().getDefaultFeePayer(),
enabled: enabledArg,
index,
priceOracle: {
source: oracleSource,
price: oraclePrice,
address: oracleAddress ? new PublicKey(opts.oracleAddress) : undefined,
},
riskCategory,
strict,
});
logResponse(response);
} catch (e) {
Expand All @@ -341,6 +296,23 @@ export const registerMint = async (opts: Opts) => {
}
};

export const addUserAsset = async (opts: Opts) => {
const cvg = await createCvg(opts);
try {
const { response } = await expirationRetry(
() =>
cvg.protocol().addUserAsset({
mint: new PublicKey(opts.mint),
ticker: opts.ticker,
}),
opts
);
logResponse(response);
} catch (e) {
logError(e);
}
};

export const getRegisteredMints = async (opts: Opts) => {
const cvg = await createCvg(opts);
try {
Expand Down Expand Up @@ -546,14 +518,6 @@ export const addBaseAssetsFromJupiter = async (opts: Opts) => {
!registerMintAddresses.includes(t.address.toString())
);

let baseAssetIndexToStart;
if (baseAssets?.length > 0) {
baseAssetIndexToStart = Math.max(...baseAssets.map((b) => b.index)) + 1;
} else {
baseAssetIndexToStart = 0;
}
// eslint-disable-next-line no-console
console.log('last baseAssetIndex', baseAssetIndexToStart - 1);
for (const token of jupTokensToAdd) {
try {
const coingeckoId = token?.extensions?.coingeckoId;
Expand Down Expand Up @@ -589,23 +553,19 @@ export const addBaseAssetsFromJupiter = async (opts: Opts) => {
console.log('Adding token:', token.symbol, 'with price:', tokenPrice);

//mint should already exists on mainnet
const addBaseAssetTxBuilder = addBaseAssetBuilder(cvg, {
authority: cvg.rpc().getDefaultFeePayer(),
ticker: token.symbol,
riskCategory: 'high',
index: baseAssetIndexToStart,
priceOracle: {
source: 'in-place',
price: tokenPrice,
},
});
const { builder: addBaseAssetTxBuilder, baseAssetIndex } =
await addBaseAssetBuilder(cvg, {
authority: cvg.rpc().getDefaultFeePayer(),
ticker: token.symbol,
riskCategory: 'high',
oracleSource: 'in-place',
inPlacePrice: tokenPrice,
});
// eslint-disable-next-line no-console
console.log('Adding base asset:', token.symbol);
// eslint-disable-next-line no-console
console.log('current baseAssetIndex:', baseAssetIndexToStart);
const registerMintTxBuilder = await registerMintBuilder(cvg, {
mint: new PublicKey(token.address),
baseAssetIndex: baseAssetIndexToStart,
baseAssetIndex,
});

const mergedTxBuiler = TransactionBuilder.make()
Expand All @@ -623,7 +583,6 @@ export const addBaseAssetsFromJupiter = async (opts: Opts) => {
if (signatureStatus && signatureStatus === commitment) {
// eslint-disable-next-line no-console
console.log('Transaction confirmed');
baseAssetIndexToStart++;
}
} catch (e) {
// eslint-disable-next-line no-console
Expand Down
Loading
Loading