@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;
|
|
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"}
|
package/dist/modules/swap.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
*
|
|
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
|
|
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;
|
|
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
|
-
|
|
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
|
-
*
|
|
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
|
|
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
|
|
37
|
+
return 'unknown';
|
|
19
38
|
}
|
|
20
|
-
const bidPrice =
|
|
21
|
-
const askPrice =
|
|
22
|
-
if (bidPrice.lte(0) || askPrice.lte(0)) {
|
|
23
|
-
return '
|
|
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 =
|
|
27
|
-
const output =
|
|
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
|
-
//
|
|
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
|
-
|
|
41
|
-
|
|
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
|
-
|
|
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": "
|
|
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.
|
|
49
|
-
"@cosmjs/cosmwasm-stargate": "^0.
|
|
50
|
-
"@cosmjs/proto-signing": "^0.
|
|
51
|
-
"@cosmjs/stargate": "^0.
|
|
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.
|
|
53
|
+
"cosmjs-types": "^0.11.0"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
56
|
"@types/big.js": "^6.2.2",
|
|
57
|
-
"@types/node": "^
|
|
58
|
-
"@vultisig/sdk": "0.
|
|
59
|
-
"typescript": "^5.
|
|
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.
|
|
63
|
+
"@vultisig/sdk": ">=0.8.0"
|
|
64
64
|
},
|
|
65
65
|
"peerDependenciesMeta": {
|
|
66
66
|
"@vultisig/sdk": {
|