From ff63987704fb1e501b5ea5b7db2024d1395b6ba3 Mon Sep 17 00:00:00 2001 From: Ryan Soury Date: Sun, 7 Sep 2025 01:47:52 +1000 Subject: [PATCH 1/2] optional redact --- README.md | 2 +- js/src/base/Exchange.d.ts | 6 ++++++ js/src/base/Exchange.js | 15 +++++++++++---- ts/src/base/Exchange.ts | 17 +++++++++++++---- 4 files changed, 31 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 3fdccb0..a0458e2 100644 --- a/README.md +++ b/README.md @@ -269,4 +269,4 @@ This library is licensed under the **MIT License**. See the [LICENSE](https://gi ## Star History -[![Star History Chart](https://api.star-history.com/svg?repos=ccxt/ccxt&type=Date)](https://star-history.com/#ccxt/ccxt&Date) +[![Star History Chart](https://api.star-history.com/svg?repos=ccxt/ccxt&type=Date)](https://star-history.com/#ccxt/ccxt&Date) \ No newline at end of file diff --git a/js/src/base/Exchange.d.ts b/js/src/base/Exchange.d.ts index b46ef8b..216b167 100644 --- a/js/src/base/Exchange.d.ts +++ b/js/src/base/Exchange.d.ts @@ -60,6 +60,9 @@ export default class Exchange { useVerity: boolean; verityProverUrl: string; verityMethods: string[]; + verityRequestOptions: { + redact: string; + }; minFundingAddressLength: Int; substituteCommonCurrencyCodes: boolean; quoteJsonNumbers: boolean; @@ -332,6 +335,9 @@ export default class Exchange { setProxyAgents(httpProxy: any, httpsProxy: any, socksProxy: any): any; loadHttpProxyAgent(): Promise; getHttpAgentIfNeeded(url: any): any; + addVerityRequestOptions(options: { + redact: string; + }): void; fetch(url: any, method?: string, headers?: any, body?: any): Promise; parseJson(jsonString: any): any; getResponseHeaders(response: any): {}; diff --git a/js/src/base/Exchange.js b/js/src/base/Exchange.js index 21af463..6b999e8 100644 --- a/js/src/base/Exchange.js +++ b/js/src/base/Exchange.js @@ -2268,9 +2268,12 @@ export default class Exchange { this.nodeHttpModuleLoaded = false; this.httpAgent = undefined; this.httpsAgent = undefined; + // ! Usher Labs Addition this.useVerity = false; this.verityProverUrl = "http://localhost:8080"; this.verityMethods = ["fetchBalance", "fetchDepositAddress", "fetchDepositAddress", "fetchDepositAddresses", "fetchDepositAddressesByNetwork", "fetchDeposits", "withdraw", "fetchFundingHistory", "fetchWithdrawals", "fetchWithdrawal"]; + this.verityRequestOptions = { redact: "" }; + //! ------------------------------ this.minFundingAddressLength = 1; // used in checkAddress this.substituteCommonCurrencyCodes = true; // reserved this.quoteJsonNumbers = true; // treat numbers in json as quoted precise strings @@ -2308,6 +2311,7 @@ export default class Exchange { this.last_request_body = undefined; this.last_request_url = undefined; this.last_request_path = undefined; + // ! Usher Labs Addition this.last_proof = undefined; this.id = 'Exchange'; this.markets = undefined; @@ -2750,6 +2754,11 @@ export default class Exchange { } return undefined; } + // ! Usher Labs Addition + addVerityRequestOptions(options) { + this.verityRequestOptions = options; + } + // ! Usher Labs Addition: Modified to use Verity if instantiated as such. Includes appended headers. async fetch(url, method = 'GET', headers = undefined, body = undefined) { // load node-http(s) modules only on first call if (isNode) { @@ -2830,7 +2839,7 @@ export default class Exchange { } } try { - this.last_proof = undefined; + this.last_proof = undefined; // TODO: I wonder if there's a race condition on last_proof, where another request's proof is passed instead? We should test this. const path = url.split("?")[0]; const idMap = urlToMethodMap[this.id] ?? {}; const matchedEntry = Object.entries(idMap).find(([prefix]) => path.startsWith(prefix)); @@ -2838,13 +2847,11 @@ export default class Exchange { if (this.verbose) { this.log("MethodCalled:", methodCalled + "\n"); } - // TODO: make the method Arrays that use verity configurable 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 .get(axiosConfig.url, axiosConfig) - .redact(lowercase); + .redact(this.verityRequestOptions.redact || ""); // ? Should Verity be configured for use on a per request basis always? if (this.verbose) { this.log("verityProof:", response.proof, "\n\n", "verityNotaryPub:", response.notary_pub_key, "\n"); } diff --git a/ts/src/base/Exchange.ts b/ts/src/base/Exchange.ts index b6f7f0f..f3f37ba 100644 --- a/ts/src/base/Exchange.ts +++ b/ts/src/base/Exchange.ts @@ -2466,9 +2466,13 @@ export default class Exchange { nodeHttpModuleLoaded: boolean = false; httpAgent = undefined; httpsAgent = undefined; + + // ! Usher Labs Addition useVerity: boolean = false; verityProverUrl = "http://localhost:8080"; verityMethods: string[] = ["fetchBalance", "fetchDepositAddress", "fetchDepositAddress", "fetchDepositAddresses", "fetchDepositAddressesByNetwork", "fetchDeposits", "withdraw", "fetchFundingHistory", "fetchWithdrawals", "fetchWithdrawal"]; + verityRequestOptions: { redact: string } = { redact: "" }; + //! ------------------------------ minFundingAddressLength: Int = 1 // used in checkAddress substituteCommonCurrencyCodes: boolean = true // reserved @@ -2544,6 +2548,7 @@ export default class Exchange { last_request_body = undefined last_request_url = undefined last_request_path = undefined + // ! Usher Labs Addition last_proof: string | undefined = undefined id: string = 'Exchange'; @@ -3060,7 +3065,12 @@ export default class Exchange { return undefined; } + // ! Usher Labs Addition + addVerityRequestOptions(options: { redact: string }) { + this.verityRequestOptions = options; + } + // ! Usher Labs Addition: Modified to use Verity if instantiated as such. Includes appended headers. async fetch(url, method = 'GET', headers: any = undefined, body: any = undefined) { // load node-http(s) modules only on first call @@ -3144,7 +3154,8 @@ export default class Exchange { } try { - this.last_proof = undefined; + this.last_proof = undefined; // TODO: I wonder if there's a race condition on last_proof, where another request's proof is passed instead? We should test this. + const path = url.split("?")[0]; const idMap = urlToMethodMap[this.id] ?? {}; @@ -3157,13 +3168,11 @@ 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()) && 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 .get(axiosConfig.url, axiosConfig) - .redact(lowercase); + .redact(this.verityRequestOptions.redact || ""); // ? Should Verity be configured for use on a per request basis always? if (this.verbose) { this.log("verityProof:", response.proof, "\n\n", "verityNotaryPub:", response.notary_pub_key, "\n"); } From 1dd21091a13f3f48c68b596ce0ed2f3642abb3c6 Mon Sep 17 00:00:00 2001 From: Ryan Soury Date: Sun, 7 Sep 2025 02:42:38 +1000 Subject: [PATCH 2/2] commit version bump and build update --- js/ccxt.d.ts | 2 +- js/ccxt.js | 2 +- package.json | 2 +- ts/ccxt.ts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/js/ccxt.d.ts b/js/ccxt.d.ts index e7655e2..2457ad9 100644 --- a/js/ccxt.d.ts +++ b/js/ccxt.d.ts @@ -4,7 +4,7 @@ import * as functions from './src/base/functions.js'; import * as errors from './src/base/errors.js'; import type { Int, int, Str, Strings, Num, Bool, IndexType, OrderSide, OrderType, MarketType, SubType, Dict, NullableDict, List, NullableList, Fee, OHLCV, OHLCVC, implicitReturnType, Market, Currency, Dictionary, MinMax, FeeInterface, TradingFeeInterface, MarketInterface, Trade, Order, OrderBook, Ticker, Transaction, Tickers, CurrencyInterface, Balance, BalanceAccount, Account, PartialBalances, Balances, DepositAddress, WithdrawalResponse, FundingRate, FundingRates, Position, BorrowInterest, LeverageTier, LedgerEntry, DepositWithdrawFeeNetwork, DepositWithdrawFee, TransferEntry, CrossBorrowRate, IsolatedBorrowRate, FundingRateHistory, OpenInterest, Liquidation, OrderRequest, CancellationRequest, FundingHistory, MarketMarginModes, MarginMode, Greeks, Conversion, Option, LastPrice, Leverage, MarginModification, Leverages, LastPrices, Currencies, TradingFees, MarginModes, OptionChain, IsolatedBorrowRates, CrossBorrowRates, LeverageTiers, LongShortRatio, OrderBooks, OpenInterests, ConstructorArgs } from './src/base/types.js'; import { BaseError, ExchangeError, AuthenticationError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, OperationRejected, NoChange, MarginModeAlreadySet, MarketClosed, ManualInteractionNeeded, InsufficientFunds, InvalidAddress, AddressPending, InvalidOrder, OrderNotFound, OrderNotCached, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, ContractUnavailable, NotSupported, InvalidProxySettings, ExchangeClosedByUser, OperationFailed, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, ChecksumError, RequestTimeout, BadResponse, NullResponse, CancelPending, UnsubscribeError } from './src/base/errors.js'; -declare const version = "0.0.6"; +declare const version = "0.0.10"; import alpaca from './src/alpaca.js'; import apex from './src/apex.js'; import ascendex from './src/ascendex.js'; diff --git a/js/ccxt.js b/js/ccxt.js index 2bdd929..6f26655 100644 --- a/js/ccxt.js +++ b/js/ccxt.js @@ -38,7 +38,7 @@ import * as errors from './src/base/errors.js'; import { BaseError, ExchangeError, AuthenticationError, PermissionDenied, AccountNotEnabled, AccountSuspended, ArgumentsRequired, BadRequest, BadSymbol, OperationRejected, NoChange, MarginModeAlreadySet, MarketClosed, ManualInteractionNeeded, InsufficientFunds, InvalidAddress, AddressPending, InvalidOrder, OrderNotFound, OrderNotCached, OrderImmediatelyFillable, OrderNotFillable, DuplicateOrderId, ContractUnavailable, NotSupported, InvalidProxySettings, ExchangeClosedByUser, OperationFailed, NetworkError, DDoSProtection, RateLimitExceeded, ExchangeNotAvailable, OnMaintenance, InvalidNonce, ChecksumError, RequestTimeout, BadResponse, NullResponse, CancelPending, UnsubscribeError } from './src/base/errors.js'; //----------------------------------------------------------------------------- // this is updated by vss.js when building -const version = '0.0.6'; +const version = '0.0.10'; Exchange.ccxtVersion = version; //----------------------------------------------------------------------------- import alpaca from './src/alpaca.js'; diff --git a/package.json b/package.json index 4203d78..469da6d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@usherlabs/ccxt", - "version": "0.0.6", + "version": "0.0.10", "description": "A JavaScript cryptocurrency trading library with support for 100+ exchanges. Verifiable data powered by Verity.", "unpkg": "dist/ccxt.browser.min.js", "type": "module", diff --git a/ts/ccxt.ts b/ts/ccxt.ts index 2170f64..f8b1cf3 100644 --- a/ts/ccxt.ts +++ b/ts/ccxt.ts @@ -40,7 +40,7 @@ import {BaseError, ExchangeError, AuthenticationError, PermissionDenied, Account //----------------------------------------------------------------------------- // this is updated by vss.js when building -const version = '0.0.6'; +const version = '0.0.10'; (Exchange as any).ccxtVersion = version