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

feat: oracle price queries #BE-33 #1

Merged
merged 11 commits into from
Oct 10, 2023
Merged
Show file tree
Hide file tree
Changes from 8 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
3 changes: 3 additions & 0 deletions .commitlintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": ["@commitlint/config-conventional"]
}
2 changes: 2 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules
dist
55 changes: 55 additions & 0 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
module.exports = {
env: {
browser: true,
es2021: true,
},
extends: 'airbnb-base',
overrides: [
{
env: {
node: true,
},
files: [
'.eslintrc.{js,cjs}',
],
parserOptions: {
sourceType: 'script',
},
},
],
settings: {
'import/resolver': {
// Loads tsconfig from root
typescript: {},
},
},
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaVersion: 'latest',
parser: '@typescript-eslint/parser',
sourceType: 'module',
},
plugins: [
'@typescript-eslint',
],
rules: {
// So we don't have to specify file extensions on this types
'import/extensions': ['error', 'always', {
js: 'never',
mjs: 'never',
jsx: 'never',
ts: 'never',
tsx: 'never',
}],
// Ignore base rule for unused inputs in declarations,
// allows us to have unused vars in type declarations
'no-unused-vars': 0,
// enums showing they have already been used
'no-shadow': 'off',
'@typescript-eslint/no-shadow': 'error',
// Allow non default exports:
'import/prefer-default-export': 'off',
// importing from vitest for test dependencies
'import/no-extraneous-dependencies': ['error', { devDependencies: ['**/*.test.ts', '**/*.test.tsx'] }],
},
};
47 changes: 47 additions & 0 deletions .github/workflows/javascript.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: Tests, Typecheck, Eslint

on: [push]

jobs:
tests:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Node Version
uses: actions/setup-node@v3
with:
node-version: 18.16.0
cache: yarn
- name: Install Dependencies
run: yarn install --frozen-lockfile
- name: Test
run: yarn test
typecheck:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Node Version
uses: actions/setup-node@v3
with:
node-version: 18.16.0
cache: yarn
- name: Install Dependencies
run: yarn install --frozen-lockfile
- name: Type-Check
run: yarn typecheck
eslint:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Node Version
uses: actions/setup-node@v3
with:
node-version: 18.16.0
cache: yarn
- name: Install Dependencies
run: yarn install --frozen-lockfile
- name: Eslint-Check
run: yarn lint
23 changes: 23 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# IDEs & Logs
*.log
.idea
.nyc_output
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

# Vite default settings
node_modules
.DS_Store
dist
dist-ssr
*.local

# Vitest
coverage

# We use yarn
package-lock.json
16 changes: 15 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,15 @@
# shadejs
# shadejs
Library for interacting with Shade smart contracts

## Yarn
Yarn is the default package manager.

## Build
```
$ yarn
```

## Test
```
$ yarn test
```
26 changes: 26 additions & 0 deletions lefthook.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# To make sure everything is fine before reaching github
#

commit-msg:
parallel: true
commands:
# make sure we are using conventional commits
# https://www.conventionalcommits.org/en/v1.0.0
lint-commit-msg:
run: npx commitlint --edit

pre-commit:
parallel: true
commands:
type-check:
glob: '*.{ts,tsx}'
run: yarn typecheck
eslint:
glob: "*.{js,ts,vue}"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't need vue here

run: yarn lint:fix {staged_files}

pre-push:
parallel: true
commands:
test:
run: yarn test
41 changes: 41 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"name": "shadejs",
"version": "0.0.1",
"author": "Secure Secrets",
"license": "MIT",
"scripts": {
"commitizen": "cz",
"lint": "eslint \"**/*.{ts,js}\"",
"lint:fix": "eslint \"**/*.{vue,ts,js}\" --fix",
"test": "vitest --run",
"test:coverage": "vitest run --coverage",
"test:watch": "vitest watch",
"typecheck": "tsc --noEmit"
},
"type": "module",
"dependencies": {
"@arkweid/lefthook": "^0.7.7",
"@commitlint/cli": "^17.7.2",
"@commitlint/config-conventional": "^17.7.0",
"bignumber.js": "^9.1.0",
"cz-conventional-changelog": "^3.3.0",
"eslint": "^8.51.0",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-import-resolver-typescript": "^3.6.1",
"eslint-plugin-import": "^2.28.1",
"rxjs": "^7.8.1",
"secretjs": "^1.9.3",
"typescript": "^5.2.2",
"vite": "^4.4.11",
"vitest": "^0.34.6"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^6.7.4",
"@typescript-eslint/parser": "^6.7.4"
},
"config": {
"commitizen": {
"path": "./node_modules/cz-conventional-changelog"
}
}
}
77 changes: 77 additions & 0 deletions src/client/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import {
of,
defer,
tap,
first,
} from 'rxjs';
import {
SecretNetworkClient,
} from 'secretjs';
import { createFetchClient } from '~/client/services/createFetch';
import { WalletAccount } from '~/types/wallet';
import {
DEFAULT_SECRET_LCD_ENDPOINT,
SECRET_MAINNET_CHAIN_ID,
} from '~/config';

/**
* Create and returns Secret Network client
* @param walletAccount not required for making public queries
*/
const getSecretNetworkClient$ = ({
walletAccount,
lcdEndpoint,
chainId,
}:{
walletAccount?: WalletAccount
lcdEndpoint: string,
chainId: string,
}) => createFetchClient(defer(
() => {
if (walletAccount) {
return of(new SecretNetworkClient({
url: lcdEndpoint,
wallet: walletAccount.signer,
walletAddress: walletAccount.walletAddress,
chainId,
encryptionUtils: walletAccount.encryptionUtils,
encryptionSeed: walletAccount.encryptionSeed,
}));
}
return of(new SecretNetworkClient({
url: lcdEndpoint,
chainId,
}));
},
));

let activeClient: SecretNetworkClient | undefined;

/**
* Gets the active query client. If one does not exist, initialize it and stores it for
* future use.
* @param lcdEndpoint uses a default mainnet endpoint if one is not provided
* @param chainId uses a default mainnet chainID if one is not provided
*/
function getActiveQueryClient$(lcdEndpoint?: string, chainId?: string) {
// check if a client exists for a given chain and return it if it exists
if (activeClient) {
return of(activeClient);
}

// if no endpoint/chainId is provided, assume mainnet and use defaults
return getSecretNetworkClient$({
lcdEndpoint: lcdEndpoint ?? DEFAULT_SECRET_LCD_ENDPOINT,
chainId: chainId ?? SECRET_MAINNET_CHAIN_ID,
}).pipe(
tap((client) => {
activeClient = client;
}),
first(),
);
}

export {
getSecretNetworkClient$,
getActiveQueryClient$,
};
58 changes: 58 additions & 0 deletions src/client/services/clientServices.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import {
first,
defer,
from,
tap,
} from 'rxjs';
import { SecretNetworkClient } from 'secretjs';
import { createFetchClient } from '~/client/services/createFetch';
import { identifyQueryResponseErrors } from '~/errors';

/**
* query the contract using a secret client
*/
const secretClientContractQuery$ = ({
queryMsg,
client,
contractAddress,
codeHash,
}: {
queryMsg: any,
client: SecretNetworkClient,
contractAddress: string,
codeHash?: string
}) => createFetchClient(defer(
() => from(client.query.compute.queryContract({
contract_address: contractAddress,
code_hash: codeHash,
query: queryMsg,
})),
));

/**
* sets up the service observable for calling the querying with the secret client
*/
const sendSecretClientContractQuery$ = ({
queryMsg,
client,
contractAddress,
codeHash,
}: {
queryMsg: any,
client: SecretNetworkClient,
contractAddress: string,
codeHash?: string
}) => secretClientContractQuery$({
queryMsg,
client,
contractAddress,
codeHash,
})
.pipe(
tap((response) => identifyQueryResponseErrors(response)),
first(),
);

export {
sendSecretClientContractQuery$,
};
33 changes: 33 additions & 0 deletions src/client/services/createFetch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import {
catchError,
Observable,
of,
switchMap,
first,
} from 'rxjs';

function createFetchClient<T>(data$: Observable<T>) {
return data$.pipe(
switchMap((response) => of(response)),
first(),
catchError((err) => {
throw err;
}),
);
}

function createFetch(data$: Observable<Response>) {
return data$.pipe(
switchMap(async (response) => {
if (response.ok) {
return response.json();
}
throw new Error('Fetch Error');
}),
);
}

export {
createFetchClient,
createFetch,
};
Loading