@vultisig/rujira 1.0.0 → 4.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/CHANGELOG.md CHANGED
@@ -1,5 +1,33 @@
1
1
  # @vultisig/rujira
2
2
 
3
+ ## 4.0.0
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [[`da88c6f`](https://github.com/vultisig/vultisig-sdk/commit/da88c6f06b8d74ccb5642f793e386d85ff6f30b1), [`4b29636`](https://github.com/vultisig/vultisig-sdk/commit/4b29636514edccf0980eddf5e8fffacfcb31c88f), [`7677523`](https://github.com/vultisig/vultisig-sdk/commit/76775232866dccf4e1e85aa0fe0d91c2fd8fdddb)]:
8
+ - @vultisig/sdk@0.8.0
9
+
10
+ ## 3.0.0
11
+
12
+ ### Patch Changes
13
+
14
+ - Updated dependencies [[`da68dda`](https://github.com/vultisig/vultisig-sdk/commit/da68dda0622a024af35666bb7b7088dea4cf3cfd)]:
15
+ - @vultisig/sdk@0.7.0
16
+
17
+ ## 2.0.0
18
+
19
+ ### Patch Changes
20
+
21
+ - [#107](https://github.com/vultisig/vultisig-sdk/pull/107) [`117cd70`](https://github.com/vultisig/vultisig-sdk/commit/117cd705271305269acce5436a2845decd98dc90) Thanks [@vultisigsdkbot](https://github.com/vultisigsdkbot)! - Fix price impact calculation returning hardcoded 50% for small trades on deep pairs
22
+ - Remove hardcoded 50% cap on price impact values
23
+ - Add bidirectional price comparison to handle both swap directions correctly
24
+ (buying base vs selling base relative to orderbook convention)
25
+ - Return 'unknown' instead of guessed ranges when orderbook data is unavailable
26
+ - Return 'unknown' when calculated impact exceeds 99% (likely unit mismatch)
27
+
28
+ - Updated dependencies [[`355c700`](https://github.com/vultisig/vultisig-sdk/commit/355c700e7caca812199fafceb3767b8b3c5fd236), [`78f8bd2`](https://github.com/vultisig/vultisig-sdk/commit/78f8bd237dc3ca6f42dd268d069ed8f7902e733b), [`26d3cae`](https://github.com/vultisig/vultisig-sdk/commit/26d3cae3066a316d1e9429a2664a6b4ea18dd8a2), [`2ed545f`](https://github.com/vultisig/vultisig-sdk/commit/2ed545fb20f5920cb70d096076d55756cea222aa), [`a2d545b`](https://github.com/vultisig/vultisig-sdk/commit/a2d545b96794cce087eb4ea8ce955db20212c926), [`f5176ba`](https://github.com/vultisig/vultisig-sdk/commit/f5176ba4a9fda2c82b6264a958d61d5170e3d2cd)]:
29
+ - @vultisig/sdk@0.6.0
30
+
3
31
  ## 1.0.0
4
32
 
5
33
  ### Minor Changes
@@ -1 +1 @@
1
- {"version":3,"file":"swap.d.ts","sourceRoot":"","sources":["../../src/modules/swap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAA;AAI5C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAChD,OAAO,EAAe,KAAK,aAAa,EAAE,KAAK,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAGzF,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACjG,OAAO,EAAc,KAAK,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAKtE,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,CAAC,EAAE,iBAAiB,GAAG,KAAK,CAAA;IACjC,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,gHAAgH;IAChH,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB,CAAA;AAED,qBAAa,UAAU;IAQnB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAPzB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA8B;IACzD,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAQ;IAC5C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAQ;IACnC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAQ;IACzC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAQ;gBAGnB,MAAM,EAAE,YAAY,EACrC,OAAO,GAAE,iBAAsB;IASjC,UAAU,IAAI,IAAI;IAIlB,aAAa,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAIlE,QAAQ,CACZ,MAAM,EAAE,WAAW,EACnB,OAAO,GAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAe,GAC1E,OAAO,CAAC,SAAS,CAAC;IAiGf,OAAO,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,UAAU,CAAC;IAoDzE,WAAW,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,UAAU,CAAC;IAKhF,gBAAgB,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC;QACnD,eAAe,EAAE,MAAM,CAAA;QACvB,GAAG,EAAE,aAAa,CAAA;QAClB,KAAK,EAAE,IAAI,EAAE,CAAA;KACd,CAAC;IAoCI,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC;IAMjD,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,UAAU,CAAC;IA2CvD,cAAc,CAClB,MAAM,EAAE,aAAa,EAAE,EACvB,MAAM,EAAE,MAAM,EACd,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,SAAS,GAAG,IAAI,CAAC,CAAC;IAqC1C,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,SAAS,GAAG,IAAI,CAAC,CAAC;IAK5G,OAAO,CAAC,sBAAsB;YAOhB,YAAY;IAiC1B,OAAO,CAAC,mBAAmB;YAoCb,eAAe;CA6B9B"}
1
+ {"version":3,"file":"swap.d.ts","sourceRoot":"","sources":["../../src/modules/swap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAA;AAI5C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAChD,OAAO,EAAe,KAAK,aAAa,EAAE,KAAK,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAGzF,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACjG,OAAO,EAAc,KAAK,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAKtE,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,CAAC,EAAE,iBAAiB,GAAG,KAAK,CAAA;IACjC,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,gHAAgH;IAChH,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB,CAAA;AAED,qBAAa,UAAU;IAQnB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAPzB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA8B;IACzD,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAQ;IAC5C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAQ;IACnC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAQ;IACzC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAQ;gBAGnB,MAAM,EAAE,YAAY,EACrC,OAAO,GAAE,iBAAsB;IASjC,UAAU,IAAI,IAAI;IAIlB,aAAa,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAIlE,QAAQ,CACZ,MAAM,EAAE,WAAW,EACnB,OAAO,GAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAe,GAC1E,OAAO,CAAC,SAAS,CAAC;IA4Gf,OAAO,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,UAAU,CAAC;IAoDzE,WAAW,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,UAAU,CAAC;IAKhF,gBAAgB,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC;QACnD,eAAe,EAAE,MAAM,CAAA;QACvB,GAAG,EAAE,aAAa,CAAA;QAClB,KAAK,EAAE,IAAI,EAAE,CAAA;KACd,CAAC;IAoCI,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC;IAMjD,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,UAAU,CAAC;IA2CvD,cAAc,CAClB,MAAM,EAAE,aAAa,EAAE,EACvB,MAAM,EAAE,MAAM,EACd,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,SAAS,GAAG,IAAI,CAAC,CAAC;IAqC1C,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,SAAS,GAAG,IAAI,CAAC,CAAC;IAK5G,OAAO,CAAC,sBAAsB;YAOhB,YAAY;IAiC1B,OAAO,CAAC,mBAAmB;YAoCb,eAAe;CA6B9B"}
@@ -74,7 +74,17 @@ export class RujiraSwap {
74
74
  const rate = outputAmount.gt(0)
75
75
  ? inputAmount.mul(100000000).div(outputAmount).toFixed(0, 0) // round down
76
76
  : '0';
77
- const priceImpact = calculatePriceImpact(params.amount, simulation.returned, orderbook);
77
+ // Determine if swap direction is reversed relative to orderbook's base/quote convention
78
+ // Reversed = buying base (input is quote asset, output is base asset)
79
+ const reversedToOrderbook = orderbook
80
+ ? params.fromAsset === orderbook.pair.quote || params.toAsset === orderbook.pair.base
81
+ : false;
82
+ const priceImpact = calculatePriceImpact({
83
+ inputAmount: params.amount,
84
+ outputAmount: simulation.returned,
85
+ orderbook,
86
+ reversedToOrderbook,
87
+ });
78
88
  const priceImpactEstimated = !orderbook || !orderbook.bids[0]?.price || !orderbook.asks[0]?.price;
79
89
  const quote = {
80
90
  params,
@@ -3,9 +3,31 @@
3
3
  * @module services/price-impact
4
4
  */
5
5
  import type { OrderBook } from '../types.js';
6
+ /**
7
+ * Input for calculatePriceImpact function.
8
+ */
9
+ export type CalculatePriceImpactInput = {
10
+ inputAmount: string;
11
+ outputAmount: string;
12
+ orderbook: OrderBook | null;
13
+ /**
14
+ * True when the swap direction is reversed relative to the orderbook's
15
+ * base/quote convention (i.e., swapping quote → base instead of base → quote).
16
+ */
17
+ reversedToOrderbook: boolean;
18
+ };
6
19
  /**
7
20
  * Calculate price impact for a swap using orderbook data when available.
8
- * Falls back to heuristic estimates when orderbook data is unavailable.
21
+ *
22
+ * The swap direction may not match the orderbook's base/quote convention:
23
+ * - Selling base (input=base, output=quote): executionPrice = output/input ≈ midPrice
24
+ * - Buying base (input=quote, output=base): executionPrice = input/output ≈ midPrice
25
+ *
26
+ * The caller must specify `reversedToOrderbook` to indicate whether the swap
27
+ * is in the opposite direction of the orderbook's base/quote pair.
28
+ *
29
+ * Returns 'unknown' when orderbook data is unavailable or when the
30
+ * calculation cannot determine a reliable impact value.
9
31
  */
10
- export declare function calculatePriceImpact(inputAmount: string, outputAmount: string, orderbook: OrderBook | null): string;
32
+ export declare function calculatePriceImpact({ inputAmount, outputAmount, orderbook, reversedToOrderbook, }: CalculatePriceImpactInput): string;
11
33
  //# sourceMappingURL=price-impact.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"price-impact.d.ts","sourceRoot":"","sources":["../../src/services/price-impact.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,SAAS,GAAG,IAAI,GAC1B,MAAM,CA6CR"}
1
+ {"version":3,"file":"price-impact.d.ts","sourceRoot":"","sources":["../../src/services/price-impact.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C;;GAEG;AACH,MAAM,MAAM,yBAAyB,GAAG;IACtC,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC;IAC5B;;;OAGG;IACH,mBAAmB,EAAE,OAAO,CAAC;CAC9B,CAAC;AAaF;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,WAAW,EACX,YAAY,EACZ,SAAS,EACT,mBAAmB,GACpB,EAAE,yBAAyB,GAAG,MAAM,CAyCpC"}
@@ -3,56 +3,58 @@
3
3
  * @module services/price-impact
4
4
  */
5
5
  import Big from 'big.js';
6
- import { LARGE_SWAP_THRESHOLD } from '../config/constants.js';
6
+ /**
7
+ * Safely parse a string into a Big number, returning null on failure.
8
+ */
9
+ function safeBig(value) {
10
+ try {
11
+ return Big(value);
12
+ }
13
+ catch {
14
+ return null;
15
+ }
16
+ }
7
17
  /**
8
18
  * Calculate price impact for a swap using orderbook data when available.
9
- * Falls back to heuristic estimates when orderbook data is unavailable.
19
+ *
20
+ * The swap direction may not match the orderbook's base/quote convention:
21
+ * - Selling base (input=base, output=quote): executionPrice = output/input ≈ midPrice
22
+ * - Buying base (input=quote, output=base): executionPrice = input/output ≈ midPrice
23
+ *
24
+ * The caller must specify `reversedToOrderbook` to indicate whether the swap
25
+ * is in the opposite direction of the orderbook's base/quote pair.
26
+ *
27
+ * Returns 'unknown' when orderbook data is unavailable or when the
28
+ * calculation cannot determine a reliable impact value.
10
29
  */
11
- export function calculatePriceImpact(inputAmount, outputAmount, orderbook) {
30
+ export function calculatePriceImpact({ inputAmount, outputAmount, orderbook, reversedToOrderbook, }) {
12
31
  if (!orderbook) {
13
- return estimatePriceImpactWithoutOrderbook(inputAmount);
32
+ return 'unknown';
14
33
  }
15
34
  const bestBid = orderbook.bids[0]?.price;
16
35
  const bestAsk = orderbook.asks[0]?.price;
17
36
  if (!bestBid || !bestAsk) {
18
- return estimatePriceImpactWithoutOrderbook(inputAmount);
37
+ return 'unknown';
19
38
  }
20
- const bidPrice = Big(bestBid);
21
- const askPrice = Big(bestAsk);
22
- if (bidPrice.lte(0) || askPrice.lte(0)) {
23
- return '0';
39
+ const bidPrice = safeBig(bestBid);
40
+ const askPrice = safeBig(bestAsk);
41
+ if (!bidPrice || !askPrice || bidPrice.lte(0) || askPrice.lte(0)) {
42
+ return 'unknown';
24
43
  }
25
44
  const midPrice = bidPrice.plus(askPrice).div(2);
26
- const input = Big(inputAmount);
27
- const output = Big(outputAmount);
28
- if (input.lte(0) || output.lte(0)) {
29
- return '0';
30
- }
31
- // execution_price = output / input
32
- const executionPrice = output.div(input);
33
- // Detect unit mismatch from reversed-pair contract
34
- const ratio = executionPrice.div(midPrice);
35
- if (ratio.gt(100) || ratio.lt(0.01)) {
45
+ const input = safeBig(inputAmount);
46
+ const output = safeBig(outputAmount);
47
+ if (!input || !output || input.lte(0) || output.lte(0)) {
36
48
  return 'unknown';
37
49
  }
38
- // impact = abs((execution_price - midPrice) / midPrice) * 100
50
+ // Calculate execution price based on swap direction relative to orderbook:
51
+ // - Direct (selling base): executionPrice = output / input
52
+ // - Reversed (buying base): executionPrice = input / output
53
+ const executionPrice = reversedToOrderbook ? input.div(output) : output.div(input);
39
54
  const impact = executionPrice.minus(midPrice).div(midPrice).abs().mul(100);
40
- if (impact.gt(50)) {
41
- return '50.00';
42
- }
43
- return impact.toFixed(4);
44
- }
45
- /**
46
- * Estimate price impact heuristically when orderbook data is unavailable.
47
- */
48
- function estimatePriceImpactWithoutOrderbook(inputAmount) {
49
- const amount = BigInt(inputAmount);
50
- if (amount >= LARGE_SWAP_THRESHOLD) {
55
+ // If impact is unreasonably high, report as unknown
56
+ if (impact.gt(99)) {
51
57
  return 'unknown';
52
58
  }
53
- const mediumSwapThreshold = BigInt('100000000000');
54
- if (amount >= mediumSwapThreshold) {
55
- return '2.0-5.0';
56
- }
57
- return '1.0-3.0';
59
+ return impact.toFixed(4);
58
60
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vultisig/rujira",
3
- "version": "1.0.0",
3
+ "version": "4.0.0",
4
4
  "type": "module",
5
5
  "description": "Rujira DEX integration for Vultisig SDK - Modular TypeScript SDK for swaps and limit orders on THORChain",
6
6
  "main": "./dist/index.js",
@@ -45,22 +45,22 @@
45
45
  "typecheck": "tsc --noEmit"
46
46
  },
47
47
  "dependencies": {
48
- "@bufbuild/protobuf": "^2.10.2",
49
- "@cosmjs/cosmwasm-stargate": "^0.32.4",
50
- "@cosmjs/proto-signing": "^0.32.4",
51
- "@cosmjs/stargate": "^0.32.4",
48
+ "@bufbuild/protobuf": "^2.11.0",
49
+ "@cosmjs/cosmwasm-stargate": "^0.38.1",
50
+ "@cosmjs/proto-signing": "^0.38.1",
51
+ "@cosmjs/stargate": "^0.38.1",
52
52
  "big.js": "^7.0.1",
53
- "cosmjs-types": "^0.9.0"
53
+ "cosmjs-types": "^0.11.0"
54
54
  },
55
55
  "devDependencies": {
56
56
  "@types/big.js": "^6.2.2",
57
- "@types/node": "^22.13.10",
58
- "@vultisig/sdk": "0.5.0",
59
- "typescript": "^5.8.2",
57
+ "@types/node": "^25.5.0",
58
+ "@vultisig/sdk": "0.8.0",
59
+ "typescript": "^5.9.3",
60
60
  "vitest": "^3.0.9"
61
61
  },
62
62
  "peerDependencies": {
63
- "@vultisig/sdk": ">=0.5.0"
63
+ "@vultisig/sdk": ">=0.8.0"
64
64
  },
65
65
  "peerDependenciesMeta": {
66
66
  "@vultisig/sdk": {