sushi 6.6.10 → 6.7.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.
Files changed (179) hide show
  1. package/_cjs/evm/abi/selfPermitAbi/index.js +0 -2
  2. package/_cjs/evm/abi/selfPermitAbi/index.js.map +1 -1
  3. package/_cjs/evm/validate/zod.js +4 -3
  4. package/_cjs/evm/validate/zod.js.map +1 -1
  5. package/_cjs/generic/format/number.js +5 -1
  6. package/_cjs/generic/format/number.js.map +1 -1
  7. package/_cjs/generic/utils/id.js.map +1 -1
  8. package/_cjs/generic/utils/native-address.js.map +1 -1
  9. package/_cjs/generic/validate/zod.js +6 -0
  10. package/_cjs/generic/validate/zod.js.map +1 -1
  11. package/_cjs/mvm/index.js +1 -0
  12. package/_cjs/mvm/index.js.map +1 -1
  13. package/_cjs/mvm/validate/index.js +18 -0
  14. package/_cjs/mvm/validate/index.js.map +1 -0
  15. package/_cjs/mvm/validate/zod.js +48 -0
  16. package/_cjs/mvm/validate/zod.js.map +1 -0
  17. package/_cjs/stellar/config/simple-constants.js +1 -1
  18. package/_cjs/stellar/config/simple-constants.js.map +1 -1
  19. package/_cjs/stellar/index.js +1 -0
  20. package/_cjs/stellar/index.js.map +1 -1
  21. package/_cjs/stellar/validate/index.js +18 -0
  22. package/_cjs/stellar/validate/index.js.map +1 -0
  23. package/_cjs/stellar/validate/zod.js +60 -0
  24. package/_cjs/stellar/validate/zod.js.map +1 -0
  25. package/_cjs/svm/currency/token.js +1 -1
  26. package/_cjs/svm/currency/token.js.map +1 -1
  27. package/_cjs/svm/index.js +1 -0
  28. package/_cjs/svm/index.js.map +1 -1
  29. package/_cjs/svm/validate/index.js +18 -0
  30. package/_cjs/svm/validate/index.js.map +1 -0
  31. package/_cjs/svm/validate/zod.js +48 -0
  32. package/_cjs/svm/validate/zod.js.map +1 -0
  33. package/_cjs/version.js +1 -1
  34. package/_cjs/version.js.map +1 -1
  35. package/_esm/evm/abi/selfPermitAbi/index.js +0 -2
  36. package/_esm/evm/abi/selfPermitAbi/index.js.map +1 -1
  37. package/_esm/evm/validate/zod.js +4 -3
  38. package/_esm/evm/validate/zod.js.map +1 -1
  39. package/_esm/generic/format/number.js +5 -1
  40. package/_esm/generic/format/number.js.map +1 -1
  41. package/_esm/generic/utils/id.js.map +1 -1
  42. package/_esm/generic/utils/native-address.js.map +1 -1
  43. package/_esm/generic/validate/zod.js +6 -0
  44. package/_esm/generic/validate/zod.js.map +1 -1
  45. package/_esm/mvm/index.js +1 -0
  46. package/_esm/mvm/index.js.map +1 -1
  47. package/_esm/mvm/validate/index.js +2 -0
  48. package/_esm/mvm/validate/index.js.map +1 -0
  49. package/_esm/mvm/validate/zod.js +11 -0
  50. package/_esm/mvm/validate/zod.js.map +1 -0
  51. package/_esm/stellar/config/simple-constants.js +1 -1
  52. package/_esm/stellar/config/simple-constants.js.map +1 -1
  53. package/_esm/stellar/index.js +1 -0
  54. package/_esm/stellar/index.js.map +1 -1
  55. package/_esm/stellar/validate/index.js +2 -0
  56. package/_esm/stellar/validate/index.js.map +1 -0
  57. package/_esm/stellar/validate/zod.js +21 -0
  58. package/_esm/stellar/validate/zod.js.map +1 -0
  59. package/_esm/svm/currency/token.js +1 -1
  60. package/_esm/svm/currency/token.js.map +1 -1
  61. package/_esm/svm/index.js +1 -0
  62. package/_esm/svm/index.js.map +1 -1
  63. package/_esm/svm/validate/index.js +2 -0
  64. package/_esm/svm/validate/index.js.map +1 -0
  65. package/_esm/svm/validate/zod.js +11 -0
  66. package/_esm/svm/validate/zod.js.map +1 -0
  67. package/_esm/version.js +1 -1
  68. package/_esm/version.js.map +1 -1
  69. package/_types/evm/abi/selfPermitAbi/index.d.ts +0 -2
  70. package/_types/evm/abi/selfPermitAbi/index.d.ts.map +1 -1
  71. package/_types/evm/chain/chains.d.ts +10 -10
  72. package/_types/evm/validate/zod.d.ts.map +1 -1
  73. package/_types/generic/currency/serialized-currency.d.ts +1 -1
  74. package/_types/generic/types/for-chain.d.ts +3 -2
  75. package/_types/generic/types/for-chain.d.ts.map +1 -1
  76. package/_types/generic/utils/id.d.ts +4 -1
  77. package/_types/generic/utils/id.d.ts.map +1 -1
  78. package/_types/generic/utils/native-address.d.ts +2 -2
  79. package/_types/generic/utils/native-address.d.ts.map +1 -1
  80. package/_types/generic/validate/zod.d.ts +11 -0
  81. package/_types/generic/validate/zod.d.ts.map +1 -1
  82. package/_types/mvm/index.d.ts +1 -0
  83. package/_types/mvm/index.d.ts.map +1 -1
  84. package/_types/mvm/validate/index.d.ts +2 -0
  85. package/_types/mvm/validate/index.d.ts.map +1 -0
  86. package/_types/mvm/validate/zod.d.ts +6 -0
  87. package/_types/mvm/validate/zod.d.ts.map +1 -0
  88. package/_types/stellar/config/simple-constants.d.ts +1 -1
  89. package/_types/stellar/config/simple-constants.d.ts.map +1 -1
  90. package/_types/stellar/index.d.ts +1 -0
  91. package/_types/stellar/index.d.ts.map +1 -1
  92. package/_types/stellar/validate/index.d.ts +2 -0
  93. package/_types/stellar/validate/index.d.ts.map +1 -0
  94. package/_types/stellar/validate/zod.d.ts +10 -0
  95. package/_types/stellar/validate/zod.d.ts.map +1 -0
  96. package/_types/svm/config/tokens/tokens/USDC.d.ts +1 -1
  97. package/_types/svm/config/tokens/tokens/USDT.d.ts +1 -1
  98. package/_types/svm/config/tokens/tokens/WBTC.d.ts +1 -1
  99. package/_types/svm/config/tokens/tokens/WETH.d.ts +1 -1
  100. package/_types/svm/config/tokens/tokens/WSOL.d.ts +1 -1
  101. package/_types/svm/currency/currency.d.ts +2 -2
  102. package/_types/svm/currency/currency.d.ts.map +1 -1
  103. package/_types/svm/currency/token.d.ts +1 -1
  104. package/_types/svm/currency/token.d.ts.map +1 -1
  105. package/_types/svm/index.d.ts +1 -0
  106. package/_types/svm/index.d.ts.map +1 -1
  107. package/_types/svm/validate/index.d.ts +2 -0
  108. package/_types/svm/validate/index.d.ts.map +1 -0
  109. package/_types/svm/validate/zod.d.ts +7 -0
  110. package/_types/svm/validate/zod.d.ts.map +1 -0
  111. package/_types/version.d.ts +1 -1
  112. package/_types/version.d.ts.map +1 -1
  113. package/evm/abi/selfPermitAbi/index.ts +0 -2
  114. package/evm/pool/sushiswap-v3/entities/TickDataProvider.test.ts +4 -4
  115. package/evm/validate/zod.ts +4 -3
  116. package/generic/format/number.test.ts +101 -1
  117. package/generic/format/number.ts +13 -6
  118. package/generic/types/for-chain.test-d.ts +15 -0
  119. package/generic/types/for-chain.ts +25 -9
  120. package/generic/utils/id.test-d.ts +35 -0
  121. package/generic/utils/id.ts +8 -2
  122. package/generic/utils/native-address.test-d.ts +25 -0
  123. package/generic/utils/native-address.ts +6 -6
  124. package/generic/validate/zod.test.ts +44 -0
  125. package/generic/validate/zod.ts +6 -0
  126. package/mvm/index.ts +1 -0
  127. package/mvm/validate/index.ts +1 -0
  128. package/mvm/validate/zod.ts +13 -0
  129. package/package.json +3 -4
  130. package/stellar/config/simple-constants.ts +2 -5
  131. package/stellar/index.ts +1 -0
  132. package/stellar/validate/index.ts +1 -0
  133. package/stellar/validate/zod.ts +38 -0
  134. package/svm/currency/token.ts +1 -1
  135. package/svm/index.ts +1 -0
  136. package/svm/validate/index.ts +1 -0
  137. package/svm/validate/zod.ts +13 -0
  138. package/_cjs/evm/abi/selfPermitAbi/selfPermitAbi_selfPermitAllowedIfNecessary.js +0 -20
  139. package/_cjs/evm/abi/selfPermitAbi/selfPermitAbi_selfPermitAllowedIfNecessary.js.map +0 -1
  140. package/_cjs/evm/abi/selfPermitAbi/selfPermitAbi_selfPermitIfNecessary.js +0 -20
  141. package/_cjs/evm/abi/selfPermitAbi/selfPermitAbi_selfPermitIfNecessary.js.map +0 -1
  142. package/_cjs/evm/abi/splitter.js +0 -68
  143. package/_cjs/evm/abi/splitter.js.map +0 -1
  144. package/_cjs/evm/api/config.js +0 -20
  145. package/_cjs/evm/api/config.js.map +0 -1
  146. package/_cjs/evm/config/drpc.js +0 -83
  147. package/_cjs/evm/config/drpc.js.map +0 -1
  148. package/_cjs/evm/config/tokens/tokens/SGUSDC.js +0 -18
  149. package/_cjs/evm/config/tokens/tokens/SGUSDC.js.map +0 -1
  150. package/_esm/evm/abi/selfPermitAbi/selfPermitAbi_selfPermitAllowedIfNecessary.js +0 -17
  151. package/_esm/evm/abi/selfPermitAbi/selfPermitAbi_selfPermitAllowedIfNecessary.js.map +0 -1
  152. package/_esm/evm/abi/selfPermitAbi/selfPermitAbi_selfPermitIfNecessary.js +0 -17
  153. package/_esm/evm/abi/selfPermitAbi/selfPermitAbi_selfPermitIfNecessary.js.map +0 -1
  154. package/_esm/evm/abi/splitter.js +0 -34
  155. package/_esm/evm/abi/splitter.js.map +0 -1
  156. package/_esm/evm/api/config.js +0 -17
  157. package/_esm/evm/api/config.js.map +0 -1
  158. package/_esm/evm/config/drpc.js +0 -78
  159. package/_esm/evm/config/drpc.js.map +0 -1
  160. package/_esm/evm/config/tokens/tokens/SGUSDC.js +0 -15
  161. package/_esm/evm/config/tokens/tokens/SGUSDC.js.map +0 -1
  162. package/_types/evm/abi/selfPermitAbi/selfPermitAbi_selfPermitAllowedIfNecessary.d.ts +0 -32
  163. package/_types/evm/abi/selfPermitAbi/selfPermitAbi_selfPermitAllowedIfNecessary.d.ts.map +0 -1
  164. package/_types/evm/abi/selfPermitAbi/selfPermitAbi_selfPermitIfNecessary.d.ts +0 -32
  165. package/_types/evm/abi/selfPermitAbi/selfPermitAbi_selfPermitIfNecessary.d.ts.map +0 -1
  166. package/_types/evm/abi/splitter.d.ts +0 -2
  167. package/_types/evm/abi/splitter.d.ts.map +0 -1
  168. package/_types/evm/api/config.d.ts +0 -11
  169. package/_types/evm/api/config.d.ts.map +0 -1
  170. package/_types/evm/config/drpc.d.ts +0 -9
  171. package/_types/evm/config/drpc.d.ts.map +0 -1
  172. package/_types/evm/config/tokens/tokens/SGUSDC.d.ts +0 -9
  173. package/_types/evm/config/tokens/tokens/SGUSDC.d.ts.map +0 -1
  174. package/evm/abi/selfPermitAbi/selfPermitAbi_selfPermitAllowedIfNecessary.ts +0 -16
  175. package/evm/abi/selfPermitAbi/selfPermitAbi_selfPermitIfNecessary.ts +0 -16
  176. package/evm/abi/splitter.ts +0 -53
  177. package/evm/api/config.ts +0 -23
  178. package/evm/config/drpc.ts +0 -92
  179. package/evm/config/tokens/tokens/SGUSDC.ts +0 -19
@@ -1,2 +1,2 @@
1
- export declare const version = "5.0.12";
1
+ export declare const version = "6.7.0";
2
2
  //# sourceMappingURL=version.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,WAAW,CAAA"}
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,UAAU,CAAA"}
@@ -1,4 +1,2 @@
1
1
  export * from './selfPermitAbi_selfPermit.js'
2
2
  export * from './selfPermitAbi_selfPermitAllowed.js'
3
- export * from './selfPermitAbi_selfPermitAllowedIfNecessary.js'
4
- export * from './selfPermitAbi_selfPermitIfNecessary.js'
@@ -4,13 +4,13 @@ import { NoTickDataProvider } from './TickDataProvider.js'
4
4
  describe('TickDataProvider', () => {
5
5
  describe('NoTickDataProvider', () => {
6
6
  const provider = new NoTickDataProvider()
7
- it('throws on getTick', () => {
8
- expect(provider.getTick(0)).rejects.toThrow(
7
+ it('throws on getTick', async () => {
8
+ await expect(provider.getTick(0)).rejects.toThrow(
9
9
  'No tick data provider was given',
10
10
  )
11
11
  })
12
- it('throws on nextInitializedTickWithinOneWord', () => {
13
- expect(
12
+ it('throws on nextInitializedTickWithinOneWord', async () => {
13
+ await expect(
14
14
  provider.nextInitializedTickWithinOneWord(0, false, 1),
15
15
  ).rejects.toThrow('No tick data provider was given')
16
16
  })
@@ -1,13 +1,14 @@
1
- import { type Address, isAddress } from 'viem'
2
1
  import * as z from 'zod'
2
+ import { type EvmAddress, isEvmAddress } from '../currency/token.js'
3
+ import { normalizeEvmAddress } from '../utils/normalize-address.js'
3
4
 
4
5
  export const evmAddress = () =>
5
6
  z
6
7
  .string()
7
- .refine((value) => isAddress(value, { strict: false }), {
8
+ .refine((value) => isEvmAddress(value), {
8
9
  message: 'Invalid address',
9
10
  })
10
- .transform((value) => value as Address)
11
+ .transform((value) => normalizeEvmAddress(value as EvmAddress))
11
12
 
12
13
  export const szevm = {
13
14
  address: evmAddress,
@@ -127,7 +127,7 @@ describe('numberToFixed', () => {
127
127
  })
128
128
 
129
129
  describe('edge cases', () => {
130
- it('should handle empty and z8ero values', () => {
130
+ it('should handle empty and zero values', () => {
131
131
  expect(numberToFixed(0, { maxFixed: 2 })).toBe('0')
132
132
  expect(numberToFixed('0', { maxFixed: 2 })).toBe('0')
133
133
  expect(numberToFixed('0.00', { maxFixed: 2 })).toBe('0')
@@ -143,4 +143,104 @@ describe('numberToFixed', () => {
143
143
  expect(numberToFixed('1.23e+2', { maxFixed: 2 })).toBe('123')
144
144
  })
145
145
  })
146
+
147
+ describe('string rounding edge cases', () => {
148
+ it('should round fixed-decimal string inputs that overflow into a new integer digit', () => {
149
+ expect(numberToFixed('9.995', { fixed: 2 })).toBe('10')
150
+ expect(numberToFixed('-9.995', { fixed: 2 })).toBe('-10')
151
+ })
152
+
153
+ it('should round long leading-zero decimals when using significant digits', () => {
154
+ expect(numberToFixed('0.00009999', { significant: 2 })).toBe('0.0001')
155
+ expect(numberToFixed('-0.00009999', { significant: 2 })).toBe('-0.0001')
156
+ })
157
+
158
+ it('should round large negative strings when all significant digits are 9s', () => {
159
+ expect(numberToFixed('-9999.9', { significant: 1 })).toBe('-10000')
160
+ })
161
+ })
162
+
163
+ describe('fixed rounding cascades', () => {
164
+ it('should cascade rounding across multiple integer digits for strings', () => {
165
+ expect(numberToFixed('199.995', { fixed: 2 })).toBe('200')
166
+ expect(numberToFixed('-199.995', { fixed: 2 })).toBe('-200')
167
+ })
168
+
169
+ it('should keep trailing zeros for numeric inputs when the same rounding occurs', () => {
170
+ expect(numberToFixed(199.995, { fixed: 2 })).toBe('200.00')
171
+ expect(numberToFixed(-199.995, { fixed: 2 })).toBe('-200.00')
172
+ })
173
+
174
+ it('should handle +/-0.005 thresholds symmetrically', () => {
175
+ expect(numberToFixed('0.005', { fixed: 2 })).toBe('0.01')
176
+ expect(numberToFixed('-0.005', { fixed: 2 })).toBe('-0.01')
177
+ expect(numberToFixed(0.005, { fixed: 2 })).toBe('0.01')
178
+ expect(numberToFixed(-0.005, { fixed: 2 })).toBe('-0.01')
179
+ })
180
+
181
+ it('should preserve decimal accuracy for strings at IEEE rounding pain points', () => {
182
+ expect(numberToFixed('2.675', { fixed: 2 })).toBe('2.68')
183
+ expect(numberToFixed(2.675, { fixed: 2 })).toBe('2.67')
184
+ })
185
+ })
186
+
187
+ describe('maxFixed nuances', () => {
188
+ it('should truncate (not round) string inputs for maxFixed', () => {
189
+ expect(numberToFixed('2.999', { maxFixed: 2 })).toBe('2.99')
190
+ expect(numberToFixed('-2.999', { maxFixed: 2 })).toBe('-2.99')
191
+ })
192
+
193
+ it('should round numeric inputs for maxFixed after trimming trailing zeros', () => {
194
+ expect(numberToFixed(2.999, { maxFixed: 2 })).toBe('3')
195
+ expect(numberToFixed(-2.999, { maxFixed: 2 })).toBe('-3')
196
+ })
197
+
198
+ it('should drop redundant zeros for very small fractions supplied as strings', () => {
199
+ expect(numberToFixed('0.0001000', { maxFixed: 6 })).toBe('0.0001')
200
+ expect(numberToFixed('-0.0001000', { maxFixed: 6 })).toBe('-0.0001')
201
+ })
202
+
203
+ it('should distinguish between truncation and rounding when maxFixed is zero', () => {
204
+ expect(numberToFixed('12.9', { maxFixed: 0 })).toBe('12')
205
+ expect(numberToFixed('-12.9', { maxFixed: 0 })).toBe('-12')
206
+ expect(numberToFixed(12.9, { maxFixed: 0 })).toBe('13')
207
+ expect(numberToFixed(-12.9, { maxFixed: 0 })).toBe('-13')
208
+ })
209
+
210
+ it('should trim or round repeating decimals based on input type', () => {
211
+ expect(numberToFixed('0.10999', { maxFixed: 3 })).toBe('0.109')
212
+ expect(numberToFixed('-0.10999', { maxFixed: 3 })).toBe('-0.109')
213
+ expect(numberToFixed(0.10999, { maxFixed: 3 })).toBe('0.11')
214
+ expect(numberToFixed(-0.10999, { maxFixed: 3 })).toBe('-0.11')
215
+ })
216
+ })
217
+
218
+ describe('significant digits with decimals', () => {
219
+ it('should keep track of leading zeros for negative decimals', () => {
220
+ expect(numberToFixed('-0.00056789', { significant: 2 })).toBe('-0.0006')
221
+ })
222
+
223
+ it('should round decimals just below one down to -1 with a single significant digit', () => {
224
+ expect(numberToFixed('-0.9994', { significant: 1 })).toBe('-1')
225
+ })
226
+ })
227
+
228
+ describe('input validation', () => {
229
+ it('should accept trailing decimal strings', () => {
230
+ expect(numberToFixed('1.', { fixed: 2 })).toBe('1.00')
231
+ expect(numberToFixed('1.', { significant: 2 })).toBe('1')
232
+ })
233
+
234
+ it('should reject invalid numeric strings', () => {
235
+ expect(() => numberToFixed('invalid', { fixed: 2 })).toThrow(
236
+ 'Invalid number string',
237
+ )
238
+ })
239
+
240
+ it('should reject empty option objects', () => {
241
+ expect(() => numberToFixed(1, {} as any)).toThrow(
242
+ 'Invalid arguments for numberToFixed',
243
+ )
244
+ })
245
+ })
146
246
  })
@@ -175,7 +175,9 @@ function stringToFixed(
175
175
  significantDecimal = significantDecimal.slice(0, -1)
176
176
  }
177
177
 
178
- const res = `${integerPart}${significantDecimal ? `.${significantDecimal}` : ''}`
178
+ const res = `${integerPart}${
179
+ significantDecimal ? `.${significantDecimal}` : ''
180
+ }`
179
181
  return roundString(str, res)
180
182
  }
181
183
 
@@ -192,6 +194,10 @@ function stringToFixed(
192
194
  }
193
195
 
194
196
  function roundString(original: string, formatted: string) {
197
+ if (!original.match(/^-?(?:\d+\.?|\d*\.\d+)$/)) {
198
+ throw new Error('Invalid number string')
199
+ }
200
+
195
201
  const decimalIndex = original.indexOf('.')
196
202
 
197
203
  const nextDigitIndex = formatted.length
@@ -216,15 +222,16 @@ function roundString(original: string, formatted: string) {
216
222
  // handle full carry (e.g., "9.9" -> "10")
217
223
  if (formatted.length === 0 || formatted === '-') {
218
224
  const negative = original.startsWith('-')
219
- const zeros = Math.max(decimalIndex, 0)
225
+ const digitsLeftOfDecimal = decimalIndex - (negative ? 1 : 0)
226
+ const zeros = Math.max(digitsLeftOfDecimal, 0)
220
227
  return `${negative ? '-' : ''}1${'0'.repeat(zeros)}`
221
228
  }
222
229
  }
223
230
 
224
- return `${formatted.substring(0, formatted.length - 1)}${String.fromCharCode(lastDigit() + 1)}`.padEnd(
225
- decimalIndex,
226
- '0',
227
- )
231
+ return `${formatted.substring(
232
+ 0,
233
+ formatted.length - 1,
234
+ )}${String.fromCharCode(lastDigit() + 1)}`.padEnd(decimalIndex, '0')
228
235
  }
229
236
 
230
237
  return formatted
@@ -15,6 +15,7 @@ import type { SvmNative } from '../../svm/currency/native.js'
15
15
  import type { SvmToken } from '../../svm/currency/token.js'
16
16
  import type { SvmChainId } from '../../svm/index.js'
17
17
  import type { SvmID } from '../../svm/types/id.js'
18
+ import type { ChainId } from '../chain/chains.js'
18
19
  import type {
19
20
  CurrencyFor,
20
21
  IDFor,
@@ -73,6 +74,20 @@ describe('generic/types/for-chain.ts types', () => {
73
74
  CurrencyFor<EvmChainId | SvmChainId, Metadata>
74
75
  >().toEqualTypeOf<EvmCurrency<Metadata> | SvmCurrency<Metadata>>()
75
76
  })
77
+
78
+ it('should accept TokenFor for a generic chain id', () => {
79
+ // Regression guard: holds only because TokenFor's branch order matches
80
+ // CurrencyFor's, letting TypeScript relate the two conditional types for
81
+ // an unresolved generic `T`. The constraint `A extends B` fails to
82
+ // compile if TokenFor<T> is not assignable to CurrencyFor<T>.
83
+ type AssertAssignable<_A extends B, B> = true
84
+ type _Guard<T extends ChainId> = AssertAssignable<
85
+ TokenFor<T, Metadata>,
86
+ CurrencyFor<T, Metadata>
87
+ >
88
+
89
+ expectTypeOf<_Guard<ChainId>>().toEqualTypeOf<true>()
90
+ })
76
91
  })
77
92
 
78
93
  describe('NativeFor', () => {
@@ -13,7 +13,11 @@ import type {
13
13
  MvmToken,
14
14
  MvmTxHash,
15
15
  } from '../../mvm/currency/token.js'
16
- import type { StellarAddress, StellarTxHash } from '../../stellar/address.js'
16
+ import type {
17
+ StellarAddress,
18
+ StellarContractAddress,
19
+ StellarTxHash,
20
+ } from '../../stellar/address.js'
17
21
  import type { StellarChainId } from '../../stellar/chain/chains.js'
18
22
  import type { StellarCurrency } from '../../stellar/currency/currency.js'
19
23
  import type { StellarToken } from '../../stellar/currency/token.js'
@@ -30,23 +34,24 @@ import type { SvmID } from '../../svm/types/id.js'
30
34
  import type { ChainId } from '../chain/chains.js'
31
35
  import type { CurrencyMetadata } from '../currency/currency.js'
32
36
 
37
+ // Branch order (Evm, Svm, Mvm, Stellar) is kept identical across `TokenFor`,
38
+ // `NativeFor` and `CurrencyFor` so TypeScript can relate the conditional types
39
+ // branch-by-branch and prove `TokenFor<T>`/`NativeFor<T>` are assignable to
40
+ // `CurrencyFor<T>` for a generic `T`. The chain families are disjoint, so the
41
+ // order has no effect on the resolved type — only on relatability.
33
42
  export type TokenFor<
34
43
  TChainId extends ChainId,
35
44
  Metadata extends CurrencyMetadata = CurrencyMetadata,
36
45
  > = TChainId extends EvmChainId
37
46
  ? EvmToken<Metadata>
38
- : TChainId extends MvmChainId
39
- ? MvmToken<Metadata>
40
- : TChainId extends SvmChainId
41
- ? SvmToken<Metadata>
47
+ : TChainId extends SvmChainId
48
+ ? SvmToken<Metadata>
49
+ : TChainId extends MvmChainId
50
+ ? MvmToken<Metadata>
42
51
  : TChainId extends StellarChainId
43
52
  ? StellarToken<Metadata>
44
53
  : never
45
54
 
46
- // Branch order matches `NativeFor` (Evm, then Svm) so TypeScript can relate the
47
- // two conditional types and prove `NativeFor<T>` is assignable to
48
- // `CurrencyFor<T>` for a generic `T`. The chain families are disjoint, so the
49
- // order has no effect on the resolved type.
50
55
  export type CurrencyFor<
51
56
  TChainId extends ChainId,
52
57
  Metadata extends CurrencyMetadata = CurrencyMetadata,
@@ -81,6 +86,17 @@ export type AddressFor<TChainId extends ChainId> = TChainId extends EvmChainId
81
86
  ? StellarAddress
82
87
  : never
83
88
 
89
+ export type ContractAddressFor<TChainId extends ChainId> =
90
+ TChainId extends EvmChainId
91
+ ? EvmAddress
92
+ : TChainId extends MvmChainId
93
+ ? MvmAddress
94
+ : TChainId extends SvmChainId
95
+ ? SvmAddress
96
+ : TChainId extends StellarChainId
97
+ ? StellarContractAddress
98
+ : never
99
+
84
100
  export type TxHashFor<TChainId extends ChainId> = TChainId extends EvmChainId
85
101
  ? EvmTxHash
86
102
  : TChainId extends MvmChainId
@@ -0,0 +1,35 @@
1
+ import { describe, expectTypeOf, it } from 'vitest'
2
+ import { SvmChainId } from '~/svm/chain/chains.js'
3
+ import type { SvmAddress } from '~/svm/currency/token.js'
4
+ import type { EvmChainId } from '../../evm/chain/chains.js'
5
+ import type { EvmAddress } from '../../evm/currency/token.js'
6
+ import type { ID } from '../types/id.js'
7
+ import { getChainIdAddressFromId, getIdFromChainIdAddress } from './id.js'
8
+
9
+ describe('getChainIdAddressFromId', () => {
10
+ it('preserves EVM chainId and address types', () => {
11
+ const id = '1:0xaa' as ID<EvmChainId, EvmAddress>
12
+
13
+ expectTypeOf(getChainIdAddressFromId(id)).toEqualTypeOf<{
14
+ chainId: EvmChainId
15
+ address: EvmAddress
16
+ }>()
17
+ })
18
+
19
+ it('preserves Solana chainId and address types', () => {
20
+ const id = getIdFromChainIdAddress(
21
+ SvmChainId.SOLANA,
22
+ 'So11111111111111111111111111111111111111112' as SvmAddress,
23
+ )
24
+
25
+ expectTypeOf(getChainIdAddressFromId(id)).not.toEqualTypeOf<{
26
+ chainId: SvmChainId
27
+ address: `${SvmAddress}`
28
+ }>()
29
+
30
+ expectTypeOf(getChainIdAddressFromId(id)).toEqualTypeOf<{
31
+ chainId: SvmChainId
32
+ address: SvmAddress
33
+ }>()
34
+ })
35
+ })
@@ -1,9 +1,15 @@
1
+ import type { SvmAddress } from '../../svm/currency/token.js'
1
2
  import type { ChainId } from '../chain/chains.js'
2
3
  import type { AddressFor } from '../types/for-chain.js'
3
4
  import type { ID } from '../types/id.js'
4
5
  import { getNativeAddress } from './native-address.js'
5
6
  import { normalizeAddress } from './normalize-address.js'
6
7
 
8
+ // Hacky fix, SvmAddress is a branded type, but when used in a template literal type, it loses its branding.
9
+ type ReturnedAddress<TAddress extends string> = TAddress extends `${SvmAddress}`
10
+ ? SvmAddress
11
+ : TAddress
12
+
7
13
  export function getChainIdAddressFromId<
8
14
  TChainId extends ChainId,
9
15
  TAddress extends string,
@@ -11,7 +17,7 @@ export function getChainIdAddressFromId<
11
17
  id: ID<TChainId, TAddress>,
12
18
  ): {
13
19
  chainId: TChainId
14
- address: TAddress
20
+ address: ReturnedAddress<TAddress>
15
21
  } {
16
22
  const separatorIndex = id.indexOf(':')
17
23
 
@@ -22,7 +28,7 @@ export function getChainIdAddressFromId<
22
28
  }
23
29
 
24
30
  const chainId = +id.slice(0, separatorIndex) as TChainId
25
- const address = id.slice(separatorIndex + 1) as TAddress
31
+ const address = id.slice(separatorIndex + 1) as ReturnedAddress<TAddress>
26
32
 
27
33
  if (!chainId || !address) {
28
34
  throw new Error(
@@ -0,0 +1,25 @@
1
+ import { describe, expectTypeOf, it } from 'vitest'
2
+ import { EvmChainId } from '../../evm/chain/chains.js'
3
+ import type { EvmAddress } from '../../evm/currency/token.js'
4
+ import type {
5
+ StellarAccountAddress,
6
+ StellarContractAddress,
7
+ } from '../../stellar/address.js'
8
+ import { StellarChainId } from '../../stellar/chain/chains.js'
9
+ import { getNativeAddress } from './native-address.js'
10
+
11
+ describe('getNativeAddress', () => {
12
+ it('returns contract address types', () => {
13
+ expectTypeOf(
14
+ getNativeAddress(EvmChainId.ETHEREUM),
15
+ ).toEqualTypeOf<EvmAddress>()
16
+
17
+ expectTypeOf(
18
+ getNativeAddress(StellarChainId.STELLAR),
19
+ ).toEqualTypeOf<StellarContractAddress>()
20
+
21
+ expectTypeOf(
22
+ getNativeAddress(StellarChainId.STELLAR),
23
+ ).not.toEqualTypeOf<StellarAccountAddress>()
24
+ })
25
+ })
@@ -7,26 +7,26 @@ import { stellarNativeAddress } from '../../stellar/config/simple-constants.js'
7
7
  import { isSvmChainId } from '../../svm/chain/chains.js'
8
8
  import { svmNativeAddress } from '../../svm/config/simple-constants.js'
9
9
  import type { ChainId } from '../chain/chains.js'
10
- import type { AddressFor } from '../types/for-chain.js'
10
+ import type { ContractAddressFor } from '../types/for-chain.js'
11
11
  import { assertNever } from './assert-never.js'
12
12
 
13
13
  export function getNativeAddress<TChainId extends ChainId>(
14
14
  chainId: TChainId,
15
- ): AddressFor<TChainId> {
15
+ ): ContractAddressFor<TChainId> {
16
16
  if (isEvmChainId(chainId)) {
17
- return evmNativeAddress as AddressFor<TChainId>
17
+ return evmNativeAddress as ContractAddressFor<TChainId>
18
18
  }
19
19
 
20
20
  if (isMvmChainId(chainId)) {
21
- return mvmNativeAddress as AddressFor<TChainId>
21
+ return mvmNativeAddress as ContractAddressFor<TChainId>
22
22
  }
23
23
 
24
24
  if (isSvmChainId(chainId)) {
25
- return svmNativeAddress as AddressFor<TChainId>
25
+ return svmNativeAddress as ContractAddressFor<TChainId>
26
26
  }
27
27
 
28
28
  if (isStellarChainId(chainId)) {
29
- return stellarNativeAddress as AddressFor<TChainId>
29
+ return stellarNativeAddress as ContractAddressFor<TChainId>
30
30
  }
31
31
 
32
32
  assertNever(chainId, `getNativeAddress, unsupported chainId: ${chainId}`)
@@ -0,0 +1,44 @@
1
+ import { describe, expect, it } from 'vitest'
2
+ import { sz } from './zod.js'
3
+
4
+ describe('sz address validators', () => {
5
+ it('validates, casts, and normalizes EVM addresses', () => {
6
+ const address = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'
7
+
8
+ expect(sz.evm.address().parse(address)).toBe(
9
+ '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
10
+ )
11
+ expect(sz.evm.address().safeParse('0x1234').success).toBe(false)
12
+ })
13
+
14
+ it('validates and casts SVM addresses', () => {
15
+ const address = 'So11111111111111111111111111111111111111112'
16
+
17
+ expect(sz.svm.address().parse(address)).toBe(address)
18
+ expect(sz.svm.address().safeParse('0x1234').success).toBe(false)
19
+ })
20
+
21
+ it('validates and casts MVM addresses', () => {
22
+ const address = '0x2::sui::SUI'
23
+
24
+ expect(sz.mvm.address().parse(address)).toBe(address)
25
+ expect(sz.mvm.address().safeParse('0x2::sui').success).toBe(false)
26
+ })
27
+
28
+ it('validates, casts, and normalizes Stellar addresses', () => {
29
+ const accountAddress =
30
+ 'GAAZI4TCR3TY5OJHCTJC2A4QSY6CJWJH5IAJTGKIN2ER7LBNVKOCCWN7'
31
+ const contractAddress =
32
+ 'CCRSMJDITH3VK5QOGYCVZDAKIY5GL3RCG4TCVLIAVB662IW2V5KJGZGF'
33
+
34
+ expect(sz.stellar.address().parse(accountAddress.toLowerCase())).toBe(
35
+ accountAddress,
36
+ )
37
+ expect(
38
+ sz.stellar.contractAddress().parse(contractAddress.toLowerCase()),
39
+ ).toBe(contractAddress)
40
+ expect(sz.stellar.accountAddress().safeParse(contractAddress).success).toBe(
41
+ false,
42
+ )
43
+ })
44
+ })
@@ -1,6 +1,9 @@
1
1
  import type { Hex } from 'viem'
2
2
  import * as z from 'zod'
3
3
  import { szevm } from '../../evm/validate/zod.js'
4
+ import { szmvm } from '../../mvm/validate/zod.js'
5
+ import { szstellar } from '../../stellar/validate/zod.js'
6
+ import { szsvm } from '../../svm/validate/zod.js'
4
7
 
5
8
  export const hex = () =>
6
9
  z
@@ -13,4 +16,7 @@ export const hex = () =>
13
16
  export const sz = {
14
17
  evm: szevm,
15
18
  hex,
19
+ mvm: szmvm,
20
+ stellar: szstellar,
21
+ svm: szsvm,
16
22
  }
package/mvm/index.ts CHANGED
@@ -2,3 +2,4 @@ export * from './chain/index.js'
2
2
  export * from './config/index.js'
3
3
  export * from './currency/index.js'
4
4
  export * from './utils/index.js'
5
+ export * from './validate/index.js'
@@ -0,0 +1 @@
1
+ export * from './zod.js'
@@ -0,0 +1,13 @@
1
+ import * as z from 'zod'
2
+ import { isMvmAddress, type MvmAddress } from '../currency/token.js'
3
+ import { normalizeMvmAddress } from '../utils/normalize-address.js'
4
+
5
+ export const mvmAddress = () =>
6
+ z
7
+ .string()
8
+ .refine(isMvmAddress, { message: 'Invalid address' })
9
+ .transform((value) => normalizeMvmAddress(value as MvmAddress))
10
+
11
+ export const szmvm = {
12
+ address: mvmAddress,
13
+ }
package/package.json CHANGED
@@ -1,8 +1,7 @@
1
1
  {
2
2
  "name": "sushi",
3
3
  "description": "Sushi",
4
- "version": "6.6.10",
5
- "type": "module",
4
+ "version": "6.7.0",
6
5
  "main": "./_cjs/generic/index.js",
7
6
  "module": "./_esm/generic/index.js",
8
7
  "types": "./_types/generic/index.d.ts",
@@ -68,13 +67,13 @@
68
67
  }
69
68
  },
70
69
  "dependencies": {
71
- "@solana/addresses": ">=5",
70
+ "@solana/addresses": "6.9.0",
72
71
  "@uniswap/token-lists": "1.0.0-beta.33",
73
72
  "tiny-invariant": "1.3.3"
74
73
  },
75
74
  "peerDependencies": {
76
75
  "@solana/addresses": ">=5",
77
- "typescript": ">= 5.8.3 < 6",
76
+ "typescript": ">= 5.8.3 < 7",
78
77
  "viem": "*",
79
78
  "zod": ">=4"
80
79
  },
@@ -1,11 +1,8 @@
1
- import type {
2
- StellarAccountAddress,
3
- StellarContractAddress,
4
- } from '../address.js'
1
+ import type { StellarContractAddress } from '../address.js'
5
2
  import { StellarChainId } from '../chain/chains.js'
6
3
 
7
4
  export const stellarNativeAddress =
8
- 'GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' as const satisfies StellarAccountAddress
5
+ 'CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' as const satisfies StellarContractAddress
9
6
 
10
7
  export const SUSHISWAP_V3_FACTORY_ADDRESS: Record<
11
8
  StellarChainId,
package/stellar/index.ts CHANGED
@@ -4,3 +4,4 @@ export * from './config/index.js'
4
4
  export * from './currency/index.js'
5
5
  export type * from './types/index.js'
6
6
  export * from './utils/index.js'
7
+ export * from './validate/index.js'
@@ -0,0 +1 @@
1
+ export * from './zod.js'
@@ -0,0 +1,38 @@
1
+ import * as z from 'zod'
2
+ import {
3
+ isStellarAccountAddress,
4
+ isStellarAddress,
5
+ isStellarContractAddress,
6
+ type StellarAccountAddress,
7
+ type StellarAddress,
8
+ type StellarContractAddress,
9
+ } from '../address.js'
10
+ import { normalizeStellarAddress } from '../utils/normalize-address.js'
11
+
12
+ export const stellarAddress = () =>
13
+ z
14
+ .string()
15
+ .transform((value) => normalizeStellarAddress(value as StellarAddress))
16
+ .refine(isStellarAddress, { message: 'Invalid address' })
17
+
18
+ export const stellarAccountAddress = () =>
19
+ z
20
+ .string()
21
+ .transform((value) =>
22
+ normalizeStellarAddress(value as StellarAccountAddress),
23
+ )
24
+ .refine(isStellarAccountAddress, { message: 'Invalid address' })
25
+
26
+ export const stellarContractAddress = () =>
27
+ z
28
+ .string()
29
+ .transform((value) =>
30
+ normalizeStellarAddress(value as StellarContractAddress),
31
+ )
32
+ .refine(isStellarContractAddress, { message: 'Invalid address' })
33
+
34
+ export const szstellar = {
35
+ accountAddress: stellarAccountAddress,
36
+ address: stellarAddress,
37
+ contractAddress: stellarContractAddress,
38
+ }
@@ -9,7 +9,7 @@ import { Token } from '../../generic/currency/token.js'
9
9
  import { isSvmChainId, type SvmChainId } from '../chain/chains.js'
10
10
  import { normalizeSvmAddress } from '../utils/normalize-address.js'
11
11
 
12
- export { type SvmAddress, svmAddress, isSvmAddress }
12
+ export { isSvmAddress, type SvmAddress, svmAddress }
13
13
  export type SvmTxHash = string
14
14
 
15
15
  export type SvmTokenOrigin = 'native' | 'native-bridge'
package/svm/index.ts CHANGED
@@ -2,3 +2,4 @@ export * from './chain/index.js'
2
2
  export * from './config/index.js'
3
3
  export * from './currency/index.js'
4
4
  export * from './utils/index.js'
5
+ export * from './validate/index.js'
@@ -0,0 +1 @@
1
+ export * from './zod.js'
@@ -0,0 +1,13 @@
1
+ import * as z from 'zod'
2
+ import { isSvmAddress, type SvmAddress } from '../currency/token.js'
3
+ import { normalizeSvmAddress } from '../utils/normalize-address.js'
4
+
5
+ export const svmAddressSchema = () =>
6
+ z
7
+ .string()
8
+ .refine(isSvmAddress, { message: 'Invalid address' })
9
+ .transform((value) => normalizeSvmAddress(value as SvmAddress))
10
+
11
+ export const szsvm = {
12
+ address: svmAddressSchema,
13
+ }