@lifi/perps-sdk 23.1.0 → 25.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +102 -56
- package/dist/cjs/client/PerpsClient.d.ts +3 -2
- package/dist/cjs/client/PerpsClient.d.ts.map +1 -1
- package/dist/cjs/client/PerpsClient.js +16 -9
- package/dist/cjs/client/PerpsClient.js.map +1 -1
- package/dist/cjs/decimal/arithmetic.d.ts +15 -0
- package/dist/cjs/decimal/arithmetic.d.ts.map +1 -0
- package/dist/cjs/decimal/arithmetic.js +53 -0
- package/dist/cjs/decimal/arithmetic.js.map +1 -0
- package/dist/cjs/decimal/big.d.ts +0 -1
- package/dist/cjs/decimal/big.d.ts.map +1 -1
- package/dist/cjs/decimal/big.js +0 -4
- package/dist/cjs/decimal/big.js.map +1 -1
- package/dist/cjs/decimal/compare.d.ts +6 -2
- package/dist/cjs/decimal/compare.d.ts.map +1 -1
- package/dist/cjs/decimal/compare.js +15 -2
- package/dist/cjs/decimal/compare.js.map +1 -1
- package/dist/cjs/decimal/convert.d.ts +10 -6
- package/dist/cjs/decimal/convert.d.ts.map +1 -1
- package/dist/cjs/decimal/convert.js +34 -21
- package/dist/cjs/decimal/convert.js.map +1 -1
- package/dist/cjs/decimal/decimalStringToBig.d.ts +5 -0
- package/dist/cjs/decimal/decimalStringToBig.d.ts.map +1 -0
- package/dist/cjs/decimal/decimalStringToBig.js +25 -0
- package/dist/cjs/decimal/decimalStringToBig.js.map +1 -0
- package/dist/cjs/decimal/format.d.ts.map +1 -1
- package/dist/cjs/decimal/format.js +70 -52
- package/dist/cjs/decimal/format.js.map +1 -1
- package/dist/cjs/decimal/parse.d.ts +5 -4
- package/dist/cjs/decimal/parse.d.ts.map +1 -1
- package/dist/cjs/decimal/parse.js +43 -25
- package/dist/cjs/decimal/parse.js.map +1 -1
- package/dist/cjs/errors/invalidInput.d.ts +3 -0
- package/dist/cjs/errors/invalidInput.d.ts.map +1 -0
- package/dist/cjs/errors/invalidInput.js +9 -0
- package/dist/cjs/errors/invalidInput.js.map +1 -0
- package/dist/cjs/index.d.ts +15 -12
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +69 -9
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/math/fills.d.ts +1 -1
- package/dist/cjs/math/fills.d.ts.map +1 -1
- package/dist/cjs/math/fills.js +28 -13
- package/dist/cjs/math/fills.js.map +1 -1
- package/dist/cjs/math/order.d.ts +27 -16
- package/dist/cjs/math/order.d.ts.map +1 -1
- package/dist/cjs/math/order.js +131 -134
- package/dist/cjs/math/order.js.map +1 -1
- package/dist/cjs/math/position.d.ts +85 -35
- package/dist/cjs/math/position.d.ts.map +1 -1
- package/dist/cjs/math/position.js +93 -94
- package/dist/cjs/math/position.js.map +1 -1
- package/dist/cjs/services/getGasRecommendation.js +1 -1
- package/dist/cjs/services/getGasRecommendation.js.map +1 -1
- package/dist/cjs/services/getQuote.d.ts +1 -1
- package/dist/cjs/services/resolveSubscribeQuote.d.ts.map +1 -1
- package/dist/cjs/services/resolveSubscribeQuote.js +3 -2
- package/dist/cjs/services/resolveSubscribeQuote.js.map +1 -1
- package/dist/cjs/transport/request.d.ts +1 -0
- package/dist/cjs/transport/request.d.ts.map +1 -1
- package/dist/cjs/transport/request.js +2 -2
- package/dist/cjs/transport/request.js.map +1 -1
- package/dist/cjs/types/api.d.ts +4 -0
- package/dist/cjs/types/api.d.ts.map +1 -1
- package/dist/cjs/types/provider.d.ts +9 -5
- package/dist/cjs/types/provider.d.ts.map +1 -1
- package/dist/cjs/types/withdrawal.d.ts +12 -4
- package/dist/cjs/types/withdrawal.d.ts.map +1 -1
- package/dist/cjs/utils/createSafeFunction.d.ts +2 -0
- package/dist/cjs/utils/createSafeFunction.d.ts.map +1 -0
- package/dist/cjs/utils/createSafeFunction.js +15 -0
- package/dist/cjs/utils/createSafeFunction.js.map +1 -0
- package/dist/cjs/utils/timestampToIsoString.d.ts +3 -0
- package/dist/cjs/utils/timestampToIsoString.d.ts.map +1 -0
- package/dist/cjs/utils/timestampToIsoString.js +16 -0
- package/dist/cjs/utils/timestampToIsoString.js.map +1 -0
- package/dist/cjs/utils/warnOnce.d.ts +6 -0
- package/dist/cjs/utils/warnOnce.d.ts.map +1 -1
- package/dist/cjs/utils/warnOnce.js +19 -1
- package/dist/cjs/utils/warnOnce.js.map +1 -1
- package/dist/cjs/version.d.ts +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/cjs/websocket/PerpsWsClient.d.ts +2 -0
- package/dist/cjs/websocket/PerpsWsClient.d.ts.map +1 -1
- package/dist/cjs/websocket/PerpsWsClient.js +14 -1
- package/dist/cjs/websocket/PerpsWsClient.js.map +1 -1
- package/dist/cjs/websocket/wsLog.d.ts +2 -0
- package/dist/cjs/websocket/wsLog.d.ts.map +1 -1
- package/dist/cjs/websocket/wsLog.js +9 -0
- package/dist/cjs/websocket/wsLog.js.map +1 -1
- package/dist/cjs/wire/orderAmounts.d.ts +3 -2
- package/dist/cjs/wire/orderAmounts.d.ts.map +1 -1
- package/dist/cjs/wire/orderAmounts.js +22 -21
- package/dist/cjs/wire/orderAmounts.js.map +1 -1
- package/dist/cjs/wire/refuel.d.ts +4 -1
- package/dist/cjs/wire/refuel.d.ts.map +1 -1
- package/dist/cjs/wire/refuel.js +23 -6
- package/dist/cjs/wire/refuel.js.map +1 -1
- package/dist/cjs/wire/transferable.js +3 -3
- package/dist/cjs/wire/transferable.js.map +1 -1
- package/dist/cjs/wire/withdraw.d.ts.map +1 -1
- package/dist/cjs/wire/withdraw.js +3 -3
- package/dist/cjs/wire/withdraw.js.map +1 -1
- package/dist/esm/client/PerpsClient.d.ts +17 -4
- package/dist/esm/client/PerpsClient.d.ts.map +1 -1
- package/dist/esm/client/PerpsClient.js +30 -8
- package/dist/esm/client/PerpsClient.js.map +1 -1
- package/dist/esm/decimal/arithmetic.d.ts +98 -0
- package/dist/esm/decimal/arithmetic.d.ts.map +1 -0
- package/dist/esm/decimal/arithmetic.js +126 -0
- package/dist/esm/decimal/arithmetic.js.map +1 -0
- package/dist/esm/decimal/big.d.ts +0 -2
- package/dist/esm/decimal/big.d.ts.map +1 -1
- package/dist/esm/decimal/big.js +0 -4
- package/dist/esm/decimal/big.js.map +1 -1
- package/dist/esm/decimal/compare.d.ts +40 -6
- package/dist/esm/decimal/compare.d.ts.map +1 -1
- package/dist/esm/decimal/compare.js +46 -6
- package/dist/esm/decimal/compare.js.map +1 -1
- package/dist/esm/decimal/convert.d.ts +50 -36
- package/dist/esm/decimal/convert.d.ts.map +1 -1
- package/dist/esm/decimal/convert.js +64 -42
- package/dist/esm/decimal/convert.js.map +1 -1
- package/dist/esm/decimal/decimalStringToBig.d.ts +25 -0
- package/dist/esm/decimal/decimalStringToBig.d.ts.map +1 -0
- package/dist/esm/decimal/decimalStringToBig.js +37 -0
- package/dist/esm/decimal/decimalStringToBig.js.map +1 -0
- package/dist/esm/decimal/format.d.ts +4 -1
- package/dist/esm/decimal/format.d.ts.map +1 -1
- package/dist/esm/decimal/format.js +71 -70
- package/dist/esm/decimal/format.js.map +1 -1
- package/dist/esm/decimal/parse.d.ts +29 -13
- package/dist/esm/decimal/parse.d.ts.map +1 -1
- package/dist/esm/decimal/parse.js +61 -44
- package/dist/esm/decimal/parse.js.map +1 -1
- package/dist/esm/errors/invalidInput.d.ts +4 -0
- package/dist/esm/errors/invalidInput.d.ts.map +1 -0
- package/dist/esm/errors/invalidInput.js +7 -0
- package/dist/esm/errors/invalidInput.js.map +1 -0
- package/dist/esm/index.d.ts +15 -12
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +11 -8
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/math/fills.d.ts +6 -3
- package/dist/esm/math/fills.d.ts.map +1 -1
- package/dist/esm/math/fills.js +31 -16
- package/dist/esm/math/fills.js.map +1 -1
- package/dist/esm/math/order.d.ts +84 -66
- package/dist/esm/math/order.d.ts.map +1 -1
- package/dist/esm/math/order.js +178 -175
- package/dist/esm/math/order.js.map +1 -1
- package/dist/esm/math/position.d.ts +155 -98
- package/dist/esm/math/position.d.ts.map +1 -1
- package/dist/esm/math/position.js +160 -156
- package/dist/esm/math/position.js.map +1 -1
- package/dist/esm/services/getGasRecommendation.js +1 -1
- package/dist/esm/services/getGasRecommendation.js.map +1 -1
- package/dist/esm/services/getQuote.d.ts +2 -2
- package/dist/esm/services/getQuote.js +1 -1
- package/dist/esm/services/resolveSubscribeQuote.d.ts +1 -1
- package/dist/esm/services/resolveSubscribeQuote.d.ts.map +1 -1
- package/dist/esm/services/resolveSubscribeQuote.js +4 -3
- package/dist/esm/services/resolveSubscribeQuote.js.map +1 -1
- package/dist/esm/transport/request.d.ts +5 -0
- package/dist/esm/transport/request.d.ts.map +1 -1
- package/dist/esm/transport/request.js +2 -2
- package/dist/esm/transport/request.js.map +1 -1
- package/dist/esm/types/api.d.ts +9 -0
- package/dist/esm/types/api.d.ts.map +1 -1
- package/dist/esm/types/provider.d.ts +30 -16
- package/dist/esm/types/provider.d.ts.map +1 -1
- package/dist/esm/types/withdrawal.d.ts +32 -7
- package/dist/esm/types/withdrawal.d.ts.map +1 -1
- package/dist/esm/utils/createSafeFunction.d.ts +9 -0
- package/dist/esm/utils/createSafeFunction.d.ts.map +1 -0
- package/dist/esm/utils/createSafeFunction.js +19 -0
- package/dist/esm/utils/createSafeFunction.js.map +1 -0
- package/dist/esm/utils/timestampToIsoString.d.ts +15 -0
- package/dist/esm/utils/timestampToIsoString.d.ts.map +1 -0
- package/dist/esm/utils/timestampToIsoString.js +24 -0
- package/dist/esm/utils/timestampToIsoString.js.map +1 -0
- package/dist/esm/utils/warnOnce.d.ts +27 -0
- package/dist/esm/utils/warnOnce.d.ts.map +1 -1
- package/dist/esm/utils/warnOnce.js +36 -0
- package/dist/esm/utils/warnOnce.js.map +1 -1
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/esm/websocket/PerpsWsClient.d.ts +7 -0
- package/dist/esm/websocket/PerpsWsClient.d.ts.map +1 -1
- package/dist/esm/websocket/PerpsWsClient.js +20 -2
- package/dist/esm/websocket/PerpsWsClient.js.map +1 -1
- package/dist/esm/websocket/wsLog.d.ts +12 -0
- package/dist/esm/websocket/wsLog.d.ts.map +1 -1
- package/dist/esm/websocket/wsLog.js +19 -0
- package/dist/esm/websocket/wsLog.js.map +1 -1
- package/dist/esm/wire/orderAmounts.d.ts +9 -7
- package/dist/esm/wire/orderAmounts.d.ts.map +1 -1
- package/dist/esm/wire/orderAmounts.js +24 -20
- package/dist/esm/wire/orderAmounts.js.map +1 -1
- package/dist/esm/wire/refuel.d.ts +24 -14
- package/dist/esm/wire/refuel.d.ts.map +1 -1
- package/dist/esm/wire/refuel.js +38 -17
- package/dist/esm/wire/refuel.js.map +1 -1
- package/dist/esm/wire/transferable.d.ts +2 -2
- package/dist/esm/wire/transferable.js +5 -5
- package/dist/esm/wire/transferable.js.map +1 -1
- package/dist/esm/wire/withdraw.d.ts.map +1 -1
- package/dist/esm/wire/withdraw.js +3 -3
- package/dist/esm/wire/withdraw.js.map +1 -1
- package/dist/types/client/PerpsClient.d.ts +17 -4
- package/dist/types/client/PerpsClient.d.ts.map +1 -1
- package/dist/types/decimal/arithmetic.d.ts +98 -0
- package/dist/types/decimal/arithmetic.d.ts.map +1 -0
- package/dist/types/decimal/big.d.ts +0 -2
- package/dist/types/decimal/big.d.ts.map +1 -1
- package/dist/types/decimal/compare.d.ts +40 -6
- package/dist/types/decimal/compare.d.ts.map +1 -1
- package/dist/types/decimal/convert.d.ts +50 -36
- package/dist/types/decimal/convert.d.ts.map +1 -1
- package/dist/types/decimal/decimalStringToBig.d.ts +25 -0
- package/dist/types/decimal/decimalStringToBig.d.ts.map +1 -0
- package/dist/types/decimal/format.d.ts +4 -1
- package/dist/types/decimal/format.d.ts.map +1 -1
- package/dist/types/decimal/parse.d.ts +29 -13
- package/dist/types/decimal/parse.d.ts.map +1 -1
- package/dist/types/errors/invalidInput.d.ts +4 -0
- package/dist/types/errors/invalidInput.d.ts.map +1 -0
- package/dist/types/index.d.ts +15 -12
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/math/fills.d.ts +6 -3
- package/dist/types/math/fills.d.ts.map +1 -1
- package/dist/types/math/order.d.ts +84 -66
- package/dist/types/math/order.d.ts.map +1 -1
- package/dist/types/math/position.d.ts +155 -98
- package/dist/types/math/position.d.ts.map +1 -1
- package/dist/types/services/getQuote.d.ts +2 -2
- package/dist/types/services/resolveSubscribeQuote.d.ts +1 -1
- package/dist/types/services/resolveSubscribeQuote.d.ts.map +1 -1
- package/dist/types/transport/request.d.ts +5 -0
- package/dist/types/transport/request.d.ts.map +1 -1
- package/dist/types/types/api.d.ts +9 -0
- package/dist/types/types/api.d.ts.map +1 -1
- package/dist/types/types/provider.d.ts +30 -16
- package/dist/types/types/provider.d.ts.map +1 -1
- package/dist/types/types/withdrawal.d.ts +32 -7
- package/dist/types/types/withdrawal.d.ts.map +1 -1
- package/dist/types/utils/createSafeFunction.d.ts +9 -0
- package/dist/types/utils/createSafeFunction.d.ts.map +1 -0
- package/dist/types/utils/timestampToIsoString.d.ts +15 -0
- package/dist/types/utils/timestampToIsoString.d.ts.map +1 -0
- package/dist/types/utils/warnOnce.d.ts +27 -0
- package/dist/types/utils/warnOnce.d.ts.map +1 -1
- package/dist/types/version.d.ts +1 -1
- package/dist/types/websocket/PerpsWsClient.d.ts +7 -0
- package/dist/types/websocket/PerpsWsClient.d.ts.map +1 -1
- package/dist/types/websocket/wsLog.d.ts +12 -0
- package/dist/types/websocket/wsLog.d.ts.map +1 -1
- package/dist/types/wire/orderAmounts.d.ts +9 -7
- package/dist/types/wire/orderAmounts.d.ts.map +1 -1
- package/dist/types/wire/refuel.d.ts +24 -14
- package/dist/types/wire/refuel.d.ts.map +1 -1
- package/dist/types/wire/transferable.d.ts +2 -2
- package/dist/types/wire/withdraw.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/client/PerpsClient.ts +48 -10
- package/src/decimal/arithmetic.ts +170 -0
- package/src/decimal/big.ts +0 -5
- package/src/decimal/compare.ts +61 -11
- package/src/decimal/convert.ts +105 -63
- package/src/decimal/decimalStringToBig.ts +42 -0
- package/src/decimal/format.ts +81 -72
- package/src/decimal/parse.ts +78 -57
- package/src/errors/invalidInput.ts +10 -0
- package/src/index.ts +80 -12
- package/src/math/fills.ts +32 -17
- package/src/math/order.ts +279 -226
- package/src/math/position.ts +280 -196
- package/src/services/getGasRecommendation.ts +1 -1
- package/src/services/getQuote.ts +2 -2
- package/src/services/resolveSubscribeQuote.ts +4 -3
- package/src/transport/request.ts +7 -2
- package/src/types/api.ts +10 -0
- package/src/types/provider.ts +39 -16
- package/src/types/withdrawal.ts +35 -8
- package/src/utils/createSafeFunction.ts +20 -0
- package/src/utils/timestampToIsoString.ts +31 -0
- package/src/utils/warnOnce.ts +60 -0
- package/src/version.ts +1 -1
- package/src/websocket/PerpsWsClient.ts +25 -2
- package/src/websocket/wsLog.ts +44 -0
- package/src/wire/orderAmounts.ts +45 -26
- package/src/wire/refuel.ts +56 -20
- package/src/wire/transferable.ts +5 -5
- package/src/wire/withdraw.ts +3 -5
- package/dist/cjs/decimal/requireDecimal.d.ts +0 -4
- package/dist/cjs/decimal/requireDecimal.d.ts.map +0 -1
- package/dist/cjs/decimal/requireDecimal.js +0 -12
- package/dist/cjs/decimal/requireDecimal.js.map +0 -1
- package/dist/esm/decimal/requireDecimal.d.ts +0 -5
- package/dist/esm/decimal/requireDecimal.d.ts.map +0 -1
- package/dist/esm/decimal/requireDecimal.js +0 -7
- package/dist/esm/decimal/requireDecimal.js.map +0 -1
- package/dist/types/decimal/requireDecimal.d.ts +0 -5
- package/dist/types/decimal/requireDecimal.d.ts.map +0 -1
- package/src/decimal/requireDecimal.ts +0 -8
|
@@ -30,8 +30,9 @@ import {
|
|
|
30
30
|
PerpsSigner,
|
|
31
31
|
SigningMethod,
|
|
32
32
|
} from '@lifi/perps-types'
|
|
33
|
-
import Big from 'big.js'
|
|
34
33
|
import type { Address } from 'viem'
|
|
34
|
+
import { isDecimalStringGreaterThan } from '../decimal/compare.js'
|
|
35
|
+
import { unknownToDecimalString } from '../decimal/parse.js'
|
|
35
36
|
import { PerpsError } from '../errors/PerpsError.js'
|
|
36
37
|
import { getAssetRegistry, toAssetDisplay } from '../registry/assetRegistry.js'
|
|
37
38
|
import { getMarketRegistry } from '../registry/marketRegistry.js'
|
|
@@ -60,6 +61,7 @@ import type {
|
|
|
60
61
|
GetPortfolioHistoryParams,
|
|
61
62
|
GetSetupParams,
|
|
62
63
|
GetWithdrawableBalancesParams,
|
|
64
|
+
GetWithdrawalTypesParams,
|
|
63
65
|
GetWithdrawFlowParams,
|
|
64
66
|
ModifyOrdersParams,
|
|
65
67
|
PerpsClientOptions,
|
|
@@ -85,7 +87,11 @@ import type {
|
|
|
85
87
|
SignActionProgress,
|
|
86
88
|
SignActionsContext,
|
|
87
89
|
} from '../types/provider.js'
|
|
88
|
-
import type {
|
|
90
|
+
import type {
|
|
91
|
+
WithdrawableBalance,
|
|
92
|
+
WithdrawalSourceTypes,
|
|
93
|
+
WithdrawFlow,
|
|
94
|
+
} from '../types/withdrawal.js'
|
|
89
95
|
import { isUserFacingSetupStep } from '../utils/setupActions.js'
|
|
90
96
|
import { signTypedDataWithSigner } from '../utils/signTypedData.js'
|
|
91
97
|
import {
|
|
@@ -219,7 +225,10 @@ function assertAllSucceeded(results: ActionResult[]): void {
|
|
|
219
225
|
|
|
220
226
|
function isNonNegativeDecimal(value: string): boolean {
|
|
221
227
|
try {
|
|
222
|
-
return
|
|
228
|
+
return !isDecimalStringGreaterThan(
|
|
229
|
+
'0',
|
|
230
|
+
unknownToDecimalString(value, 'withdrawalFee', 'perps-sdk')
|
|
231
|
+
)
|
|
223
232
|
} catch {
|
|
224
233
|
return false
|
|
225
234
|
}
|
|
@@ -838,8 +847,9 @@ export class PerpsClient {
|
|
|
838
847
|
}
|
|
839
848
|
|
|
840
849
|
/**
|
|
841
|
-
* The `(asset,
|
|
842
|
-
* `params.provider`. The venue owns how its balances split across
|
|
850
|
+
* The `(asset, category)` selections `params.address` can actually withdraw
|
|
851
|
+
* at `params.provider`. The venue owns how its balances split across
|
|
852
|
+
* categories;
|
|
843
853
|
* this join adds the core `/assets` metadata — precision, L1 identity and
|
|
844
854
|
* the per-asset minimum — and drops every row the minimum rules out, plus
|
|
845
855
|
* any row whose asset the provider's registry does not carry, since without
|
|
@@ -878,22 +888,31 @@ export class PerpsClient {
|
|
|
878
888
|
}
|
|
879
889
|
const minimum = asset.minWithdrawalAmount
|
|
880
890
|
if (minimum !== undefined) {
|
|
881
|
-
let floor:
|
|
891
|
+
let floor: string
|
|
882
892
|
try {
|
|
883
|
-
floor =
|
|
893
|
+
floor = unknownToDecimalString(
|
|
894
|
+
minimum,
|
|
895
|
+
'minWithdrawalAmount',
|
|
896
|
+
'perps-sdk'
|
|
897
|
+
)
|
|
884
898
|
} catch {
|
|
885
899
|
throw new PerpsError(
|
|
886
900
|
PerpsErrorCode.SDKError,
|
|
887
901
|
`Asset '${asset.id}' field \`minWithdrawalAmount\` is not a valid decimal.`
|
|
888
902
|
)
|
|
889
903
|
}
|
|
890
|
-
if (
|
|
904
|
+
if (isDecimalStringGreaterThan(floor, row.available)) {
|
|
891
905
|
return []
|
|
892
906
|
}
|
|
893
907
|
}
|
|
894
908
|
if (row.withdrawalFee === undefined) {
|
|
895
909
|
return [
|
|
896
|
-
{
|
|
910
|
+
{
|
|
911
|
+
asset,
|
|
912
|
+
categoryId: row.categoryId,
|
|
913
|
+
available: row.available,
|
|
914
|
+
max: row.max,
|
|
915
|
+
},
|
|
897
916
|
]
|
|
898
917
|
}
|
|
899
918
|
if (!isNonNegativeDecimal(row.withdrawalFee)) {
|
|
@@ -905,7 +924,7 @@ export class PerpsClient {
|
|
|
905
924
|
return [
|
|
906
925
|
{
|
|
907
926
|
asset,
|
|
908
|
-
|
|
927
|
+
categoryId: row.categoryId,
|
|
909
928
|
available: row.available,
|
|
910
929
|
max: row.max,
|
|
911
930
|
withdrawalFee: row.withdrawalFee,
|
|
@@ -917,6 +936,25 @@ export class PerpsClient {
|
|
|
917
936
|
})
|
|
918
937
|
}
|
|
919
938
|
|
|
939
|
+
/**
|
|
940
|
+
* The withdrawal types `params.address` can choose per holding at
|
|
941
|
+
* `params.provider`, each with its cap and the `withdrawalOptions` to pass
|
|
942
|
+
* unchanged in `WithdrawalParams`.
|
|
943
|
+
*
|
|
944
|
+
* @returns `undefined` when the registered plugin declares no withdrawal
|
|
945
|
+
* types read.
|
|
946
|
+
* @throws {PerpsError} When the provider plugin is not registered, or when
|
|
947
|
+
* the plugin read fails.
|
|
948
|
+
* @public
|
|
949
|
+
*/
|
|
950
|
+
async getWithdrawalTypes(
|
|
951
|
+
params: GetWithdrawalTypesParams,
|
|
952
|
+
options?: SDKRequestOptions
|
|
953
|
+
): Promise<WithdrawalSourceTypes[] | undefined> {
|
|
954
|
+
const plugin = this.requireProvider(params.provider)
|
|
955
|
+
return plugin.getWithdrawalTypes?.({ address: params.address }, options)
|
|
956
|
+
}
|
|
957
|
+
|
|
920
958
|
/**
|
|
921
959
|
* The account's portfolio value and cumulative PnL over `params.range` at
|
|
922
960
|
* `params.provider`, read directly from the venue.
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { PerpsErrorCode } from '@lifi/perps-types'
|
|
2
|
+
import type Big from 'big.js'
|
|
3
|
+
import { PerpsError } from '../errors/PerpsError.js'
|
|
4
|
+
import { createSafeFunction } from '../utils/createSafeFunction.js'
|
|
5
|
+
import { DivBig, TruncBig } from './big.js'
|
|
6
|
+
import { bigToDecimalString, decimalStringToBig } from './decimalStringToBig.js'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Exact `a + b`.
|
|
10
|
+
*
|
|
11
|
+
* @throws {PerpsError} `ValidationError` when an input does not match the decimal pattern.
|
|
12
|
+
* @public
|
|
13
|
+
*/
|
|
14
|
+
export function addDecimalString(a: string, b: string): string {
|
|
15
|
+
return bigToDecimalString(decimalStringToBig(a).plus(decimalStringToBig(b)))
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* {@link addDecimalString}, or `undefined` with a warning when it throws.
|
|
20
|
+
*
|
|
21
|
+
* @public
|
|
22
|
+
*/
|
|
23
|
+
export const safeAddDecimalString = createSafeFunction(
|
|
24
|
+
'addDecimalString',
|
|
25
|
+
addDecimalString
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Exact sum of every value; `'0'` for an empty list.
|
|
30
|
+
*
|
|
31
|
+
* @throws {PerpsError} `ValidationError` when a value does not match the
|
|
32
|
+
* decimal pattern.
|
|
33
|
+
* @public
|
|
34
|
+
*/
|
|
35
|
+
export function addDecimalStrings(values: readonly string[]): string {
|
|
36
|
+
return bigToDecimalString(
|
|
37
|
+
values.reduce<Big>(
|
|
38
|
+
(sum, value) => sum.plus(decimalStringToBig(value)),
|
|
39
|
+
decimalStringToBig('0')
|
|
40
|
+
)
|
|
41
|
+
)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* {@link addDecimalStrings}, or `undefined` with a warning when it throws.
|
|
46
|
+
* One bad value gives `undefined`, never a partial sum.
|
|
47
|
+
*
|
|
48
|
+
* @public
|
|
49
|
+
*/
|
|
50
|
+
export const safeAddDecimalStrings = createSafeFunction(
|
|
51
|
+
'addDecimalStrings',
|
|
52
|
+
addDecimalStrings
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Exact `a - b`.
|
|
57
|
+
*
|
|
58
|
+
* @throws {PerpsError} `ValidationError` when an input does not match the decimal pattern.
|
|
59
|
+
* @public
|
|
60
|
+
*/
|
|
61
|
+
export function subtractDecimalString(a: string, b: string): string {
|
|
62
|
+
return bigToDecimalString(decimalStringToBig(a).minus(decimalStringToBig(b)))
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* {@link subtractDecimalString}, or `undefined` with a warning when it throws.
|
|
67
|
+
*
|
|
68
|
+
* @public
|
|
69
|
+
*/
|
|
70
|
+
export const safeSubtractDecimalString = createSafeFunction(
|
|
71
|
+
'subtractDecimalString',
|
|
72
|
+
subtractDecimalString
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Exact `a × b`.
|
|
77
|
+
*
|
|
78
|
+
* @throws {PerpsError} `ValidationError` when an input does not match the decimal pattern.
|
|
79
|
+
* @public
|
|
80
|
+
*/
|
|
81
|
+
export function multiplyDecimalString(a: string, b: string): string {
|
|
82
|
+
return bigToDecimalString(decimalStringToBig(a).times(decimalStringToBig(b)))
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* {@link multiplyDecimalString}, or `undefined` with a warning when it throws.
|
|
87
|
+
*
|
|
88
|
+
* @public
|
|
89
|
+
*/
|
|
90
|
+
export const safeMultiplyDecimalString = createSafeFunction(
|
|
91
|
+
'multiplyDecimalString',
|
|
92
|
+
multiplyDecimalString
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
function requireNonZeroDivisor(divisor: string): Big {
|
|
96
|
+
const parsed = decimalStringToBig(divisor)
|
|
97
|
+
if (parsed.eq(0)) {
|
|
98
|
+
throw new PerpsError(
|
|
99
|
+
PerpsErrorCode.ValidationError,
|
|
100
|
+
`Division by zero: divisor '${divisor}'.`
|
|
101
|
+
)
|
|
102
|
+
}
|
|
103
|
+
return parsed
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* `a ÷ b` to 40 decimal places, rounded half up.
|
|
108
|
+
*
|
|
109
|
+
* @throws {PerpsError} `ValidationError` when an input does not match the
|
|
110
|
+
* decimal pattern or `b` is zero.
|
|
111
|
+
* @public
|
|
112
|
+
*/
|
|
113
|
+
export function divideDecimalString(a: string, b: string): string {
|
|
114
|
+
const divisor = requireNonZeroDivisor(b)
|
|
115
|
+
return bigToDecimalString(new DivBig(decimalStringToBig(a)).div(divisor))
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* {@link divideDecimalString}, or `undefined` with a warning when it throws.
|
|
120
|
+
*
|
|
121
|
+
* @public
|
|
122
|
+
*/
|
|
123
|
+
export const safeDivideDecimalString = createSafeFunction(
|
|
124
|
+
'divideDecimalString',
|
|
125
|
+
divideDecimalString
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* `a ÷ b` to 40 decimal places, truncated toward zero, so a derived amount
|
|
130
|
+
* never exceeds the exact quotient.
|
|
131
|
+
*
|
|
132
|
+
* @throws {PerpsError} `ValidationError` when an input does not match the
|
|
133
|
+
* decimal pattern or `b` is zero.
|
|
134
|
+
* @public
|
|
135
|
+
*/
|
|
136
|
+
export function divideDecimalStringRoundDown(a: string, b: string): string {
|
|
137
|
+
const divisor = requireNonZeroDivisor(b)
|
|
138
|
+
return bigToDecimalString(new TruncBig(decimalStringToBig(a)).div(divisor))
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* {@link divideDecimalStringRoundDown}, or `undefined` with a warning when it
|
|
143
|
+
* throws.
|
|
144
|
+
*
|
|
145
|
+
* @public
|
|
146
|
+
*/
|
|
147
|
+
export const safeDivideDecimalStringRoundDown = createSafeFunction(
|
|
148
|
+
'divideDecimalStringRoundDown',
|
|
149
|
+
divideDecimalStringRoundDown
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Exact `|value|`.
|
|
154
|
+
*
|
|
155
|
+
* @throws {PerpsError} `ValidationError` when `value` does not match the decimal pattern.
|
|
156
|
+
* @public
|
|
157
|
+
*/
|
|
158
|
+
export function absDecimalString(value: string): string {
|
|
159
|
+
return bigToDecimalString(decimalStringToBig(value).abs())
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* {@link absDecimalString}, or `undefined` with a warning when it throws.
|
|
164
|
+
*
|
|
165
|
+
* @public
|
|
166
|
+
*/
|
|
167
|
+
export const safeAbsDecimalString = createSafeFunction(
|
|
168
|
+
'absDecimalString',
|
|
169
|
+
absDecimalString
|
|
170
|
+
)
|
package/src/decimal/big.ts
CHANGED
|
@@ -14,8 +14,3 @@ DivBig.DP = 40
|
|
|
14
14
|
export const TruncBig = Big()
|
|
15
15
|
TruncBig.DP = 40
|
|
16
16
|
TruncBig.RM = Big.roundDown
|
|
17
|
-
|
|
18
|
-
/** True when every value is a finite number, so `new DivBig(value)` cannot throw. */
|
|
19
|
-
export function areFinite(...values: number[]): boolean {
|
|
20
|
-
return values.every(Number.isFinite)
|
|
21
|
-
}
|
package/src/decimal/compare.ts
CHANGED
|
@@ -1,17 +1,67 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
1
|
+
import { createSafeFunction } from '../utils/createSafeFunction.js'
|
|
2
|
+
import { decimalStringToBig } from './decimalStringToBig.js'
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* Exact `a > b` on two
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* Exact `a > b` on two decimal strings, with no float rounding, so a funds
|
|
6
|
+
* gate can tell `'1.0000000000000001'` from `'1'`. The other relations follow
|
|
7
|
+
* from it: `a <= b` is `!isDecimalStringGreaterThan(a, b)`.
|
|
8
8
|
*
|
|
9
|
-
* @throws {PerpsError} `ValidationError` when either operand
|
|
9
|
+
* @throws {PerpsError} `ValidationError` when either operand does not match the decimal pattern.
|
|
10
10
|
* @public
|
|
11
11
|
*/
|
|
12
|
-
export function isDecimalStringGreaterThan(
|
|
13
|
-
a
|
|
14
|
-
b: DecimalString
|
|
15
|
-
): boolean {
|
|
16
|
-
return requireDecimal(a, 'a').gt(requireDecimal(b, 'b'))
|
|
12
|
+
export function isDecimalStringGreaterThan(a: string, b: string): boolean {
|
|
13
|
+
return decimalStringToBig(a).gt(decimalStringToBig(b))
|
|
17
14
|
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* {@link isDecimalStringGreaterThan}, or `undefined` with a warning when it
|
|
18
|
+
* throws.
|
|
19
|
+
*
|
|
20
|
+
* @public
|
|
21
|
+
*/
|
|
22
|
+
export const safeIsDecimalStringGreaterThan = createSafeFunction(
|
|
23
|
+
'isDecimalStringGreaterThan',
|
|
24
|
+
isDecimalStringGreaterThan
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Exact `value == 0`, so a flat-position check never reads `'0.0'` as
|
|
29
|
+
* non-zero.
|
|
30
|
+
*
|
|
31
|
+
* @throws {PerpsError} `ValidationError` when `value` does not match the decimal pattern.
|
|
32
|
+
* @public
|
|
33
|
+
*/
|
|
34
|
+
export function isDecimalStringZero(value: string): boolean {
|
|
35
|
+
return decimalStringToBig(value).eq(0)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* {@link isDecimalStringZero}, or `undefined` with a warning when it throws.
|
|
40
|
+
*
|
|
41
|
+
* @public
|
|
42
|
+
*/
|
|
43
|
+
export const safeIsDecimalStringZero = createSafeFunction(
|
|
44
|
+
'isDecimalStringZero',
|
|
45
|
+
isDecimalStringZero
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Exact three-way compare for a sort: `-1` when `a < b`, `0` when equal, `1`
|
|
50
|
+
* when `a > b`.
|
|
51
|
+
*
|
|
52
|
+
* @throws {PerpsError} `ValidationError` when either operand does not match the decimal pattern.
|
|
53
|
+
* @public
|
|
54
|
+
*/
|
|
55
|
+
export function compareDecimalStrings(a: string, b: string): -1 | 0 | 1 {
|
|
56
|
+
return decimalStringToBig(a).cmp(decimalStringToBig(b))
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* {@link compareDecimalStrings}, or `undefined` with a warning when it throws.
|
|
61
|
+
*
|
|
62
|
+
* @public
|
|
63
|
+
*/
|
|
64
|
+
export const safeCompareDecimalStrings = createSafeFunction(
|
|
65
|
+
'compareDecimalStrings',
|
|
66
|
+
compareDecimalStrings
|
|
67
|
+
)
|
package/src/decimal/convert.ts
CHANGED
|
@@ -1,44 +1,92 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { PerpsErrorCode } from '@lifi/perps-types'
|
|
2
2
|
import Big from 'big.js'
|
|
3
3
|
import { formatUnits } from 'viem'
|
|
4
4
|
import { PerpsError } from '../errors/PerpsError.js'
|
|
5
|
-
import {
|
|
5
|
+
import { createSafeFunction } from '../utils/createSafeFunction.js'
|
|
6
|
+
import { bigToDecimalString, decimalStringToBig } from './decimalStringToBig.js'
|
|
7
|
+
import { isDecimalString } from './parse.js'
|
|
6
8
|
|
|
7
9
|
/**
|
|
8
|
-
* Off-grid resolution for {@link
|
|
9
|
-
* - `truncate
|
|
10
|
-
*
|
|
11
|
-
* - `round
|
|
12
|
-
*
|
|
10
|
+
* Off-grid resolution for {@link roundDecimalString}:
|
|
11
|
+
* - `truncate`: toward zero, for sizes and collateral amounts. The result
|
|
12
|
+
* never exceeds the caller's intent.
|
|
13
|
+
* - `round`: half away from zero, for prices, which snap to the nearest tick.
|
|
14
|
+
* - `up`: away from zero, for an amount that must cover a target.
|
|
13
15
|
* @public
|
|
14
16
|
*/
|
|
15
|
-
export type
|
|
17
|
+
export type DecimalRounding = 'truncate' | 'round' | 'up'
|
|
18
|
+
|
|
19
|
+
const BIG_ROUNDING = {
|
|
20
|
+
truncate: Big.roundDown,
|
|
21
|
+
round: Big.roundHalfUp,
|
|
22
|
+
up: Big.roundUp,
|
|
23
|
+
} as const
|
|
16
24
|
|
|
17
25
|
/**
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* per `rounding`; there is no silent default.
|
|
26
|
+
* Round a decimal string to `decimals` places with exact decimal arithmetic.
|
|
27
|
+
* The result has no trailing zeros: `roundDecimalString('1.50', 1, 'round')`
|
|
28
|
+
* is `'1.5'`.
|
|
22
29
|
*
|
|
23
|
-
* @throws {PerpsError} `ValidationError` when `value`
|
|
24
|
-
*
|
|
25
|
-
* result's magnitude exceeds `Number.MAX_SAFE_INTEGER`.
|
|
30
|
+
* @throws {PerpsError} `ValidationError` when `value` does not match the decimal pattern,
|
|
31
|
+
* or `decimals` is not a non-negative integer.
|
|
26
32
|
* @public
|
|
27
33
|
*/
|
|
28
|
-
export
|
|
29
|
-
value:
|
|
34
|
+
export function roundDecimalString(
|
|
35
|
+
value: string,
|
|
30
36
|
decimals: number,
|
|
31
|
-
rounding:
|
|
32
|
-
):
|
|
37
|
+
rounding: DecimalRounding
|
|
38
|
+
): string {
|
|
39
|
+
if (!Number.isInteger(decimals) || decimals < 0) {
|
|
40
|
+
throw new PerpsError(
|
|
41
|
+
PerpsErrorCode.ValidationError,
|
|
42
|
+
`Invalid decimals for rounding: ${decimals}`
|
|
43
|
+
)
|
|
44
|
+
}
|
|
45
|
+
return bigToDecimalString(
|
|
46
|
+
decimalStringToBig(value).round(decimals, BIG_ROUNDING[rounding])
|
|
47
|
+
)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* {@link roundDecimalString}, or `undefined` with a warning when it throws.
|
|
52
|
+
*
|
|
53
|
+
* @public
|
|
54
|
+
*/
|
|
55
|
+
export const safeRoundDecimalString = createSafeFunction(
|
|
56
|
+
'roundDecimalString',
|
|
57
|
+
roundDecimalString
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Scale a decimal string to an integer at `decimals` places in exact decimal
|
|
62
|
+
* arithmetic: `'0.29'` at 2 decimals is 29, never 28. Off-grid input resolves
|
|
63
|
+
* per `rounding`. No `$`, `%` or `,` is removed first.
|
|
64
|
+
*
|
|
65
|
+
* @throws {PerpsError} `ValidationError` when `value` does not match the decimal pattern,
|
|
66
|
+
* `decimals` is not a non-negative integer, or the result's magnitude
|
|
67
|
+
* exceeds `Number.MAX_SAFE_INTEGER`.
|
|
68
|
+
* @public
|
|
69
|
+
*/
|
|
70
|
+
export function decimalStringToScaledInteger(
|
|
71
|
+
value: string,
|
|
72
|
+
decimals: number,
|
|
73
|
+
rounding: DecimalRounding
|
|
74
|
+
): number {
|
|
75
|
+
if (!isDecimalString(value)) {
|
|
76
|
+
throw new PerpsError(
|
|
77
|
+
PerpsErrorCode.ValidationError,
|
|
78
|
+
`'${value}' does not match the decimal pattern.`
|
|
79
|
+
)
|
|
80
|
+
}
|
|
33
81
|
if (!Number.isInteger(decimals) || decimals < 0) {
|
|
34
82
|
throw new PerpsError(
|
|
35
83
|
PerpsErrorCode.ValidationError,
|
|
36
84
|
`Invalid decimals for integer scaling: ${decimals}`
|
|
37
85
|
)
|
|
38
86
|
}
|
|
39
|
-
const scaled =
|
|
87
|
+
const scaled = new Big(value)
|
|
40
88
|
.times(new Big(10).pow(decimals))
|
|
41
|
-
.round(0, rounding
|
|
89
|
+
.round(0, BIG_ROUNDING[rounding])
|
|
42
90
|
if (scaled.abs().gt(Number.MAX_SAFE_INTEGER)) {
|
|
43
91
|
throw new PerpsError(
|
|
44
92
|
PerpsErrorCode.ValidationError,
|
|
@@ -48,72 +96,56 @@ export const decimalToBaseUnits = (
|
|
|
48
96
|
return scaled.toNumber()
|
|
49
97
|
}
|
|
50
98
|
|
|
51
|
-
|
|
99
|
+
/**
|
|
100
|
+
* {@link decimalStringToScaledInteger}, or `undefined` with a warning when it
|
|
101
|
+
* throws.
|
|
102
|
+
*
|
|
103
|
+
* @public
|
|
104
|
+
*/
|
|
105
|
+
export const safeDecimalStringToScaledInteger = createSafeFunction(
|
|
106
|
+
'decimalStringToScaledInteger',
|
|
107
|
+
decimalStringToScaledInteger
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
export const BASE_UNITS_PATTERN = /^-?\d+$/
|
|
52
111
|
|
|
53
112
|
/**
|
|
54
|
-
* Convert a
|
|
113
|
+
* Convert a scaled integer string (a token amount in base units) to a decimal
|
|
114
|
+
* string: `scaledIntegerToDecimalString('1000000', 6)` is `'1'`.
|
|
55
115
|
*
|
|
56
|
-
* @param amount - Amount in base units (e.g. "1000000" for 1 USDC)
|
|
57
|
-
* @param decimals - Token decimals (e.g. 6 for USDC)
|
|
58
116
|
* @throws {PerpsError} `ValidationError` when `amount` is not an integer
|
|
59
117
|
* string, or `decimals` is not a non-negative integer.
|
|
60
|
-
* @example
|
|
61
|
-
* ```ts
|
|
62
|
-
* baseUnitsToDecimal('1000000', 6) // '1'
|
|
63
|
-
* ```
|
|
64
118
|
* @public
|
|
65
119
|
*/
|
|
66
|
-
export function
|
|
67
|
-
amount:
|
|
120
|
+
export function scaledIntegerToDecimalString(
|
|
121
|
+
amount: string,
|
|
68
122
|
decimals: number
|
|
69
|
-
):
|
|
123
|
+
): string {
|
|
70
124
|
if (!Number.isInteger(decimals) || decimals < 0) {
|
|
71
125
|
throw new PerpsError(
|
|
72
126
|
PerpsErrorCode.ValidationError,
|
|
73
|
-
`Invalid \`
|
|
127
|
+
`Invalid \`scaledIntegerToDecimalString(decimals)\`: ${decimals} is not a non-negative integer.`
|
|
74
128
|
)
|
|
75
129
|
}
|
|
76
130
|
if (!BASE_UNITS_PATTERN.test(amount)) {
|
|
77
131
|
throw new PerpsError(
|
|
78
132
|
PerpsErrorCode.ValidationError,
|
|
79
|
-
`Invalid \`
|
|
133
|
+
`Invalid \`scaledIntegerToDecimalString(amount)\`: '${amount}' is not an integer base-unit string.`
|
|
80
134
|
)
|
|
81
135
|
}
|
|
82
136
|
return formatUnits(BigInt(amount), decimals)
|
|
83
137
|
}
|
|
84
138
|
|
|
85
139
|
/**
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
* where `'500.00'` and `'500'` are two renderings of one amount and the field
|
|
89
|
-
* wants the first. For a canonical wire amount with no trailing zeros, read
|
|
90
|
-
* the amount off `calculateOrderAmounts` or a provider snap instead.
|
|
91
|
-
*
|
|
92
|
-
* Exact decimal arithmetic throughout, so there is no 2^53 ceiling and no
|
|
93
|
-
* float artifact: `'0.01'` at 18 decimals gives
|
|
94
|
-
* `'0.010000000000000000'`, which `Number#toFixed` cannot.
|
|
140
|
+
* {@link scaledIntegerToDecimalString}, or `undefined` with a warning when it
|
|
141
|
+
* throws.
|
|
95
142
|
*
|
|
96
|
-
* @throws {PerpsError} `ValidationError` when `value` is not a
|
|
97
|
-
* {@link DecimalString}, or `decimals` is not a non-negative integer.
|
|
98
143
|
* @public
|
|
99
144
|
*/
|
|
100
|
-
export
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
)
|
|
104
|
-
if (!Number.isInteger(decimals) || decimals < 0) {
|
|
105
|
-
throw new PerpsError(
|
|
106
|
-
PerpsErrorCode.ValidationError,
|
|
107
|
-
`Invalid decimals for truncation: ${decimals}`
|
|
108
|
-
)
|
|
109
|
-
}
|
|
110
|
-
const truncated = requireDecimal(value, 'truncateDecimal(value)').round(
|
|
111
|
-
decimals,
|
|
112
|
-
Big.roundDown
|
|
113
|
-
)
|
|
114
|
-
// big.js carries the sign through a round to zero; '-0.00' is not a spelling.
|
|
115
|
-
return (truncated.eq(0) ? new Big(0) : truncated).toFixed(decimals)
|
|
116
|
-
}
|
|
145
|
+
export const safeScaledIntegerToDecimalString = createSafeFunction(
|
|
146
|
+
'scaledIntegerToDecimalString',
|
|
147
|
+
scaledIntegerToDecimalString
|
|
148
|
+
)
|
|
117
149
|
|
|
118
150
|
/**
|
|
119
151
|
* Spell a `number` as a {@link DecimalString} in plain notation: `1e-7`
|
|
@@ -125,7 +157,7 @@ export function truncateDecimal(
|
|
|
125
157
|
* @throws {PerpsError} `ValidationError` when `value` is `NaN` or infinite.
|
|
126
158
|
* @public
|
|
127
159
|
*/
|
|
128
|
-
export function numberToDecimalString(value: number):
|
|
160
|
+
export function numberToDecimalString(value: number): string {
|
|
129
161
|
if (!Number.isFinite(value)) {
|
|
130
162
|
throw new PerpsError(
|
|
131
163
|
PerpsErrorCode.ValidationError,
|
|
@@ -135,3 +167,13 @@ export function numberToDecimalString(value: number): DecimalString {
|
|
|
135
167
|
const parsed = new Big(value)
|
|
136
168
|
return (parsed.eq(0) ? new Big(0) : parsed).toFixed()
|
|
137
169
|
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* {@link numberToDecimalString}, or `undefined` with a warning when it throws.
|
|
173
|
+
*
|
|
174
|
+
* @public
|
|
175
|
+
*/
|
|
176
|
+
export const safeNumberToDecimalString = createSafeFunction(
|
|
177
|
+
'numberToDecimalString',
|
|
178
|
+
numberToDecimalString
|
|
179
|
+
)
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { DECIMAL_PATTERN, PerpsErrorCode } from '@lifi/perps-types'
|
|
2
|
+
import Big from 'big.js'
|
|
3
|
+
import { PerpsError } from '../errors/PerpsError.js'
|
|
4
|
+
import { DivBig } from './big.js'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Read a decimal string as a `Big`. The string must match `DECIMAL_PATTERN`,
|
|
8
|
+
* so `'$1,234.5'`, `'0.05%'` and the exponent form `'1e5'` are rejected.
|
|
9
|
+
*
|
|
10
|
+
* @throws {PerpsError} `ValidationError` when `value` does not match the
|
|
11
|
+
* decimal pattern.
|
|
12
|
+
* @internal
|
|
13
|
+
*/
|
|
14
|
+
export function decimalStringToBig(value: string): Big {
|
|
15
|
+
if (typeof value !== 'string' || !DECIMAL_PATTERN.test(value)) {
|
|
16
|
+
throw new PerpsError(
|
|
17
|
+
PerpsErrorCode.ValidationError,
|
|
18
|
+
`'${String(value)}' does not match the decimal pattern.`
|
|
19
|
+
)
|
|
20
|
+
}
|
|
21
|
+
return new Big(value)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Spell a `Big` as a canonical decimal string, with no exponent and no `-0`.
|
|
26
|
+
*
|
|
27
|
+
* @internal
|
|
28
|
+
*/
|
|
29
|
+
export function bigToDecimalString(value: Big): string {
|
|
30
|
+
return value.eq(0) ? '0' : value.toFixed()
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* {@link decimalStringToBig} as a `DivBig`, so a later `div` keeps 40 decimal
|
|
35
|
+
* places.
|
|
36
|
+
*
|
|
37
|
+
* @throws {PerpsError} `ValidationError` as {@link decimalStringToBig}.
|
|
38
|
+
* @internal
|
|
39
|
+
*/
|
|
40
|
+
export function decimalStringToDivBig(value: string): Big {
|
|
41
|
+
return new DivBig(decimalStringToBig(value))
|
|
42
|
+
}
|