@swapkit/core 1.0.0-rc.5 → 1.0.0-rc.51

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/package.json CHANGED
@@ -1,30 +1,30 @@
1
1
  {
2
2
  "author": "swapkit-oss-team",
3
3
  "dependencies": {
4
- "@swapkit/types": "1.0.0-rc.0",
5
- "@swapkit/helpers": "1.0.0-rc.1"
4
+ "@swapkit/types": "1.0.0-rc.22",
5
+ "@swapkit/helpers": "1.0.0-rc.42"
6
6
  },
7
7
  "description": "SwapKit Lib core",
8
8
  "devDependencies": {
9
- "@vitest/coverage-istanbul": "0.34.4",
10
- "ethers": "6.7.1",
11
- "vite": "4.4.9",
9
+ "@vitest/coverage-istanbul": "0.34.6",
10
+ "ethers": "6.9.0",
11
+ "vite": "4.5.0",
12
12
  "vite-plugin-top-level-await": "1.3.1",
13
13
  "vite-plugin-wasm": "3.2.2",
14
- "vitest": "0.34.4",
15
- "@internal/config": "0.0.0-internal.0",
16
- "@swapkit/api": "1.0.0-rc.0",
17
- "@swapkit/tokens": "1.0.0-rc.0",
18
- "@swapkit/toolbox-cosmos": "1.0.0-rc.3",
19
- "@swapkit/toolbox-evm": "1.0.0-rc.2",
20
- "@swapkit/toolbox-utxo": "1.0.0-rc.2"
14
+ "vitest": "0.34.6",
15
+ "@internal/config": "0.0.0-rc.8",
16
+ "@swapkit/api": "1.0.0-rc.22",
17
+ "@swapkit/tokens": "1.0.0-rc.23",
18
+ "@swapkit/toolbox-cosmos": "1.0.0-rc.44",
19
+ "@swapkit/toolbox-evm": "1.0.0-rc.44",
20
+ "@swapkit/toolbox-utxo": "1.0.0-rc.45"
21
21
  },
22
22
  "peerDependencies": {
23
- "@swapkit/api": "1.0.0-rc.0",
24
- "@swapkit/tokens": "1.0.0-rc.0",
25
- "@swapkit/toolbox-cosmos": "1.0.0-rc.3",
26
- "@swapkit/toolbox-evm": "1.0.0-rc.2",
27
- "@swapkit/toolbox-utxo": "1.0.0-rc.2"
23
+ "@swapkit/api": "1.0.0-rc.22",
24
+ "@swapkit/tokens": "1.0.0-rc.23",
25
+ "@swapkit/toolbox-cosmos": "1.0.0-rc.44",
26
+ "@swapkit/toolbox-evm": "1.0.0-rc.44",
27
+ "@swapkit/toolbox-utxo": "1.0.0-rc.45"
28
28
  },
29
29
  "eslintConfig": {
30
30
  "extends": "../../../internal/eslint-config"
@@ -52,7 +52,7 @@
52
52
  "repository": "https://github.com/thorswap/SwapKit.git",
53
53
  "type": "module",
54
54
  "types": "./dist/index.d.ts",
55
- "version": "1.0.0-rc.5",
55
+ "version": "1.0.0-rc.51",
56
56
  "scripts": {
57
57
  "build": "NODE_OPTIONS=--max_old_space_size=16384 vite build",
58
58
  "clean": "rm -rf dist vite.config.ts.* .turbo node_modules",
@@ -4,19 +4,43 @@ import { describe, expect, test } from 'vitest';
4
4
  import { getExplorerAddressUrl, getExplorerTxUrl } from '../explorerUrls.ts';
5
5
 
6
6
  describe('Explorer URLs', () => {
7
- Object.values(Chain)
8
- .filter((c) => ![Chain.Litecoin, Chain.Dogecoin, Chain.Cosmos].includes(c))
9
- .forEach((chain) => {
10
- test(`getExplorerTxUrl returns correct URL for ${chain}`, () => {
11
- expect(getExplorerTxUrl({ chain, txHash: '0x12345' })).toBe(
12
- `${ChainToExplorerUrl[chain]}/tx/0x12345`,
13
- );
7
+ [
8
+ Chain.Binance,
9
+ Chain.Bitcoin,
10
+ Chain.BitcoinCash,
11
+ Chain.Maya,
12
+ Chain.Kujira,
13
+ Chain.THORChain,
14
+ ].forEach((chain) => {
15
+ test(`getExplorerTxUrl returns correct URL for ${chain}`, () => {
16
+ expect(getExplorerTxUrl({ chain, txHash: '0x123456789' })).toBe(
17
+ `${ChainToExplorerUrl[chain]}/tx/123456789`,
18
+ );
14
19
 
15
- expect(getExplorerAddressUrl({ chain, address: 'asdfg' })).toBe(
16
- `${ChainToExplorerUrl[chain]}/address/asdfg`,
17
- );
18
- });
20
+ expect(getExplorerAddressUrl({ chain, address: 'asdfg' })).toBe(
21
+ `${ChainToExplorerUrl[chain]}/address/asdfg`,
22
+ );
19
23
  });
24
+ });
25
+
26
+ [
27
+ Chain.Arbitrum,
28
+ Chain.Avalanche,
29
+ Chain.BinanceSmartChain,
30
+ Chain.Ethereum,
31
+ Chain.Optimism,
32
+ Chain.Polygon,
33
+ ].forEach((chain) => {
34
+ test(`getExplorerTxUrl returns correct URL for ${chain}`, () => {
35
+ expect(getExplorerTxUrl({ chain, txHash: '0x123456789' })).toBe(
36
+ `${ChainToExplorerUrl[chain]}/tx/0x123456789`,
37
+ );
38
+
39
+ expect(getExplorerAddressUrl({ chain, address: 'asdfg' })).toBe(
40
+ `${ChainToExplorerUrl[chain]}/address/asdfg`,
41
+ );
42
+ });
43
+ });
20
44
 
21
45
  test('getExplorerTxUrl throws Error for unsupported Chain', () => {
22
46
  expect(() =>
@@ -10,7 +10,7 @@ export const getExplorerTxUrl = ({ chain, txHash }: { txHash: string; chain: Cha
10
10
  case Chain.Maya:
11
11
  case Chain.Kujira:
12
12
  case Chain.THORChain:
13
- return `${baseUrl}/tx/${txHash}`;
13
+ return `${baseUrl}/tx/${txHash.startsWith('0x') ? txHash.slice(2) : txHash}`;
14
14
 
15
15
  case Chain.Arbitrum:
16
16
  case Chain.Avalanche:
@@ -68,9 +68,8 @@ export class SwapKitCore<T = ''> {
68
68
  getWallet = <T extends Chain>(chain: Chain) => this.connectedWallets[chain] as WalletMethods[T];
69
69
  getExplorerAddressUrl = (chain: Chain, address: string) =>
70
70
  getExplorerAddressUrl({ chain, address });
71
- getBalance = async (chain: Chain, refresh?: boolean) => {
72
- if (!refresh) return this.connectedChains[chain]?.balance || [];
73
- const wallet = await this.getWalletByChain(chain);
71
+ getBalance = async (chain: Chain, potentialScamFilter?: boolean) => {
72
+ const wallet = await this.getWalletByChain(chain, potentialScamFilter);
74
73
 
75
74
  return wallet?.balance || [];
76
75
  };
@@ -80,8 +79,8 @@ export class SwapKitCore<T = ''> {
80
79
  const evmChain = quoteMode.startsWith('ERC20-')
81
80
  ? Chain.Ethereum
82
81
  : quoteMode.startsWith('ARC20-')
83
- ? Chain.Avalanche
84
- : Chain.BinanceSmartChain;
82
+ ? Chain.Avalanche
83
+ : Chain.BinanceSmartChain;
85
84
 
86
85
  if (!route.complete) throw new SwapKitError('core_swap_route_not_complete');
87
86
 
@@ -95,7 +94,6 @@ export class SwapKitCore<T = ''> {
95
94
  const transaction = streamSwap ? route?.streamingSwap?.transaction : route?.transaction;
96
95
  if (!transaction) throw new SwapKitError('core_swap_route_transaction_not_found');
97
96
 
98
- const { isHexString, parseUnits } = await import('ethers');
99
97
  const { data, from, to, value } = route.transaction;
100
98
 
101
99
  const params = {
@@ -103,11 +101,7 @@ export class SwapKitCore<T = ''> {
103
101
  from,
104
102
  to: to.toLowerCase(),
105
103
  chainId: BigInt(ChainToChainId[evmChain]),
106
- value: value
107
- ? new SwapKitNumber({
108
- value: !isHexString(value) ? parseUnits(value, 'wei').toString(16) : value,
109
- }).baseValueBigInt
110
- : 0n,
104
+ value: value ? BigInt(value) : 0n,
111
105
  };
112
106
 
113
107
  return walletMethods.sendTransaction(params, feeOptionKey) as Promise<string>;
@@ -121,13 +115,20 @@ export class SwapKitCore<T = ''> {
121
115
  const { address: recipient } = await this.#getInboundDataByChain(asset.chain);
122
116
  const {
123
117
  contract: router,
124
- calldata: { amountIn, memo, memoStreamingSwap },
118
+ calldata: { expiration, amountIn, memo, memoStreamingSwap },
125
119
  } = route;
126
120
 
127
121
  const assetValue = asset.add(SwapKitNumber.fromBigInt(BigInt(amountIn), asset.decimal));
128
122
  const swapMemo = (streamSwap ? memoStreamingSwap || memo : memo) as string;
129
123
 
130
- return this.deposit({ assetValue, memo: swapMemo, feeOptionKey, router, recipient });
124
+ return this.deposit({
125
+ expiration,
126
+ assetValue,
127
+ memo: swapMemo,
128
+ feeOptionKey,
129
+ router,
130
+ recipient,
131
+ });
131
132
  }
132
133
 
133
134
  if (SWAP_IN.includes(quoteMode)) {
@@ -148,9 +149,7 @@ export class SwapKitCore<T = ''> {
148
149
 
149
150
  const contract = await walletMethods.createContract?.(contractAddress, abi, provider);
150
151
 
151
- // TODO: (@Towan) Contract evm methods should be generic
152
- // @ts-expect-error
153
- const tx = await contract.populateTransaction.swapIn?.(
152
+ const tx = await contract.getFunction('swapIn').populateTransaction(
154
153
  ...getSwapInParams({
155
154
  streamSwap,
156
155
  toChecksumAddress,
@@ -170,21 +169,27 @@ export class SwapKitCore<T = ''> {
170
169
  }
171
170
  };
172
171
 
173
- getWalletByChain = async (chain: Chain) => {
172
+ getWalletByChain = async (chain: Chain, potentialScamFilter?: boolean) => {
174
173
  const address = this.getAddress(chain);
175
174
  if (!address) return null;
175
+ const defaultBalance = [AssetValue.fromChainOrSignature(chain)];
176
+ const walletType = this.connectedChains[chain]?.walletType as WalletOption;
176
177
 
177
- const balance = (await this.getWallet(chain)?.getBalance(address)) ?? [
178
- AssetValue.fromChainOrSignature(chain),
179
- ];
178
+ try {
179
+ const balance = await this.getWallet(chain)?.getBalance(address, potentialScamFilter);
180
180
 
181
- this.connectedChains[chain] = {
182
- address,
183
- balance,
184
- walletType: this.connectedChains[chain]?.walletType as WalletOption,
185
- };
181
+ this.connectedChains[chain] = {
182
+ address,
183
+ balance: balance?.length ? balance : defaultBalance,
184
+ walletType,
185
+ };
186
+
187
+ return { ...this.connectedChains[chain] };
188
+ } catch (error) {
189
+ console.error(error);
186
190
 
187
- return { ...this.connectedChains[chain] };
191
+ return { address, balance: defaultBalance, walletType };
192
+ }
188
193
  };
189
194
 
190
195
  approveAssetValue = (assetValue: AssetValue, contractAddress?: string) =>
@@ -235,10 +240,10 @@ export class SwapKitCore<T = ''> {
235
240
  chain === Chain.Avalanche
236
241
  ? TCAvalancheDepositABI
237
242
  : chain === Chain.BinanceSmartChain
238
- ? TCBscDepositABI
239
- : TCEthereumVaultAbi;
243
+ ? TCBscDepositABI
244
+ : TCEthereumVaultAbi;
240
245
 
241
- return (await (
246
+ const response = await (
242
247
  walletInstance as EVMWallet<typeof AVAXToolbox | typeof ETHToolbox | typeof BSCToolbox>
243
248
  ).call({
244
249
  abi,
@@ -248,13 +253,17 @@ export class SwapKitCore<T = ''> {
248
253
  funcParams: [
249
254
  recipient,
250
255
  getChecksumAddressFromAsset({ chain, symbol, ticker }, chain),
251
- // TODO: (@Towan) Re-Check on that conversion 🙏
252
- assetValue.baseValueBigInt.toString(),
256
+ assetValue.getBaseValue('string'),
253
257
  params.memo,
254
- rest.expiration,
258
+ rest.expiration || parseInt(`${(new Date().getTime() + 15 * 60 * 1000) / 1000}`),
255
259
  ],
256
- txOverrides: { from: params.from, value: assetValue.baseValueBigInt },
257
- })) as Promise<string>;
260
+ txOverrides: {
261
+ from: params.from,
262
+ value: assetValue.isGasAsset ? assetValue.getBaseValue('bigint') : undefined,
263
+ },
264
+ });
265
+
266
+ return response as string;
258
267
  }
259
268
 
260
269
  default: {
@@ -269,10 +278,10 @@ export class SwapKitCore<T = ''> {
269
278
  const errorKey: Keys = isInsufficientFunds
270
279
  ? 'core_transaction_deposit_insufficient_funds_error'
271
280
  : isGas
272
- ? 'core_transaction_deposit_gas_error'
273
- : isServer
274
- ? 'core_transaction_deposit_server_error'
275
- : 'core_transaction_deposit_error';
281
+ ? 'core_transaction_deposit_gas_error'
282
+ : isServer
283
+ ? 'core_transaction_deposit_server_error'
284
+ : 'core_transaction_deposit_error';
276
285
 
277
286
  throw new SwapKitError(errorKey, error);
278
287
  }
@@ -323,7 +332,6 @@ export class SwapKitCore<T = ''> {
323
332
  };
324
333
 
325
334
  addLiquidity = async ({
326
- poolIdentifier,
327
335
  runeAssetValue,
328
336
  assetValue,
329
337
  runeAddr,
@@ -331,7 +339,6 @@ export class SwapKitCore<T = ''> {
331
339
  isPendingSymmAsset,
332
340
  mode = 'sym',
333
341
  }: {
334
- poolIdentifier: string;
335
342
  runeAssetValue: AssetValue;
336
343
  assetValue: AssetValue;
337
344
  isPendingSymmAsset?: boolean;
@@ -339,7 +346,7 @@ export class SwapKitCore<T = ''> {
339
346
  assetAddr?: string;
340
347
  mode?: 'sym' | 'rune' | 'asset';
341
348
  }) => {
342
- const [chain, ...symbolPath] = poolIdentifier.split('.') as [Chain, string];
349
+ const { chain, symbol } = assetValue;
343
350
  const isSym = mode === 'sym';
344
351
  const runeTransfer = runeAssetValue?.gt(0) && (isSym || mode === 'rune');
345
352
  const assetTransfer = assetValue?.gt(0) && (isSym || mode === 'asset');
@@ -355,13 +362,12 @@ export class SwapKitCore<T = ''> {
355
362
  }
356
363
 
357
364
  let runeTx, assetTx;
358
- const sharedParams = { chain, symbol: symbolPath.join('.') };
359
365
 
360
366
  if (runeTransfer && runeAssetValue) {
361
367
  try {
362
368
  runeTx = await this.#depositToPool({
363
369
  assetValue: runeAssetValue,
364
- memo: getMemoFor(MemoType.DEPOSIT, { ...sharedParams, address: assetAddress }),
370
+ memo: getMemoFor(MemoType.DEPOSIT, { chain, symbol, address: assetAddress }),
365
371
  });
366
372
  } catch (error) {
367
373
  throw new SwapKitError('core_transaction_add_liquidity_rune_error', error);
@@ -372,7 +378,7 @@ export class SwapKitCore<T = ''> {
372
378
  try {
373
379
  assetTx = await this.#depositToPool({
374
380
  assetValue,
375
- memo: getMemoFor(MemoType.DEPOSIT, { ...sharedParams, address: runeAddress }),
381
+ memo: getMemoFor(MemoType.DEPOSIT, { chain, symbol, address: runeAddress }),
376
382
  });
377
383
  } catch (error) {
378
384
  throw new SwapKitError('core_transaction_add_liquidity_asset_error', error);
@@ -382,6 +388,25 @@ export class SwapKitCore<T = ''> {
382
388
  return { runeTx, assetTx };
383
389
  };
384
390
 
391
+ addLiquidityPart = ({
392
+ assetValue,
393
+ poolAddress,
394
+ address,
395
+ symmetric,
396
+ }: {
397
+ assetValue: AssetValue;
398
+ address?: string;
399
+ poolAddress: string;
400
+ symmetric: boolean;
401
+ }) => {
402
+ if (symmetric && !address) {
403
+ throw new SwapKitError('core_transaction_add_liquidity_invalid_params');
404
+ }
405
+ const addressString = symmetric ? address || '' : '';
406
+
407
+ return this.#depositToPool({ assetValue, memo: `+:${poolAddress}:${addressString}:t:0` });
408
+ };
409
+
385
410
  withdraw = async ({
386
411
  memo,
387
412
  assetValue,
@@ -399,28 +424,22 @@ export class SwapKitCore<T = ''> {
399
424
  to === 'rune'
400
425
  ? AssetValue.fromChainOrSignature(Chain.THORChain)
401
426
  : (from === 'sym' && to === 'sym') || from === 'rune' || from === 'asset'
402
- ? undefined
403
- : assetValue;
427
+ ? undefined
428
+ : assetValue;
404
429
 
405
- try {
406
- const txHash = await this.#depositToPool({
407
- assetValue: getMinAmountByChain(from === 'asset' ? assetValue.chain : Chain.THORChain),
408
- memo:
409
- memo ||
410
- getMemoFor(MemoType.WITHDRAW, {
411
- symbol: assetValue.symbol,
412
- chain: assetValue.chain,
413
- ticker: assetValue.ticker,
414
- basisPoints: Math.max(10000, Math.round(percent * 100)),
415
- targetAssetString: targetAsset?.toString(),
416
- singleSide: false,
417
- }),
430
+ const value = getMinAmountByChain(from === 'asset' ? assetValue.chain : Chain.THORChain);
431
+ const memoString =
432
+ memo ||
433
+ getMemoFor(MemoType.WITHDRAW, {
434
+ symbol: assetValue.symbol,
435
+ chain: assetValue.chain,
436
+ ticker: assetValue.ticker,
437
+ basisPoints: Math.max(10000, Math.round(percent * 100)),
438
+ targetAssetString: targetAsset?.toString(),
439
+ singleSide: false,
418
440
  });
419
441
 
420
- return txHash;
421
- } catch (error) {
422
- throw new SwapKitError('core_transaction_withdraw_error', error);
423
- }
442
+ return this.#depositToPool({ assetValue: value, memo: memoString });
424
443
  };
425
444
 
426
445
  savings = async ({
@@ -440,10 +459,13 @@ export class SwapKitCore<T = ''> {
440
459
  symbol: assetValue.symbol,
441
460
  chain: assetValue.chain,
442
461
  singleSide: true,
443
- basisPoints: percent ? Math.max(10000, Math.round(percent * 100)) : undefined,
462
+ basisPoints: percent ? Math.min(10000, Math.round(percent * 100)) : undefined,
444
463
  });
445
464
 
446
- return this.#depositToPool({ assetValue, memo: memoString });
465
+ const value =
466
+ memoType === MemoType.DEPOSIT ? assetValue : getMinAmountByChain(assetValue.chain);
467
+
468
+ return this.#depositToPool({ memo: memoString, assetValue: value });
447
469
  };
448
470
 
449
471
  loan = ({
@@ -480,7 +502,7 @@ export class SwapKitCore<T = ''> {
480
502
  type === 'bond' ? MemoType.BOND : type === 'unbond' ? MemoType.UNBOND : MemoType.LEAVE;
481
503
  const memo = getMemoFor(memoType, {
482
504
  address,
483
- unbondAmount: type === 'unbond' ? assetValue.baseValueNumber : undefined,
505
+ unbondAmount: type === 'unbond' ? assetValue.getBaseValue('number') : undefined,
484
506
  });
485
507
 
486
508
  return this.#thorchainTransfer({
@@ -498,7 +520,7 @@ export class SwapKitCore<T = ''> {
498
520
  extend = ({ wallets, config, apis = {}, rpcUrls = {} }: ExtendParams<T>) => {
499
521
  try {
500
522
  wallets.forEach((wallet) => {
501
- // @ts-expect-error ANCHOR - Not Worth
523
+ // @ts-expect-error - this is fine as we are extending the class
502
524
  this[wallet.connectMethodName] = wallet.connect({
503
525
  addChain: this.#addConnectedChain,
504
526
  config: config || {},
@@ -612,7 +634,7 @@ export class SwapKitCore<T = ''> {
612
634
  };
613
635
 
614
636
  #approve = async <T = string>({
615
- assetValue: { baseValueBigInt, address, chain, isGasAsset, isSynthetic },
637
+ assetValue,
616
638
  type = 'checkOnly',
617
639
  contractAddress,
618
640
  }: {
@@ -620,6 +642,7 @@ export class SwapKitCore<T = ''> {
620
642
  type?: 'checkOnly' | 'approve';
621
643
  contractAddress?: string;
622
644
  }) => {
645
+ const { address, chain, isGasAsset, isSynthetic } = assetValue;
623
646
  const isEVMChain = [Chain.Ethereum, Chain.Avalanche, Chain.BinanceSmartChain].includes(chain);
624
647
  const isNativeEVM = isEVMChain && isGasAsset;
625
648
 
@@ -638,7 +661,7 @@ export class SwapKitCore<T = ''> {
638
661
  contractAddress || ((await this.#getInboundDataByChain(chain)).router as string);
639
662
 
640
663
  return walletAction({
641
- amount: baseValueBigInt,
664
+ amount: assetValue.getBaseValue('bigint'),
642
665
  assetAddress: address,
643
666
  from,
644
667
  spenderAddress,
@@ -1,4 +1,4 @@
1
- import { getRequest } from '@swapkit/helpers';
1
+ import { RequestClient } from '@swapkit/helpers';
2
2
  import type { Chain } from '@swapkit/types';
3
3
  import { ApiUrl } from '@swapkit/types';
4
4
 
@@ -21,11 +21,11 @@ type InboundAddressData = {
21
21
  export const getInboundData = (stagenet: boolean) => {
22
22
  const baseUrl = stagenet ? ApiUrl.ThornodeStagenet : ApiUrl.ThornodeMainnet;
23
23
 
24
- return getRequest<InboundAddressData>(`${baseUrl}/thorchain/inbound_addresses`);
24
+ return RequestClient.get<InboundAddressData>(`${baseUrl}/thorchain/inbound_addresses`);
25
25
  };
26
26
 
27
27
  export const getMimirData = (stagenet: boolean) => {
28
28
  const baseUrl = stagenet ? ApiUrl.ThornodeStagenet : ApiUrl.ThornodeMainnet;
29
29
 
30
- return getRequest<Record<string, number>>(`${baseUrl}/thorchain/mimir`);
30
+ return RequestClient.get<Record<string, number>>(`${baseUrl}/thorchain/mimir`);
31
31
  };
@@ -1 +0,0 @@
1
- "use strict";var nt=Object.defineProperty;var st=(e,t,r)=>t in e?nt(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r;var j=(e,t,r)=>(st(e,typeof t!="symbol"?t+"":t,r),r),D=(e,t,r)=>{if(!t.has(e))throw TypeError("Cannot "+r)};var s=(e,t,r)=>(D(e,t,"read from private field"),r?r.call(e):t.get(e)),b=(e,t,r)=>{if(t.has(e))throw TypeError("Cannot add the same private member more than once");t instanceof WeakSet?t.add(e):t.set(e,r)},M=(e,t,r,i)=>(D(e,t,"write to private field"),i?i.call(e,r):t.set(e,r),r);var u=(e,t,r)=>(D(e,t,"access private method"),r);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const Q="6.7.1";function ot(e,t,r){const i=t.split("|").map(o=>o.trim());for(let o=0;o<i.length;o++)switch(t){case"any":return;case"bigint":case"boolean":case"number":case"string":if(typeof e===t)return}const n=new Error(`invalid value for type ${t}`);throw n.code="INVALID_ARGUMENT",n.argument=`value.${r}`,n.value=e,n}function K(e,t,r){for(let i in t){let n=t[i];const o=r?r[i]:null;o&&ot(n,o,i),Object.defineProperty(e,i,{enumerable:!0,value:n,writable:!1})}}function x(e){if(e==null)return"null";if(Array.isArray(e))return"[ "+e.map(x).join(", ")+" ]";if(e instanceof Uint8Array){const t="0123456789abcdef";let r="0x";for(let i=0;i<e.length;i++)r+=t[e[i]>>4],r+=t[e[i]&15];return r}if(typeof e=="object"&&typeof e.toJSON=="function")return x(e.toJSON());switch(typeof e){case"boolean":case"symbol":return e.toString();case"bigint":return BigInt(e).toString();case"number":return e.toString();case"string":return JSON.stringify(e);case"object":{const t=Object.keys(e);return t.sort(),"{ "+t.map(r=>`${x(r)}: ${x(e[r])}`).join(", ")+" }"}}return"[ COULD NOT SERIALIZE ]"}function W(e,t,r){{const n=[];if(r){if("message"in r||"code"in r||"name"in r)throw new Error(`value will overwrite populated values: ${x(r)}`);for(const o in r){const l=r[o];n.push(o+"="+x(l))}}n.push(`code=${t}`),n.push(`version=${Q}`),n.length&&(e+=" ("+n.join(", ")+")")}let i;switch(t){case"INVALID_ARGUMENT":i=new TypeError(e);break;case"NUMERIC_FAULT":case"BUFFER_OVERRUN":i=new RangeError(e);break;default:i=new Error(e)}return K(i,{code:t}),r&&Object.assign(i,r),i}function g(e,t,r,i){if(!e)throw W(t,r,i)}function c(e,t,r,i){g(e,t,"INVALID_ARGUMENT",{argument:r,value:i})}["NFD","NFC","NFKD","NFKC"].reduce((e,t)=>{try{if("test".normalize(t)!=="test")throw new Error("bad");if(t==="NFD"){const r=String.fromCharCode(233).normalize("NFD"),i=String.fromCharCode(101,769);if(r!==i)throw new Error("broken")}e.push(t)}catch{}return e},[]);function Y(e,t,r){if(r==null&&(r=""),e!==t){let i=r,n="new";r&&(i+=".",n+=" "+r),g(!1,`private constructor; use ${i}from* methods`,"UNSUPPORTED_OPERATION",{operation:n})}}function ft(e,t,r){if(e instanceof Uint8Array)return r?new Uint8Array(e):e;if(typeof e=="string"&&e.match(/^0x([0-9a-f][0-9a-f])*$/i)){const i=new Uint8Array((e.length-2)/2);let n=2;for(let o=0;o<i.length;o++)i[o]=parseInt(e.substring(n,n+2),16),n+=2;return i}c(!1,"invalid BytesLike value",t||"value",e)}function tt(e,t){return ft(e,t,!1)}function ut(e,t){return!(typeof e!="string"||!e.match(/^0x[0-9A-Fa-f]*$/)||typeof t=="number"&&e.length!==2+2*t||t===!0&&e.length%2!==0)}const et=BigInt(0),E=BigInt(1),S=9007199254740991;function k(e,t){const r=q(e,"value"),i=BigInt(T(t,"width"));if(g(r>>i===et,"overflow","NUMERIC_FAULT",{operation:"fromTwos",fault:"overflow",value:e}),r>>i-E){const n=(E<<i)-E;return-((~r&n)+E)}return r}function z(e,t){const r=q(e,"value"),i=BigInt(T(t,"bits"));return r&(E<<i)-E}function V(e,t){switch(typeof e){case"bigint":return e;case"number":return c(Number.isInteger(e),"underflow",t||"value",e),c(e>=-S&&e<=S,"overflow",t||"value",e),BigInt(e);case"string":try{if(e==="")throw new Error("empty string");return e[0]==="-"&&e[1]!=="-"?-BigInt(e.substring(1)):BigInt(e)}catch(r){c(!1,`invalid BigNumberish string: ${r.message}`,t||"value",e)}}c(!1,"invalid BigNumberish value",t||"value",e)}function q(e,t){const r=V(e,t);return g(r>=et,"unsigned value cannot be negative","NUMERIC_FAULT",{fault:"overflow",operation:"getUint",value:e}),r}const X="0123456789abcdef";function rt(e){if(e instanceof Uint8Array){let t="0x0";for(const r of e)t+=X[r>>4],t+=X[r&15];return BigInt(t)}return V(e)}function T(e,t){switch(typeof e){case"bigint":return c(e>=-S&&e<=S,"overflow",t||"value",e),Number(e);case"number":return c(Number.isInteger(e),"underflow",t||"value",e),c(e>=-S&&e<=S,"overflow",t||"value",e),e;case"string":try{if(e==="")throw new Error("empty string");return T(BigInt(e),t)}catch(r){c(!1,`invalid numeric string: ${r.message}`,t||"value",e)}}c(!1,"invalid numeric value",t||"value",e)}const ct=BigInt(-1),d=BigInt(0),F=BigInt(1),lt=BigInt(5),B={};let A="0000";for(;A.length<80;)A+=A;function y(e){let t=A;for(;t.length<e;)t+=t;return BigInt("1"+t.substring(0,e))}function C(e,t,r){const i=BigInt(t.width);if(t.signed){const n=F<<i-F;g(r==null||e>=-n&&e<n,"overflow","NUMERIC_FAULT",{operation:r,fault:"overflow",value:e}),e>d?e=k(z(e,i),i):e=-k(z(-e,i),i)}else{const n=F<<i;g(r==null||e>=0&&e<n,"overflow","NUMERIC_FAULT",{operation:r,fault:"overflow",value:e}),e=(e%n+n)%n&n-F}return e}function P(e){typeof e=="number"&&(e=`fixed128x${e}`);let t=!0,r=128,i=18;if(typeof e=="string"){if(e!=="fixed")if(e==="ufixed")t=!1;else{const o=e.match(/^(u?)fixed([0-9]+)x([0-9]+)$/);c(o,"invalid fixed format","format",e),t=o[1]!=="u",r=parseInt(o[2]),i=parseInt(o[3])}}else if(e){const o=e,l=(h,R,it)=>o[h]==null?it:(c(typeof o[h]===R,"invalid fixed format ("+h+" not "+R+")","format."+h,o[h]),o[h]);t=l("signed","boolean",t),r=l("width","number",r),i=l("decimals","number",i)}c(r%8===0,"invalid FixedNumber width (not byte aligned)","format.width",r),c(i<=80,"invalid FixedNumber decimals (too large)","format.decimals",i);const n=(t?"":"u")+"fixed"+String(r)+"x"+String(i);return{signed:t,width:r,decimals:i,name:n}}function at(e,t){let r="";e<d&&(r="-",e*=ct);let i=e.toString();if(t===0)return r+i;for(;i.length<=t;)i=A+i;const n=i.length-t;for(i=i.substring(0,n)+"."+i.substring(n);i[0]==="0"&&i[1]!==".";)i=i.substring(1);for(;i[i.length-1]==="0"&&i[i.length-2]!==".";)i=i.substring(0,i.length-1);return r+i}var m,f,a,N,U,w,p,$,G,L,H,v,J,_,Z;const I=class I{constructor(t,r,i){b(this,N);b(this,w);b(this,$);b(this,L);b(this,v);b(this,_);j(this,"format");b(this,m,void 0);b(this,f,void 0);b(this,a,void 0);j(this,"_value");Y(t,B,"FixedNumber"),M(this,f,r),M(this,m,i);const n=at(r,i.decimals);K(this,{format:i.name,_value:n}),M(this,a,y(i.decimals))}get signed(){return s(this,m).signed}get width(){return s(this,m).width}get decimals(){return s(this,m).decimals}get value(){return s(this,f)}addUnsafe(t){return u(this,$,G).call(this,t)}add(t){return u(this,$,G).call(this,t,"add")}subUnsafe(t){return u(this,L,H).call(this,t)}sub(t){return u(this,L,H).call(this,t,"sub")}mulUnsafe(t){return u(this,v,J).call(this,t)}mul(t){return u(this,v,J).call(this,t,"mul")}mulSignal(t){u(this,N,U).call(this,t);const r=s(this,f)*s(t,f);return g(r%s(this,a)===d,"precision lost during signalling mul","NUMERIC_FAULT",{operation:"mulSignal",fault:"underflow",value:this}),u(this,w,p).call(this,r/s(this,a),"mulSignal")}divUnsafe(t){return u(this,_,Z).call(this,t)}div(t){return u(this,_,Z).call(this,t,"div")}divSignal(t){g(s(t,f)!==d,"division by zero","NUMERIC_FAULT",{operation:"div",fault:"divide-by-zero",value:this}),u(this,N,U).call(this,t);const r=s(this,f)*s(this,a);return g(r%s(t,f)===d,"precision lost during signalling div","NUMERIC_FAULT",{operation:"divSignal",fault:"underflow",value:this}),u(this,w,p).call(this,r/s(t,f),"divSignal")}cmp(t){let r=this.value,i=t.value;const n=this.decimals-t.decimals;return n>0?i*=y(n):n<0&&(r*=y(-n)),r<i?-1:r>i?1:0}eq(t){return this.cmp(t)===0}lt(t){return this.cmp(t)<0}lte(t){return this.cmp(t)<=0}gt(t){return this.cmp(t)>0}gte(t){return this.cmp(t)>=0}floor(){let t=s(this,f);return s(this,f)<d&&(t-=s(this,a)-F),t=s(this,f)/s(this,a)*s(this,a),u(this,w,p).call(this,t,"floor")}ceiling(){let t=s(this,f);return s(this,f)>d&&(t+=s(this,a)-F),t=s(this,f)/s(this,a)*s(this,a),u(this,w,p).call(this,t,"ceiling")}round(t){if(t==null&&(t=0),t>=this.decimals)return this;const r=this.decimals-t,i=lt*y(r-1);let n=this.value+i;const o=y(r);return n=n/o*o,C(n,s(this,m),"round"),new I(B,n,s(this,m))}isZero(){return s(this,f)===d}isNegative(){return s(this,f)<d}toString(){return this._value}toUnsafeFloat(){return parseFloat(this.toString())}toFormat(t){return I.fromString(this.toString(),t)}static fromValue(t,r,i){const n=r==null?0:T(r),o=P(i);let l=V(t,"value");const h=n-o.decimals;if(h>0){const R=y(h);g(l%R===d,"value loses precision for format","NUMERIC_FAULT",{operation:"fromValue",fault:"underflow",value:t}),l/=R}else h<0&&(l*=y(-h));return C(l,o,"fromValue"),new I(B,l,o)}static fromString(t,r){const i=t.match(/^(-?)([0-9]*)\.?([0-9]*)$/);c(i&&i[2].length+i[3].length>0,"invalid FixedNumber string value","value",t);const n=P(r);let o=i[2]||"0",l=i[3]||"";for(;l.length<n.decimals;)l+=A;g(l.substring(n.decimals).match(/^0*$/),"too many decimals for format","NUMERIC_FAULT",{operation:"fromString",fault:"underflow",value:t}),l=l.substring(0,n.decimals);const h=BigInt(i[1]+o+l);return C(h,n,"fromString"),new I(B,h,n)}static fromBytes(t,r){let i=rt(tt(t,"value"));const n=P(r);return n.signed&&(i=k(i,n.width)),C(i,n,"fromBytes"),new I(B,i,n)}};m=new WeakMap,f=new WeakMap,a=new WeakMap,N=new WeakSet,U=function(t){c(this.format===t.format,"incompatible format; use fixedNumber.toFormat","other",t)},w=new WeakSet,p=function(t,r){return t=C(t,s(this,m),r),new I(B,t,s(this,m))},$=new WeakSet,G=function(t,r){return u(this,N,U).call(this,t),u(this,w,p).call(this,s(this,f)+s(t,f),r)},L=new WeakSet,H=function(t,r){return u(this,N,U).call(this,t),u(this,w,p).call(this,s(this,f)-s(t,f),r)},v=new WeakSet,J=function(t,r){return u(this,N,U).call(this,t),u(this,w,p).call(this,s(this,f)*s(t,f)/s(this,a),r)},_=new WeakSet,Z=function(t,r){return g(s(t,f)!==d,"division by zero","NUMERIC_FAULT",{operation:"div",fault:"divide-by-zero",value:this}),u(this,N,U).call(this,t),u(this,w,p).call(this,s(this,f)*s(this,a)/s(t,f),r)};let O=I;const ht=["wei","kwei","mwei","gwei","szabo","finney","ether"];function gt(e,t){c(typeof e=="string","value must be a string","value",e);let r=18;if(typeof t=="string"){const i=ht.indexOf(t);c(i>=0,"invalid unit","unit",t),r=3*i}else t!=null&&(r=T(t,"unit"));return O.fromString(e,{decimals:r,width:512}).value}exports.FixedNumber=O;exports.assert=g;exports.assertArgument=c;exports.assertPrivate=Y;exports.defineProperties=K;exports.fromTwos=k;exports.getBigInt=V;exports.getBytes=tt;exports.getNumber=T;exports.getUint=q;exports.isHexString=ut;exports.makeError=W;exports.mask=z;exports.parseUnits=gt;exports.toBigInt=rt;exports.version=Q;