Skip to content

Commit

Permalink
add utils
Browse files Browse the repository at this point in the history
  • Loading branch information
vasemkin committed Jan 30, 2024
1 parent 3e41db3 commit 683f233
Show file tree
Hide file tree
Showing 19 changed files with 522 additions and 222 deletions.
6 changes: 6 additions & 0 deletions apps/ddca/src/app/app.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { Strategy } from '@jupjup/constants'

export type AppConfig = {
tradingStrategy: Strategy
startingFundsUSDC: string
}
17 changes: 7 additions & 10 deletions apps/ddca/src/app/app.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,13 @@ describe('AppService', () => {

describe.only('getData', () => {
it('should get data from jupiter client', async () => {
const res = await getQuote({
inputMint: SOLANA_NATIVE_SOL_ADDRESS,
outputMint: SOLANA_WEN_ADDRESS,
amount: '100000',
})

console.log({ res })

// expect(
// ).not.toThrow
expect(
await getQuote({
inputMint: SOLANA_NATIVE_SOL_ADDRESS,
outputMint: SOLANA_WEN_ADDRESS,
amount: '100000',
}),
).not.toThrow
})
})
})
1 change: 1 addition & 0 deletions libs/constants/src/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './lib/solana'
export * from './lib/strategies'
4 changes: 4 additions & 0 deletions libs/constants/src/lib/strategies.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export enum Strategy {
PING_PONG,
DDCA,
}
419 changes: 209 additions & 210 deletions libs/jupiter-client/src/lib/client.ts

Large diffs are not rendered by default.

30 changes: 30 additions & 0 deletions libs/utils/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"extends": ["../../.eslintrc.json"],
"ignorePatterns": ["!**/*"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"rules": {}
},
{
"files": ["*.ts", "*.tsx"],
"rules": {}
},
{
"files": ["*.js", "*.jsx"],
"rules": {}
},
{
"files": ["*.json"],
"parser": "jsonc-eslint-parser",
"rules": {
"@nx/dependency-checks": [
"error",
{
"ignoredFiles": ["{projectRoot}/vite.config.{js,ts,mjs,mts}"]
}
]
}
}
]
}
11 changes: 11 additions & 0 deletions libs/utils/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# utils

This library was generated with [Nx](https://nx.dev).

## Building

Run `nx build utils` to build the library.

## Running unit tests

Run `nx test utils` to execute the unit tests via [Jest](https://jestjs.io).
11 changes: 11 additions & 0 deletions libs/utils/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/* eslint-disable */
export default {
displayName: 'utils',
preset: '../../jest.preset.js',
testEnvironment: 'node',
transform: {
'^.+\\.[tj]s$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }],
},
moduleFileExtensions: ['ts', 'js', 'html'],
coverageDirectory: '../../coverage/libs/utils',
}
8 changes: 8 additions & 0 deletions libs/utils/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "@jupjup/utils",
"version": "0.0.1",
"dependencies": {},
"main": "./index.js",
"module": "./index.mjs",
"typings": "./index.d.ts"
}
27 changes: 27 additions & 0 deletions libs/utils/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"name": "utils",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "libs/utils/src",
"projectType": "library",
"targets": {
"build": {
"executor": "@nx/vite:build",
"outputs": ["{options.outputPath}"],
"options": {
"outputPath": "dist/libs/utils"
}
},
"lint": {
"executor": "@nx/eslint:lint",
"outputs": ["{options.outputFile}"]
},
"test": {
"executor": "@nx/jest:jest",
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
"options": {
"jestConfig": "libs/utils/jest.config.ts"
}
}
},
"tags": []
}
1 change: 1 addition & 0 deletions libs/utils/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './lib/utils'
30 changes: 30 additions & 0 deletions libs/utils/src/lib/slp.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { parseUSDC } from './spl'

describe('parseUSDC', () => {
it('should correctly parse a whole number amount', () => {
expect(parseUSDC(10)).toBe('10000000')
})

it('should correctly parse a decimal amount', () => {
expect(parseUSDC(10.5)).toBe('10500000')
})

it('should correctly handle zero', () => {
expect(parseUSDC(0)).toBe('0')
})

it('should handle very large numbers', () => {
expect(parseUSDC(123456789.123456)).toBe('123456789123456')
})

it('should throw an error for negative numbers', () => {
expect(() => parseUSDC(-1)).toThrow('Invalid USDC amount')
})

it('should throw an error for non-numeric inputs', () => {
// @ts-ignore
expect(() => parseUSDC('abc')).toThrow('Invalid USDC amount')
// @ts-ignore
expect(() => parseUSDC(undefined)).toThrow('Invalid USDC amount')
})
})
85 changes: 85 additions & 0 deletions libs/utils/src/lib/spl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { SOLANA_USDC_ADDRESS } from '@jupjup/constants'
import { getQuote, QuoteResponse } from '@jupjup/jupiter-client'

/**
* Calculates the amount of SPL Token that can be received for a given amount of USDC.
*
* This function calls the `getQuote` function from a DEX module to fetch the current
* exchange rate between USDC and the specified SPL Token. It then calculates and returns
* the amount of SPL Token that would be received for the specified amount of USDC.
*
* @param {number} usdcAmount - The amount of USDC to be traded. This should be a positive number.
* @param {string} usdcMint - The mint address for USDC. This is used to specify the type of USDC being traded.
* @param {string} splTokenMint - The mint address for the SPL Token to be received. This identifies which SPL Token is being exchanged for.
* @returns {Promise<number>} A promise that resolves to the amount of SPL Token that can be received.
*
* @example
* // Example usage
* calculateSPLTokenAmount(100, 'USDC_Mint_Address', 'SPL_Token_Mint_Address')
* .then(amount => console.log(`You will receive ${amount} SPL Tokens`))
* .catch(error => console.error(error));
*
* @throws {Error} Throws an error if the `getQuote` function call fails or if the quote response is invalid.
*
* Note: This function assumes that the `getQuote` function and `QuoteResponse` interface are correctly implemented
* and available in the scope where this function is used. The function also assumes that the DEX API returns the
* 'outAmount' as a string which needs to be parsed into a number.
*/
export const calculateSPLTokenAmount = async (
usdcAmount: string,
splTokenMint: string,
): Promise<number> => {
// Call getQuote with USDC amount and mint addresses
let quoteResponse: QuoteResponse
try {
quoteResponse = await getQuote({
inputMint: SOLANA_USDC_ADDRESS,
outputMint: splTokenMint,
amount: usdcAmount,
})
} catch (error) {
console.error('Error getting quote: ', error)
throw new Error('Unable to get quote')
}

// Check if the response is valid
if (!quoteResponse || !quoteResponse.outAmount) {
throw new Error('Invalid quote response')
}

// Convert outAmount to number (assuming it's a string in the response)
const splTokenAmount = parseFloat(quoteResponse.outAmount)

// You can add additional checks or logic here if needed

return splTokenAmount
}

/**
* Parses a decimal USDC amount to its string representation in the smallest unit.
*
* USDC, like many tokens on Solana, uses 6 decimal places. This function converts
* a decimal USDC value into the equivalent amount in the smallest unit, represented
* as a string. For example, an input of 10.5 will be converted to '10500000'.
*
* @param {number} usdcAmount - The decimal USDC amount.
* @returns {string} The string representation of the USDC amount in the smallest unit.
*
* @example
* // Example usage
* const amount = parseUSDC(10.5); // '10500000'
*
* @throws {Error} Throws an error if the input is not a valid number.
*/
export const parseUSDC = (usdcAmount: number): string => {
if (typeof usdcAmount === 'undefined' || isNaN(usdcAmount) || usdcAmount < 0) {
throw new Error('Invalid USDC amount')
}

const decimals = 6 // USDC has 6 decimal places
const smallestUnitMultiplier = 10 ** decimals
const smallestUnitAmount = usdcAmount * smallestUnitMultiplier

// Use BigInt to avoid precision issues with very large numbers
return BigInt(smallestUnitAmount).toString()
}
22 changes: 22 additions & 0 deletions libs/utils/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"module": "commonjs",
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitOverride": true,
"noPropertyAccessFromIndexSignature": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true
},
"files": [],
"include": [],
"references": [
{
"path": "./tsconfig.lib.json"
},
{
"path": "./tsconfig.spec.json"
}
]
}
10 changes: 10 additions & 0 deletions libs/utils/tsconfig.lib.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"declaration": true,
"types": ["node", "vite/client"]
},
"include": ["src/**/*.ts"],
"exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"]
}
9 changes: 9 additions & 0 deletions libs/utils/tsconfig.spec.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"module": "commonjs",
"types": ["jest", "node"]
},
"include": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts", "src/**/*.d.ts"]
}
47 changes: 47 additions & 0 deletions libs/utils/vite.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/// <reference types='vitest' />
import { defineConfig } from 'vite'
import dts from 'vite-plugin-dts'
import * as path from 'path'
import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin'

export default defineConfig({
root: __dirname,
cacheDir: '../../node_modules/.vite/libs/utils',

plugins: [
nxViteTsPaths(),
dts({
entryRoot: 'src',
tsConfigFilePath: path.join(__dirname, 'tsconfig.lib.json'),
skipDiagnostics: true,
}),
],

// Uncomment this if you are using workers.
// worker: {
// plugins: [ nxViteTsPaths() ],
// },

// Configuration for building your library.
// See: https://vitejs.dev/guide/build.html#library-mode
build: {
outDir: '../../dist/libs/utils',
reportCompressedSize: true,
commonjsOptions: {
transformMixedEsModules: true,
},
lib: {
// Could also be a dictionary or array of multiple entry points.
entry: 'src/index.ts',
name: 'utils',
fileName: 'index',
// Change this to the formats you want to support.
// Don't forget to update your package.json as well.
formats: ['es', 'cjs'],
},
rollupOptions: {
// External packages that should not be bundled into your library.
external: [],
},
},
})
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"prepare": "pnpm nx run jupiter-client:generate",
"test": "pnpm nx run-many -t test",
"test:app": "pnpm nx test ddca --verbose",
"test:utils": "pnpm nx test utils --verbose",
"test:jup-client": "pnpm nx test jupiter-client --verbose"
},
"private": true,
Expand Down
5 changes: 3 additions & 2 deletions tsconfig.base.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,16 @@
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"importHelpers": true,
"target": "es2015",
"target": "ESNext",
"module": "esnext",
"lib": ["es2020", "dom"],
"skipLibCheck": true,
"skipDefaultLibCheck": true,
"baseUrl": ".",
"paths": {
"@jupjup/constants": ["libs/constants/src/index.ts"],
"@jupjup/jupiter-client": ["libs/jupiter-client/src/index.ts"]
"@jupjup/jupiter-client": ["libs/jupiter-client/src/index.ts"],
"@jupjup/utils": ["libs/utils/src/index.ts"]
}
},
"exclude": ["node_modules", "tmp"]
Expand Down

0 comments on commit 683f233

Please sign in to comment.