@vultisig/core-chain 2.13.0 → 2.14.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,11 @@
1
1
  # @vultisig/core-chain
2
2
 
3
+ ## 2.14.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#676](https://github.com/vultisig/vultisig-sdk/pull/676) [`7572dc0`](https://github.com/vultisig/vultisig-sdk/commit/7572dc0e7fa785453e36a419d678f8a1bf17c8b5) Thanks [@rcoderdev](https://github.com/rcoderdev)! - Add THORChain limit swap memo builder, validation helpers, and JSON test vectors.
8
+
3
9
  ## 2.13.0
4
10
 
5
11
  ### Minor Changes
@@ -0,0 +1,20 @@
1
+ export declare const limitSwapExpiryHours: readonly [12, 24, 72];
2
+ export type LimitSwapExpiryHours = (typeof limitSwapExpiryHours)[number];
3
+ export type LimitSwapNumericInput = bigint | number | string;
4
+ export type LimitSwapMemoInput = {
5
+ source_asset: string;
6
+ source_amount: LimitSwapNumericInput;
7
+ target_asset: string;
8
+ dest_addr: string;
9
+ target_price: LimitSwapNumericInput;
10
+ expiry_hours: LimitSwapExpiryHours;
11
+ };
12
+ export type LimitSwapSourceChainKind = 'utxo' | 'other';
13
+ export declare const limitSwapMemoByteLimit: Record<LimitSwapSourceChainKind, number>;
14
+ export declare const getLimitSwapSourceChainKind: (sourceAsset: string) => LimitSwapSourceChainKind;
15
+ export declare const getLimitSwapIntervalBlocks: (expiryHours: LimitSwapExpiryHours) => number;
16
+ export declare const getLimitSwapLimitAmount: ({ source_amount, target_price, }: Pick<LimitSwapMemoInput, "source_amount" | "target_price">) => bigint;
17
+ export declare const assertMemoByteLength: (memo: string, sourceChainKind: LimitSwapSourceChainKind) => void;
18
+ export declare const validateLimitSwapInputs: (inputs: LimitSwapMemoInput) => void;
19
+ export declare const buildLimitSwapMemo: (inputs: LimitSwapMemoInput) => string;
20
+ //# sourceMappingURL=limitSwapMemo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"limitSwapMemo.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/chain/swap/native/limitSwapMemo.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,oBAAoB,uBAAwB,CAAA;AACzD,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAA;AAExE,MAAM,MAAM,qBAAqB,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAA;AAE5D,MAAM,MAAM,kBAAkB,GAAG;IAC/B,YAAY,EAAE,MAAM,CAAA;IACpB,aAAa,EAAE,qBAAqB,CAAA;IACpC,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,YAAY,EAAE,qBAAqB,CAAA;IACnC,YAAY,EAAE,oBAAoB,CAAA;CACnC,CAAA;AAED,MAAM,MAAM,wBAAwB,GAAG,MAAM,GAAG,OAAO,CAAA;AAEvD,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,wBAAwB,EAAE,MAAM,CAG3E,CAAA;AA8FD,eAAO,MAAM,2BAA2B,GAAI,aAAa,MAAM,KAAG,wBAGjE,CAAA;AAED,eAAO,MAAM,0BAA0B,GAAI,aAAa,oBAAoB,KAAG,MAM9E,CAAA;AAED,eAAO,MAAM,uBAAuB,GAAI,kCAGrC,IAAI,CAAC,kBAAkB,EAAE,eAAe,GAAG,cAAc,CAAC,KAAG,MAK/D,CAAA;AAED,eAAO,MAAM,oBAAoB,GAAI,MAAM,MAAM,EAAE,iBAAiB,wBAAwB,KAAG,IAU9F,CAAA;AAkDD,eAAO,MAAM,uBAAuB,GAAI,QAAQ,kBAAkB,KAAG,IASpE,CAAA;AAUD,eAAO,MAAM,kBAAkB,GAAI,QAAQ,kBAAkB,KAAG,MAmB/D,CAAA"}
@@ -0,0 +1,193 @@
1
+ import { fromBech32 } from '@cosmjs/encoding';
2
+ import { Chain } from '../../Chain.js';
3
+ import { getChainKind } from '../../ChainKind.js';
4
+ import { chainPrefixToChain } from '../../chains/cosmos/thor/lp/lpChainMap.js';
5
+ import { assertValidPoolId } from '../../chains/cosmos/thor/lp/pools.js';
6
+ import { baseAffiliateBps } from '../affiliate/config.js';
7
+ import { nativeSwapAffiliateConfig } from './nativeSwapAffiliateConfig.js';
8
+ export const limitSwapExpiryHours = [12, 24, 72];
9
+ export const limitSwapMemoByteLimit = {
10
+ utxo: 80,
11
+ other: 250,
12
+ };
13
+ const priceScale = 100000000n;
14
+ const expiryHoursToIntervalBlocks = {
15
+ 12: 7_200,
16
+ 24: 14_400,
17
+ 72: 43_200,
18
+ };
19
+ const assertMemoSegmentSafe = (value, fieldName) => {
20
+ if (typeof value !== 'string' || value.length === 0) {
21
+ throw new Error(`${fieldName} must be a non-empty string`);
22
+ }
23
+ if (value.includes(':') || value.includes('/')) {
24
+ throw new Error(`${fieldName} must not contain memo separators ":" or "/"`);
25
+ }
26
+ if (/\s/.test(value)) {
27
+ throw new Error(`${fieldName} must not contain whitespace`);
28
+ }
29
+ if (!/^[\x21-\x7E]+$/.test(value)) {
30
+ throw new Error(`${fieldName} must contain printable ASCII characters only`);
31
+ }
32
+ };
33
+ const getAssetChainPrefix = (asset) => {
34
+ const [prefix] = asset.split('.');
35
+ return prefix;
36
+ };
37
+ const getSupportedThorchainAssetChain = (asset, fieldName) => {
38
+ assertValidPoolId(asset);
39
+ const prefix = getAssetChainPrefix(asset);
40
+ const chain = chainPrefixToChain(prefix);
41
+ if (!chain) {
42
+ throw new Error(`${fieldName} has unsupported THORChain asset prefix: ${prefix}`);
43
+ }
44
+ return chain;
45
+ };
46
+ const parsePositiveInteger = (value, fieldName) => {
47
+ if (typeof value === 'bigint') {
48
+ if (value > 0n)
49
+ return value;
50
+ throw new Error(`${fieldName} must be greater than 0`);
51
+ }
52
+ if (typeof value === 'number') {
53
+ if (Number.isSafeInteger(value) && value > 0)
54
+ return BigInt(value);
55
+ throw new Error(`${fieldName} must be a positive safe integer`);
56
+ }
57
+ const normalized = value.trim();
58
+ if (!/^[1-9]\d*$/.test(normalized)) {
59
+ throw new Error(`${fieldName} must be a positive integer string`);
60
+ }
61
+ return BigInt(normalized);
62
+ };
63
+ const parsePositiveDecimal = (value, fieldName) => {
64
+ if (typeof value === 'bigint') {
65
+ if (value > 0n)
66
+ return value * priceScale;
67
+ throw new Error(`${fieldName} must be greater than 0`);
68
+ }
69
+ let normalized;
70
+ if (typeof value === 'number') {
71
+ if (!Number.isFinite(value) || value <= 0) {
72
+ throw new Error(`${fieldName} must be greater than 0`);
73
+ }
74
+ normalized = value.toString();
75
+ if (normalized.includes('e')) {
76
+ normalized = value.toFixed(8);
77
+ }
78
+ if (Number(normalized) !== value) {
79
+ throw new Error(`${fieldName} must be a positive decimal with at most 8 fractional digits`);
80
+ }
81
+ }
82
+ else {
83
+ normalized = value.trim();
84
+ }
85
+ const match = normalized.match(/^(\d+)(?:\.(\d{1,8})?)?$/);
86
+ if (!match) {
87
+ throw new Error(`${fieldName} must be a positive decimal with at most 8 fractional digits`);
88
+ }
89
+ const [, whole, fractional = ''] = match;
90
+ const scaled = BigInt(whole) * priceScale + BigInt(fractional.padEnd(8, '0'));
91
+ if (scaled <= 0n) {
92
+ throw new Error(`${fieldName} must be greater than 0`);
93
+ }
94
+ return scaled;
95
+ };
96
+ export const getLimitSwapSourceChainKind = (sourceAsset) => {
97
+ const chain = getSupportedThorchainAssetChain(sourceAsset, 'source_asset');
98
+ return getChainKind(chain) === 'utxo' ? 'utxo' : 'other';
99
+ };
100
+ export const getLimitSwapIntervalBlocks = (expiryHours) => {
101
+ const interval = expiryHoursToIntervalBlocks[expiryHours];
102
+ if (!interval) {
103
+ throw new Error(`expiry_hours must be one of ${limitSwapExpiryHours.join(', ')}, got ${expiryHours}`);
104
+ }
105
+ return interval;
106
+ };
107
+ export const getLimitSwapLimitAmount = ({ source_amount, target_price, }) => {
108
+ const sourceAmount = parsePositiveInteger(source_amount, 'source_amount');
109
+ const targetPrice = parsePositiveDecimal(target_price, 'target_price');
110
+ return (sourceAmount * targetPrice) / priceScale;
111
+ };
112
+ export const assertMemoByteLength = (memo, sourceChainKind) => {
113
+ const limit = limitSwapMemoByteLimit[sourceChainKind];
114
+ if (!limit) {
115
+ throw new Error(`Unknown source chain kind: ${sourceChainKind}`);
116
+ }
117
+ const byteLength = new TextEncoder().encode(memo).length;
118
+ if (byteLength > limit) {
119
+ throw new Error(`THORChain limit swap memo is ${byteLength} bytes, exceeding ${sourceChainKind} limit ${limit}`);
120
+ }
121
+ };
122
+ const base58AddressChars = '1-9A-HJ-NP-Za-km-z';
123
+ const isBech32Address = (address, prefix) => {
124
+ try {
125
+ const decoded = fromBech32(address);
126
+ return decoded.prefix === prefix && decoded.data.length > 0;
127
+ }
128
+ catch {
129
+ return false;
130
+ }
131
+ };
132
+ const isEvmAddress = (address) => /^0x[0-9a-fA-F]{40}$/.test(address);
133
+ const limitSwapDestinationValidators = {
134
+ [Chain.Arbitrum]: isEvmAddress,
135
+ [Chain.Avalanche]: isEvmAddress,
136
+ [Chain.Base]: isEvmAddress,
137
+ [Chain.BSC]: isEvmAddress,
138
+ [Chain.Ethereum]: isEvmAddress,
139
+ [Chain.Bitcoin]: address => new RegExp(`^(bc1[ac-hj-np-z02-9]{11,71}|[13][${base58AddressChars}]{25,34})$`, 'i').test(address),
140
+ [Chain.BitcoinCash]: address => new RegExp(`^([qp][0-9a-z]{41}|[13][${base58AddressChars}]{25,34})$`, 'i').test(address),
141
+ [Chain.Dash]: address => new RegExp(`^X[${base58AddressChars}]{33}$`).test(address),
142
+ [Chain.Dogecoin]: address => new RegExp(`^D[5-9A-HJ-NP-U][${base58AddressChars}]{32}$`).test(address),
143
+ [Chain.Litecoin]: address => new RegExp(`^(ltc1[ac-hj-np-z02-9]{11,71}|[LM3][${base58AddressChars}]{25,34})$`, 'i').test(address),
144
+ [Chain.Zcash]: address => new RegExp(`^t[13][${base58AddressChars}]{33}$`).test(address),
145
+ [Chain.Cosmos]: address => isBech32Address(address, 'cosmos'),
146
+ [Chain.Kujira]: address => isBech32Address(address, 'kujira'),
147
+ [Chain.THORChain]: address => isBech32Address(address, 'thor'),
148
+ [Chain.Ripple]: address => new RegExp(`^r[${base58AddressChars}]{24,34}$`).test(address),
149
+ [Chain.Tron]: address => new RegExp(`^T[${base58AddressChars}]{33}$`).test(address),
150
+ };
151
+ const assertValidLimitSwapDestinationAddress = (targetChain, address) => {
152
+ const validator = limitSwapDestinationValidators[targetChain];
153
+ if (!validator) {
154
+ throw new Error(`target_asset chain ${targetChain} is not supported for limit swap destinations`);
155
+ }
156
+ if (!validator(address)) {
157
+ throw new Error(`dest_addr is not a valid ${targetChain} address`);
158
+ }
159
+ };
160
+ export const validateLimitSwapInputs = (inputs) => {
161
+ getSupportedThorchainAssetChain(inputs.source_asset, 'source_asset');
162
+ const targetChain = getSupportedThorchainAssetChain(inputs.target_asset, 'target_asset');
163
+ assertMemoSegmentSafe(inputs.dest_addr, 'dest_addr');
164
+ assertValidLimitSwapDestinationAddress(targetChain, inputs.dest_addr);
165
+ parsePositiveInteger(inputs.source_amount, 'source_amount');
166
+ parsePositiveDecimal(inputs.target_price, 'target_price');
167
+ getLimitSwapIntervalBlocks(inputs.expiry_hours);
168
+ };
169
+ const buildMemo = (inputs, includeAffiliate) => {
170
+ const limit = getLimitSwapLimitAmount(inputs);
171
+ const interval = getLimitSwapIntervalBlocks(inputs.expiry_hours);
172
+ const memo = `=<:${inputs.target_asset}:${inputs.dest_addr}:${limit}/${interval}/0`;
173
+ return includeAffiliate ? `${memo}:${nativeSwapAffiliateConfig.affiliateFeeAddress}:${baseAffiliateBps}` : memo;
174
+ };
175
+ export const buildLimitSwapMemo = (inputs) => {
176
+ validateLimitSwapInputs(inputs);
177
+ const sourceChainKind = getLimitSwapSourceChainKind(inputs.source_asset);
178
+ const affiliateMemo = buildMemo(inputs, true);
179
+ if (sourceChainKind === 'utxo') {
180
+ try {
181
+ assertMemoByteLength(affiliateMemo, sourceChainKind);
182
+ return affiliateMemo;
183
+ }
184
+ catch {
185
+ const memoWithoutAffiliate = buildMemo(inputs, false);
186
+ assertMemoByteLength(memoWithoutAffiliate, sourceChainKind);
187
+ return memoWithoutAffiliate;
188
+ }
189
+ }
190
+ assertMemoByteLength(affiliateMemo, sourceChainKind);
191
+ return affiliateMemo;
192
+ };
193
+ //# sourceMappingURL=limitSwapMemo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"limitSwapMemo.js","sourceRoot":"","sources":["../../../../../../packages/core/chain/swap/native/limitSwapMemo.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,170 @@
1
+ [
2
+ {
3
+ "name": "eth-to-btc-12h",
4
+ "source_chain_kind": "other",
5
+ "affiliate_included": true,
6
+ "inputs": {
7
+ "source_asset": "ETH.ETH",
8
+ "source_amount": 100000000,
9
+ "target_asset": "BTC.BTC",
10
+ "dest_addr": "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
11
+ "target_price": 0.04,
12
+ "expiry_hours": 12
13
+ },
14
+ "expected_memo": "=<:BTC.BTC:bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh:4000000/7200/0:v0:50"
15
+ },
16
+ {
17
+ "name": "eth-to-btc-24h",
18
+ "source_chain_kind": "other",
19
+ "affiliate_included": true,
20
+ "inputs": {
21
+ "source_asset": "ETH.ETH",
22
+ "source_amount": 100000000,
23
+ "target_asset": "BTC.BTC",
24
+ "dest_addr": "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
25
+ "target_price": 0.04,
26
+ "expiry_hours": 24
27
+ },
28
+ "expected_memo": "=<:BTC.BTC:bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh:4000000/14400/0:v0:50"
29
+ },
30
+ {
31
+ "name": "eth-to-btc-3d",
32
+ "source_chain_kind": "other",
33
+ "affiliate_included": true,
34
+ "inputs": {
35
+ "source_asset": "ETH.ETH",
36
+ "source_amount": 100000000,
37
+ "target_asset": "BTC.BTC",
38
+ "dest_addr": "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
39
+ "target_price": 0.04,
40
+ "expiry_hours": 72
41
+ },
42
+ "expected_memo": "=<:BTC.BTC:bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh:4000000/43200/0:v0:50"
43
+ },
44
+ {
45
+ "name": "btc-to-eth-12h",
46
+ "source_chain_kind": "utxo",
47
+ "affiliate_included": true,
48
+ "inputs": {
49
+ "source_asset": "BTC.BTC",
50
+ "source_amount": 100000000,
51
+ "target_asset": "ETH.ETH",
52
+ "dest_addr": "0x742d35Cc6634C0532925a3b844Bc9e7595f12345",
53
+ "target_price": 16,
54
+ "expiry_hours": 12
55
+ },
56
+ "expected_memo": "=<:ETH.ETH:0x742d35Cc6634C0532925a3b844Bc9e7595f12345:1600000000/7200/0:v0:50"
57
+ },
58
+ {
59
+ "name": "btc-to-eth-24h",
60
+ "source_chain_kind": "utxo",
61
+ "affiliate_included": true,
62
+ "inputs": {
63
+ "source_asset": "BTC.BTC",
64
+ "source_amount": 100000000,
65
+ "target_asset": "ETH.ETH",
66
+ "dest_addr": "0x742d35Cc6634C0532925a3b844Bc9e7595f12345",
67
+ "target_price": 16,
68
+ "expiry_hours": 24
69
+ },
70
+ "expected_memo": "=<:ETH.ETH:0x742d35Cc6634C0532925a3b844Bc9e7595f12345:1600000000/14400/0:v0:50"
71
+ },
72
+ {
73
+ "name": "btc-to-eth-3d",
74
+ "source_chain_kind": "utxo",
75
+ "affiliate_included": true,
76
+ "inputs": {
77
+ "source_asset": "BTC.BTC",
78
+ "source_amount": 100000000,
79
+ "target_asset": "ETH.ETH",
80
+ "dest_addr": "0x742d35Cc6634C0532925a3b844Bc9e7595f12345",
81
+ "target_price": 16,
82
+ "expiry_hours": 72
83
+ },
84
+ "expected_memo": "=<:ETH.ETH:0x742d35Cc6634C0532925a3b844Bc9e7595f12345:1600000000/43200/0:v0:50"
85
+ },
86
+ {
87
+ "name": "usdt-to-btc-12h",
88
+ "source_chain_kind": "other",
89
+ "affiliate_included": true,
90
+ "inputs": {
91
+ "source_asset": "ETH.USDT-0XDAC17F958D2EE523A2206206994597C13D831EC7",
92
+ "source_amount": 100000000,
93
+ "target_asset": "BTC.BTC",
94
+ "dest_addr": "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
95
+ "target_price": 0.00001,
96
+ "expiry_hours": 12
97
+ },
98
+ "expected_memo": "=<:BTC.BTC:bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh:1000/7200/0:v0:50"
99
+ },
100
+ {
101
+ "name": "usdt-to-btc-24h",
102
+ "source_chain_kind": "other",
103
+ "affiliate_included": true,
104
+ "inputs": {
105
+ "source_asset": "ETH.USDT-0XDAC17F958D2EE523A2206206994597C13D831EC7",
106
+ "source_amount": 100000000,
107
+ "target_asset": "BTC.BTC",
108
+ "dest_addr": "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
109
+ "target_price": 0.00001,
110
+ "expiry_hours": 24
111
+ },
112
+ "expected_memo": "=<:BTC.BTC:bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh:1000/14400/0:v0:50"
113
+ },
114
+ {
115
+ "name": "usdt-to-btc-3d",
116
+ "source_chain_kind": "other",
117
+ "affiliate_included": true,
118
+ "inputs": {
119
+ "source_asset": "ETH.USDT-0XDAC17F958D2EE523A2206206994597C13D831EC7",
120
+ "source_amount": 100000000,
121
+ "target_asset": "BTC.BTC",
122
+ "dest_addr": "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
123
+ "target_price": 0.00001,
124
+ "expiry_hours": 72
125
+ },
126
+ "expected_memo": "=<:BTC.BTC:bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh:1000/43200/0:v0:50"
127
+ },
128
+ {
129
+ "name": "btc-to-rune-12h",
130
+ "source_chain_kind": "utxo",
131
+ "affiliate_included": true,
132
+ "inputs": {
133
+ "source_asset": "BTC.BTC",
134
+ "source_amount": 100000000,
135
+ "target_asset": "THOR.RUNE",
136
+ "dest_addr": "thor1x2whgc2nt665y0kc44uywhynazvp0l8tp0vtu6",
137
+ "target_price": 10,
138
+ "expiry_hours": 12
139
+ },
140
+ "expected_memo": "=<:THOR.RUNE:thor1x2whgc2nt665y0kc44uywhynazvp0l8tp0vtu6:1000000000/7200/0:v0:50"
141
+ },
142
+ {
143
+ "name": "btc-to-rune-24h",
144
+ "source_chain_kind": "utxo",
145
+ "affiliate_included": false,
146
+ "inputs": {
147
+ "source_asset": "BTC.BTC",
148
+ "source_amount": 100000000,
149
+ "target_asset": "THOR.RUNE",
150
+ "dest_addr": "thor1x2whgc2nt665y0kc44uywhynazvp0l8tp0vtu6",
151
+ "target_price": 10,
152
+ "expiry_hours": 24
153
+ },
154
+ "expected_memo": "=<:THOR.RUNE:thor1x2whgc2nt665y0kc44uywhynazvp0l8tp0vtu6:1000000000/14400/0"
155
+ },
156
+ {
157
+ "name": "btc-to-rune-3d",
158
+ "source_chain_kind": "utxo",
159
+ "affiliate_included": false,
160
+ "inputs": {
161
+ "source_asset": "BTC.BTC",
162
+ "source_amount": 100000000,
163
+ "target_asset": "THOR.RUNE",
164
+ "dest_addr": "thor1x2whgc2nt665y0kc44uywhynazvp0l8tp0vtu6",
165
+ "target_price": 10,
166
+ "expiry_hours": 72
167
+ },
168
+ "expected_memo": "=<:THOR.RUNE:thor1x2whgc2nt665y0kc44uywhynazvp0l8tp0vtu6:1000000000/43200/0"
169
+ }
170
+ ]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vultisig/core-chain",
3
- "version": "2.13.0",
3
+ "version": "2.14.0",
4
4
  "description": "Blockchain chain logic shared across Vultisig clients",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -11,7 +11,8 @@
11
11
  "type": "module",
12
12
  "sideEffects": false,
13
13
  "files": [
14
- "dist"
14
+ "dist",
15
+ "fixtures"
15
16
  ],
16
17
  "exports": {
17
18
  "./amount/fromChainAmount": {
@@ -1074,6 +1075,7 @@
1074
1075
  "import": "./dist/coin/utils/sortCoinsByBalance.js",
1075
1076
  "default": "./dist/coin/utils/sortCoinsByBalance.js"
1076
1077
  },
1078
+ "./fixtures/limit-swap-memos.json": "./fixtures/limit-swap-memos.json",
1077
1079
  "./package.json": "./package.json",
1078
1080
  "./publicKey/address/bittensor": {
1079
1081
  "types": "./dist/publicKey/address/bittensor.d.ts",
@@ -1470,6 +1472,11 @@
1470
1472
  "import": "./dist/swap/native/asset/toNativeSwapAsset.js",
1471
1473
  "default": "./dist/swap/native/asset/toNativeSwapAsset.js"
1472
1474
  },
1475
+ "./swap/native/limitSwapMemo": {
1476
+ "types": "./dist/swap/native/limitSwapMemo.d.ts",
1477
+ "import": "./dist/swap/native/limitSwapMemo.js",
1478
+ "default": "./dist/swap/native/limitSwapMemo.js"
1479
+ },
1473
1480
  "./swap/native/minimum/getNativeSwapMinAmountIn": {
1474
1481
  "types": "./dist/swap/native/minimum/getNativeSwapMinAmountIn.d.ts",
1475
1482
  "import": "./dist/swap/native/minimum/getNativeSwapMinAmountIn.js",