diff --git a/.github/README.md b/.github/README.md new file mode 100644 index 0000000..b8fe50c --- /dev/null +++ b/.github/README.md @@ -0,0 +1,81 @@ +# GitHub Actions + +This directory contains GitHub Actions workflows for building and publishing the CCXT library. + +## Workflows + +### Build and Test (`build.yml`) +- Runs on pull requests and pushes to main/master branches +- Builds the project using TypeScript, Webpack, and Rollup +- Verifies that all build artifacts are created successfully +- Does not publish to NPM + +### Build and Publish (`publish.yml`) +- Runs when a new version tag is pushed (e.g., `v0.0.4`) +- Verifies that the tag version matches the package.json version +- Builds the project and all bundles +- Publishes the package to NPM + +## Setup + +### NPM Token Setup + +To enable automatic publishing to NPM, you need to set up an NPM authentication token: + +1. **Create an NPM Access Token:** + - Go to [npmjs.com](https://www.npmjs.com) and log in + - Navigate to your profile settings + - Go to "Access Tokens" section + - Click "Generate New Token" + - Select "Automation" token type + - Copy the generated token + +2. **Add the Token to GitHub Secrets:** + - Go to your GitHub repository + - Navigate to Settings → Secrets and variables → Actions + - Click "New repository secret" + - Name: `NPM_TOKEN` + - Value: Paste your NPM access token + - Click "Add secret" + +### Publishing Process + +1. **Prepare for Release:** + - Update the version in `package.json` + - Commit your changes + - Push to the repository + +2. **Create and Push Version Tag:** + ```bash + git tag v0.0.4 + git push origin v0.0.4 + ``` + + Or create the tag via GitHub: + - Go to GitHub repository → Releases + - Click "Create a new release" + - Tag version (e.g., `v0.0.4`) + - Write release notes + - Click "Publish release" + +3. **Automatic Publishing:** + - The `publish.yml` workflow will automatically trigger when the tag is pushed + - It will verify the version matches package.json + - Build the project and publish to NPM + - Check the Actions tab to monitor the process + +## Build Process + +The build process includes: + +1. **TypeScript Compilation:** `npm run build` +2. **Browser Bundle:** Webpack creates `dist/ccxt.browser.js` +3. **CommonJS Bundle:** Rollup creates `dist/cjs/` directory +4. **Minified Bundle:** Production webpack build + +## Troubleshooting + +- **Build Failures:** Check the Actions tab for detailed error logs +- **NPM Publishing Issues:** Verify the NPM_TOKEN secret is correctly set +- **Version Conflicts:** The workflow will automatically fail if the tag version doesn't match package.json version +- **Tag Format:** Ensure tags follow the format `v*` (e.g., `v0.0.4`, `v1.2.3`) \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..8179e8f --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,40 @@ +name: Build and Test + +on: + pull_request: + branches: [ main, master ] + push: + branches: [ main, master ] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '18' + + - name: Install dependencies + run: npm ci + + - name: Build project + run: npm run build + + - name: Build browser bundle + run: npx webpack --config webpack.config.js + + - name: Build CommonJS bundle + run: npx rollup --config rollup.config.js + + - name: Create minified browser bundle + run: npx webpack --config webpack.config.js --mode production + + - name: Verify build artifacts + run: | + ls -la dist/ + echo "Build completed successfully!" \ No newline at end of file diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..29be283 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,59 @@ +name: Build and Publish to NPM + +on: + push: + tags: + - 'v*' + +jobs: + build-and-publish: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '18' + registry-url: 'https://registry.npmjs.org' + + - name: Install dependencies + run: npm ci + + - name: Verify version matches tag + run: | + # Extract version from tag (remove 'v' prefix) + TAG_VERSION=${GITHUB_REF#refs/tags/} + TAG_VERSION=${TAG_VERSION#v} + + # Get version from package.json + PACKAGE_VERSION=$(node -p "require('./package.json').version") + + echo "Tag version: $TAG_VERSION" + echo "Package version: $PACKAGE_VERSION" + + if [ "$TAG_VERSION" != "$PACKAGE_VERSION" ]; then + echo "Error: Tag version ($TAG_VERSION) does not match package.json version ($PACKAGE_VERSION)" + exit 1 + fi + + echo "Version verification passed!" + + - name: Build project + run: npm run build + + - name: Build browser bundle + run: npx webpack --config webpack.config.js + + - name: Build CommonJS bundle + run: npx rollup --config rollup.config.js + + - name: Create minified browser bundle + run: npx webpack --config webpack.config.js --mode production + + - name: Publish to NPM + run: npm publish + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} \ No newline at end of file diff --git a/.gitignore b/.gitignore index 860e71a..a8c5316 100644 --- a/.gitignore +++ b/.gitignore @@ -18,7 +18,6 @@ tmp/ coverage .nyc_output travis-keys.sh -exchanges.json ccxt.sublime-workspace .idea yarn.lock diff --git a/exchanges.json b/exchanges.json new file mode 100644 index 0000000..dd432e5 --- /dev/null +++ b/exchanges.json @@ -0,0 +1,184 @@ +{ + "ids": [ + "alpaca", + "apex", + "ascendex", + "bequant", + "bigone", + "binance", + "binancecoinm", + "binanceus", + "binanceusdm", + "bingx", + "bit2c", + "bitbank", + "bitbns", + "bitfinex", + "bitflyer", + "bitget", + "bithumb", + "bitmart", + "bitmex", + "bitopro", + "bitrue", + "bitso", + "bitstamp", + "bitteam", + "bittrade", + "bitvavo", + "blockchaincom", + "blofin", + "btcalpha", + "btcbox", + "btcmarkets", + "btcturk", + "bybit", + "cex", + "coinbase", + "coinbaseadvanced", + "coinbaseexchange", + "coinbaseinternational", + "coincatch", + "coincheck", + "coinex", + "coinmate", + "coinmetro", + "coinone", + "coinsph", + "coinspot", + "cryptocom", + "cryptomus", + "defx", + "delta", + "deribit", + "derive", + "digifinex", + "ellipx", + "exmo", + "fmfwio", + "gate", + "gateio", + "gemini", + "hashkey", + "hitbtc", + "hollaex", + "htx", + "huobi", + "hyperliquid", + "independentreserve", + "indodax", + "kraken", + "krakenfutures", + "kucoin", + "kucoinfutures", + "latoken", + "lbank", + "luno", + "mercado", + "mexc", + "modetrade", + "myokx", + "ndax", + "novadax", + "oceanex", + "okcoin", + "okx", + "okxus", + "onetrading", + "oxfun", + "p2b", + "paradex", + "paymium", + "phemex", + "poloniex", + "probit", + "timex", + "tokocrypto", + "tradeogre", + "upbit", + "vertex", + "wavesexchange", + "whitebit", + "woo", + "woofipro", + "xt", + "yobit", + "zaif", + "zonda" + ], + "ws": [ + "alpaca", + "apex", + "ascendex", + "bequant", + "binance", + "binancecoinm", + "binanceus", + "binanceusdm", + "bingx", + "bitfinex", + "bitget", + "bithumb", + "bitmart", + "bitmex", + "bitopro", + "bitrue", + "bitstamp", + "bittrade", + "bitvavo", + "blockchaincom", + "blofin", + "bybit", + "cex", + "coinbase", + "coinbaseadvanced", + "coinbaseexchange", + "coinbaseinternational", + "coincatch", + "coincheck", + "coinex", + "coinone", + "cryptocom", + "defx", + "deribit", + "derive", + "exmo", + "gate", + "gateio", + "gemini", + "hashkey", + "hitbtc", + "hollaex", + "htx", + "huobi", + "hyperliquid", + "independentreserve", + "kraken", + "krakenfutures", + "kucoin", + "kucoinfutures", + "lbank", + "luno", + "mexc", + "modetrade", + "myokx", + "ndax", + "okcoin", + "okx", + "okxus", + "onetrading", + "oxfun", + "p2b", + "paradex", + "phemex", + "poloniex", + "probit", + "tradeogre", + "upbit", + "vertex", + "whitebit", + "woo", + "woofipro", + "xt" + ] +} \ No newline at end of file diff --git a/js/src/base/Exchange.d.ts b/js/src/base/Exchange.d.ts index de9f95d..b46ef8b 100644 --- a/js/src/base/Exchange.d.ts +++ b/js/src/base/Exchange.d.ts @@ -59,6 +59,7 @@ export default class Exchange { httpsAgent: any; useVerity: boolean; verityProverUrl: string; + verityMethods: string[]; minFundingAddressLength: Int; substituteCommonCurrencyCodes: boolean; quoteJsonNumbers: boolean; diff --git a/js/src/base/Exchange.js b/js/src/base/Exchange.js index ba3ef38..21af463 100644 --- a/js/src/base/Exchange.js +++ b/js/src/base/Exchange.js @@ -2270,6 +2270,7 @@ export default class Exchange { this.httpsAgent = undefined; this.useVerity = false; this.verityProverUrl = "http://localhost:8080"; + this.verityMethods = ["fetchBalance", "fetchDepositAddress", "fetchDepositAddress", "fetchDepositAddresses", "fetchDepositAddressesByNetwork", "fetchDeposits", "withdraw", "fetchFundingHistory", "fetchWithdrawals", "fetchWithdrawal"]; this.minFundingAddressLength = 1; // used in checkAddress this.substituteCommonCurrencyCodes = true; // reserved this.quoteJsonNumbers = true; // treat numbers in json as quoted precise strings @@ -2838,7 +2839,7 @@ export default class Exchange { this.log("MethodCalled:", methodCalled + "\n"); } // TODO: make the method Arrays that use verity configurable - if (this.useVerity && ["get", "post"].includes(method.toLowerCase()) && ["fetchBalance", "fetchDepositAddress", "fetchDepositAddress", "fetchDepositAddresses", "fetchDepositAddressesByNetwork", "fetchDeposits", "withdraw"].includes(methodCalled)) { + if (this.useVerity && ["get", "post"].includes(method.toLowerCase()) && this.verityMethods.includes(methodCalled)) { const client = new verity.VerityClient({ prover_url: this.verityProverUrl }); const lowercase = Object.keys(axiosConfig.headers).map(h => `req:header:${h.toLowerCase()}`).join(","); const response = await client diff --git a/package-lock.json b/package-lock.json index 7db8ab3..e9604c3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,16 +1,15 @@ { - "name": "test-bun-ccxt", + "name": "@usherlabs/ccxt", "version": "0.0.3", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "test-bun-ccxt", + "name": "@usherlabs/ccxt", "version": "0.0.3", - "hasInstallScript": true, "license": "MIT", "dependencies": { - "@usherlabs/verity-client": "^0.0.22", + "@usherlabs/verity-client": "^0.0.24", "axios": "^1.10.0", "ws": "^8.8.1" }, @@ -1411,9 +1410,9 @@ } }, "node_modules/@usherlabs/verity-client": { - "version": "0.0.22", - "resolved": "https://registry.npmjs.org/@usherlabs/verity-client/-/verity-client-0.0.22.tgz", - "integrity": "sha512-Qq/m0C6hYF55pZWXSL2yeyoxV6MiXJIYRlO5fS6Scp5UfgNIv388ByhHKNg/h4ne4wVT/olv42FcUVoUGZQvjA==", + "version": "0.0.24", + "resolved": "https://registry.npmjs.org/@usherlabs/verity-client/-/verity-client-0.0.24.tgz", + "integrity": "sha512-TtKQUeIaKtWDTFIbFWfe/GKA3YixsOwko4vS8rjFuxQdg+FA6XUMUQolyZaAyqDr6QSzNtSu7FTYIluJZewFyQ==", "license": "MIT", "dependencies": { "@types/eventsource": "^1.1.15", diff --git a/package.json b/package.json index 26efa08..80a5389 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@usherlabs/ccxt", - "version": "0.0.3", + "version": "0.0.5", "description": "A JavaScript cryptocurrency trading library with support for 100+ exchanges powered by verity", "unpkg": "dist/ccxt.browser.min.js", "type": "module", @@ -22,7 +22,7 @@ }, "repository": { "type": "git", - "url": "git+https://github.com/ccxt/ccxt.git" + "url": "git+https://github.com/usherlabs/ccxt.git" }, "readme": "README.md", "scripts": { diff --git a/ts/src/base/Exchange.ts b/ts/src/base/Exchange.ts index 555f169..b6f7f0f 100644 --- a/ts/src/base/Exchange.ts +++ b/ts/src/base/Exchange.ts @@ -2468,6 +2468,7 @@ export default class Exchange { httpsAgent = undefined; useVerity: boolean = false; verityProverUrl = "http://localhost:8080"; + verityMethods: string[] = ["fetchBalance", "fetchDepositAddress", "fetchDepositAddress", "fetchDepositAddresses", "fetchDepositAddressesByNetwork", "fetchDeposits", "withdraw", "fetchFundingHistory", "fetchWithdrawals", "fetchWithdrawal"]; minFundingAddressLength: Int = 1 // used in checkAddress substituteCommonCurrencyCodes: boolean = true // reserved @@ -3157,7 +3158,7 @@ export default class Exchange { } // TODO: make the method Arrays that use verity configurable - if (this.useVerity && ["get", "post"].includes(method.toLowerCase()) && ["fetchBalance", "fetchDepositAddress", "fetchDepositAddress", "fetchDepositAddresses", "fetchDepositAddressesByNetwork", "fetchDeposits", "withdraw"].includes(methodCalled)) { + if (this.useVerity && ["get", "post"].includes(method.toLowerCase()) && this.verityMethods.includes(methodCalled)) { const client = new verity.VerityClient({ prover_url: this.verityProverUrl }); const lowercase = Object.keys(axiosConfig.headers).map(h => `req:header:${h.toLowerCase()}`).join(","); const response = await client