diff --git a/typescript/infra/package.json b/typescript/infra/package.json
index 268bea8315..206c2ac336 100644
--- a/typescript/infra/package.json
+++ b/typescript/infra/package.json
@@ -1,7 +1,7 @@
{
"name": "@hyperlane-xyz/infra",
"description": "Infrastructure utilities for the Hyperlane Network",
- "version": "3.1.2",
+ "version": "3.1.3",
"dependencies": {
"@arbitrum/sdk": "^3.0.0",
"@aws-sdk/client-iam": "^3.74.0",
diff --git a/typescript/infra/src/config/gas-oracle.ts b/typescript/infra/src/config/gas-oracle.ts
index 41bf8ccac7..812314220a 100644
--- a/typescript/infra/src/config/gas-oracle.ts
+++ b/typescript/infra/src/config/gas-oracle.ts
@@ -1,7 +1,7 @@
import { BigNumber, ethers } from 'ethers';
import { ChainMap, ChainName } from '@hyperlane-xyz/sdk';
-import { convertDecimalsEthersBigNumber } from '@hyperlane-xyz/utils';
+import { convertDecimals } from '@hyperlane-xyz/utils';
import { mustGetChainNativeTokenDecimals } from '../utils/utils';
@@ -77,15 +77,17 @@ export function getTokenExchangeRateFromValues(
localValue: BigNumber,
remote: ChainName,
remoteValue: BigNumber,
-) {
+): BigNumber {
// This does not yet account for decimals!
const exchangeRate = remoteValue
.mul(TOKEN_EXCHANGE_RATE_MULTIPLIER)
.div(localValue);
- return convertDecimalsEthersBigNumber(
- mustGetChainNativeTokenDecimals(remote),
- mustGetChainNativeTokenDecimals(local),
- exchangeRate,
+ return BigNumber.from(
+ convertDecimals(
+ mustGetChainNativeTokenDecimals(remote),
+ mustGetChainNativeTokenDecimals(local),
+ exchangeRate.toString(),
+ ),
);
}
diff --git a/typescript/sdk/logos/black/base.svg b/typescript/sdk/logos/black/base.svg
new file mode 100644
index 0000000000..be9b3c0889
--- /dev/null
+++ b/typescript/sdk/logos/black/base.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/typescript/sdk/logos/black/polygonzkevm.svg b/typescript/sdk/logos/black/polygonzkevm.svg
new file mode 100644
index 0000000000..2457c2bfbc
--- /dev/null
+++ b/typescript/sdk/logos/black/polygonzkevm.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/typescript/sdk/logos/black/scroll.svg b/typescript/sdk/logos/black/scroll.svg
new file mode 100644
index 0000000000..77e7199a9d
--- /dev/null
+++ b/typescript/sdk/logos/black/scroll.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/typescript/sdk/logos/color/base.svg b/typescript/sdk/logos/color/base.svg
new file mode 100644
index 0000000000..59182e5dd7
--- /dev/null
+++ b/typescript/sdk/logos/color/base.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/typescript/sdk/logos/color/polygonzkevm.svg b/typescript/sdk/logos/color/polygonzkevm.svg
new file mode 100644
index 0000000000..98cca40919
--- /dev/null
+++ b/typescript/sdk/logos/color/polygonzkevm.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/typescript/sdk/logos/color/scroll.svg b/typescript/sdk/logos/color/scroll.svg
new file mode 100644
index 0000000000..541dc4433f
--- /dev/null
+++ b/typescript/sdk/logos/color/scroll.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/typescript/utils/index.ts b/typescript/utils/index.ts
index 35e81292dd..08abee53a1 100644
--- a/typescript/utils/index.ts
+++ b/typescript/utils/index.ts
@@ -39,7 +39,6 @@ export {
} from './src/addresses';
export {
convertDecimals,
- convertDecimalsEthersBigNumber,
eqAmountApproximate,
fromWei,
fromWeiRounded,
diff --git a/typescript/utils/package.json b/typescript/utils/package.json
index 88e09f1640..4d3947371f 100644
--- a/typescript/utils/package.json
+++ b/typescript/utils/package.json
@@ -29,7 +29,7 @@
"clean": "rm -rf ./dist",
"check": "tsc --noEmit",
"prettier": "prettier --write ./src",
- "test:unit": "mocha --config .mocharc.json './src/**/*.test.ts'"
+ "test": "mocha --config .mocharc.json './src/**/*.test.ts'"
},
"sideEffects": false,
"types": "dist/index.d.ts",
diff --git a/typescript/utils/src/amount.test.ts b/typescript/utils/src/amount.test.ts
new file mode 100644
index 0000000000..4ba6c9962a
--- /dev/null
+++ b/typescript/utils/src/amount.test.ts
@@ -0,0 +1,54 @@
+import { expect } from 'chai';
+
+import { eqAmountApproximate, fromWei, fromWeiRounded, toWei } from './amount';
+
+describe('fromWei', () => {
+ it('parses and converts correctly', () => {
+ expect(fromWei(1, 0)).to.equal('1');
+ expect(fromWei('1000000', 6)).to.equal('1');
+ expect(fromWei('1000000000000000000')).to.equal('1');
+ expect(fromWei('1000000000000000000.1234')).to.equal('1');
+ });
+});
+
+describe('fromWeiRounded', () => {
+ it('parses and converts correctly', () => {
+ expect(fromWeiRounded(1, 0)).to.equal('1.0000');
+ expect(fromWeiRounded('1000000', 6)).to.equal('1.0000');
+ expect(fromWeiRounded('1000000000000000000')).to.equal('1.0000');
+ expect(fromWeiRounded('1000000000000000000.1234')).to.equal('1.0000');
+ });
+
+ it('rounds correctly', () => {
+ expect(fromWeiRounded(1234567890, 6, 2)).to.equal('1234.56');
+ expect(fromWeiRounded('1234567890', 6, 4)).to.equal('1234.5678');
+ expect(fromWeiRounded('10000000000000000000')).to.equal('10.0000');
+ expect(fromWeiRounded('10000000000000000000', 18, 0)).to.equal('10');
+ });
+
+ it('can drop decimals for large numbers', () => {
+ expect(fromWeiRounded('10001000000000000000000')).to.equal('10001.00');
+ expect(fromWeiRounded('10001000000000000000', 15, 4)).to.equal(
+ '10001.0000',
+ );
+ });
+});
+
+describe('toWei', () => {
+ it('parses and converts correctly', () => {
+ expect(toWei(1, 0)).to.equal('1');
+ expect(toWei('1', 6)).to.equal('1000000');
+ expect(toWei('123.456')).to.equal('123456000000000000000');
+ expect(toWei('1.00000000000000000001')).to.equal('1000000000000000000');
+ expect(toWei('1.00000000000000000001', 6)).to.equal('1000000');
+ });
+});
+
+describe('eqAmountApproximate', () => {
+ it('compares correctly', () => {
+ expect(eqAmountApproximate(1, 1.001, 0.001)).to.be.true;
+ expect(eqAmountApproximate(9, 9.001, 0.01)).to.be.true;
+ expect(eqAmountApproximate('9876543210', '9876543210', '1')).to.be.true;
+ expect(eqAmountApproximate('9876543210', '9876543212', '1')).to.be.false;
+ });
+});
diff --git a/typescript/utils/src/amount.ts b/typescript/utils/src/amount.ts
index 5f4dc83390..f46998230e 100644
--- a/typescript/utils/src/amount.ts
+++ b/typescript/utils/src/amount.ts
@@ -1,14 +1,9 @@
import { formatUnits, parseUnits } from '@ethersproject/units';
import BigNumber from 'bignumber.js';
-import { ethers } from 'ethers';
-const DEFAULT_MIN_ROUNDED_VALUE = 0.00001;
const DEFAULT_DISPLAY_DECIMALS = 4;
const DEFAULT_TOKEN_DECIMALS = 18;
-// Use toString(10) on bignumber.js to prevent ethers.js bigNumber error
-// when parsing exponential string over e21
-
/**
* Convert the given Wei value to Ether value
* @param value The value to convert.
@@ -34,21 +29,14 @@ export function fromWei(
export function fromWeiRounded(
value: BigNumber.Value | null | undefined,
decimals = DEFAULT_TOKEN_DECIMALS,
- roundDownIfSmall = true,
+ displayDecimals?: number,
): string {
if (!value) return '0';
const flooredValue = BigNumber(value).toFixed(0, BigNumber.ROUND_FLOOR);
const amount = BigNumber(formatUnits(flooredValue, decimals));
if (amount.isZero()) return '0';
-
- // If amount is less than min value
- if (amount.lt(DEFAULT_MIN_ROUNDED_VALUE)) {
- if (roundDownIfSmall) return '0';
- return amount.toString(10);
- }
-
- const displayDecimals = amount.gte(10000) ? 2 : DEFAULT_DISPLAY_DECIMALS;
- return amount.toFixed(displayDecimals);
+ displayDecimals ??= amount.gte(10000) ? 2 : DEFAULT_DISPLAY_DECIMALS;
+ return amount.toFixed(displayDecimals, BigNumber.ROUND_FLOOR);
}
/**
@@ -101,17 +89,17 @@ export function tryParseAmount(
/**
* Checks if an amount is equal of nearly equal to balance within a small margin of error
* Necessary because amounts in the UI are often rounded
- * @param amountInWei1 The amount to compare.
- * @param amountInWei2 The amount to compare.
+ * @param amount1 The amount to compare.
+ * @param amount2 The amount to compare.
* @returns true/false.
*/
export function eqAmountApproximate(
- amountInWei1: BigNumber.Value,
- amountInWei2: BigNumber.Value,
+ amount1: BigNumber.Value,
+ amount2: BigNumber.Value,
+ maxDifference: BigNumber.Value,
): boolean {
- const minValueWei = toWei(DEFAULT_MIN_ROUNDED_VALUE);
- // Is difference btwn amount and balance less than min amount shown for token
- return BigNumber(amountInWei1).minus(amountInWei2).abs().lt(minValueWei);
+ // Is difference btwn amounts less than maxDifference
+ return BigNumber(amount1).minus(amount2).abs().lte(maxDifference);
}
/**
@@ -143,28 +131,3 @@ export function convertDecimals(
return amount.times(BigNumber(10).pow(difference)).toString(10);
}
}
-
-/**
- * Converts a value with `fromDecimals` decimals to a value with `toDecimals` decimals.
- * Incurs a loss of precision when `fromDecimals` > `toDecimals`.
- * @param fromDecimals The number of decimals `value` has.
- * @param toDecimals The number of decimals to convert `value` to.
- * @param value The value to convert.
- * @returns `value` represented with `toDecimals` decimals.
- */
-export function convertDecimalsEthersBigNumber(
- fromDecimals: number,
- toDecimals: number,
- value: ethers.BigNumber,
-) {
- if (fromDecimals === toDecimals) return value;
- else if (fromDecimals > toDecimals) {
- const difference = fromDecimals - toDecimals;
- return value.div(ethers.BigNumber.from('10').pow(difference));
- }
- // fromDecimals < toDecimals
- else {
- const difference = toDecimals - fromDecimals;
- return value.mul(ethers.BigNumber.from('10').pow(difference));
- }
-}
diff --git a/typescript/utils/src/big-numbers.test.ts b/typescript/utils/src/big-numbers.test.ts
index 1de260be67..82efee036d 100644
--- a/typescript/utils/src/big-numbers.test.ts
+++ b/typescript/utils/src/big-numbers.test.ts
@@ -12,109 +12,107 @@ import {
mulBigAndFixed,
} from './big-numbers';
-describe('utils', () => {
- describe('isBigNumberish', () => {
- const testCases = [
- { expect: false, context: 'invalid number', case: 'invalidNumber' },
- { expect: false, context: 'NaN', case: NaN },
- { expect: false, context: 'undefined', case: undefined },
- { expect: false, context: 'null', case: null },
- { expect: true, context: 'decimal', case: 123.123 },
- { expect: true, context: 'integer', case: 300_000 },
- { expect: true, context: 'hex 0', case: 0x00 },
- { expect: true, context: 'hex 0', case: 0x000 },
- {
- expect: true,
- context: 'address 0',
- case: 0x0000000000000000000000000000000000000000,
- },
- ];
- testCases.forEach((tc) => {
- it(`returns ${tc.expect} for ${tc.case}`, () => {
- expect(isBigNumberish(tc.case!)).to.equal(tc.expect);
- });
+describe('isBigNumberish', () => {
+ const testCases = [
+ { expect: false, context: 'invalid number', case: 'invalidNumber' },
+ { expect: false, context: 'NaN', case: NaN },
+ { expect: false, context: 'undefined', case: undefined },
+ { expect: false, context: 'null', case: null },
+ { expect: true, context: 'decimal', case: 123.123 },
+ { expect: true, context: 'integer', case: 300_000 },
+ { expect: true, context: 'hex 0', case: 0x00 },
+ { expect: true, context: 'hex 0', case: 0x000 },
+ {
+ expect: true,
+ context: 'address 0',
+ case: 0x0000000000000000000000000000000000000000,
+ },
+ ];
+ testCases.forEach((tc) => {
+ it(`returns ${tc.expect} for ${tc.case}`, () => {
+ expect(isBigNumberish(tc.case!)).to.equal(tc.expect);
});
});
+});
- describe('isZeroish', () => {
- const testCases = [
- { expect: false, context: 'invalid number', case: 'invalidNumber' },
- { expect: false, context: 'NaN', case: NaN },
- { expect: false, context: 'undefined', case: undefined },
- { expect: false, context: 'null', case: null },
- { expect: false, context: 'non 0 decimal', case: 123.123 },
- { expect: false, context: 'non 0 integer', case: 123 },
- { expect: true, context: 'hex 0', case: 0x00 },
- { expect: true, context: 'hex 0', case: 0x000 },
- {
- expect: true,
- context: 'address 0',
- case: 0x0000000000000000000000000000000000000000,
- },
- ];
- testCases.forEach((tc) => {
- it(`returns ${tc.expect} for ${tc.case}`, () => {
- expect(isZeroish(tc.case!)).to.equal(tc.expect);
- });
+describe('isZeroish', () => {
+ const testCases = [
+ { expect: false, context: 'invalid number', case: 'invalidNumber' },
+ { expect: false, context: 'NaN', case: NaN },
+ { expect: false, context: 'undefined', case: undefined },
+ { expect: false, context: 'null', case: null },
+ { expect: false, context: 'non 0 decimal', case: 123.123 },
+ { expect: false, context: 'non 0 integer', case: 123 },
+ { expect: true, context: 'hex 0', case: 0x00 },
+ { expect: true, context: 'hex 0', case: 0x000 },
+ {
+ expect: true,
+ context: 'address 0',
+ case: 0x0000000000000000000000000000000000000000,
+ },
+ ];
+ testCases.forEach((tc) => {
+ it(`returns ${tc.expect} for ${tc.case}`, () => {
+ expect(isZeroish(tc.case!)).to.equal(tc.expect);
});
});
+});
- describe('bigToFixed', () => {
- it('converts a BigNumber to a FixedNumber', () => {
- const big = BigNumber('7.5e-10');
- const fixed = bigToFixed(big);
+describe('bigToFixed', () => {
+ it('converts a BigNumber to a FixedNumber', () => {
+ const big = BigNumber('7.5e-10');
+ const fixed = bigToFixed(big);
- expect(fixed.toUnsafeFloat()).to.equal(7.5e-10);
- });
+ expect(fixed.toUnsafeFloat()).to.equal(7.5e-10);
});
+});
- describe('fixedToBig', () => {
- it('converts a FixedNumber to a floored BigNumber', () => {
- const fixed = FixedNumber.from('12.34');
- const big = fixedToBig(fixed);
+describe('fixedToBig', () => {
+ it('converts a FixedNumber to a floored BigNumber', () => {
+ const fixed = FixedNumber.from('12.34');
+ const big = fixedToBig(fixed);
- expect(big.toNumber()).to.equal(12);
- });
+ expect(big.toNumber()).to.equal(12);
+ });
- it('converts a FixedNumber to a ceilinged BigNumber', () => {
- const fixed = FixedNumber.from('12.34');
- const big = fixedToBig(fixed, true);
+ it('converts a FixedNumber to a ceilinged BigNumber', () => {
+ const fixed = FixedNumber.from('12.34');
+ const big = fixedToBig(fixed, true);
- expect(big.toNumber()).to.equal(13);
- });
+ expect(big.toNumber()).to.equal(13);
});
+});
- describe('mulBigAndFixed', () => {
- it('gets the floored product of a BigNumber and FixedNumber', () => {
- const big = BigNumber('1000');
- const fixed = FixedNumber.from('1.2345');
- const product = mulBigAndFixed(big, fixed);
+describe('mulBigAndFixed', () => {
+ it('gets the floored product of a BigNumber and FixedNumber', () => {
+ const big = BigNumber('1000');
+ const fixed = FixedNumber.from('1.2345');
+ const product = mulBigAndFixed(big, fixed);
- expect(product).to.equal((1234).toString());
- });
+ expect(product).to.equal((1234).toString());
+ });
- it('gets the ceilinged product of a BigNumber and FixedNumber', () => {
- const big = BigNumber('1000');
- const fixed = FixedNumber.from('1.2345');
- const product = mulBigAndFixed(big, fixed, true);
+ it('gets the ceilinged product of a BigNumber and FixedNumber', () => {
+ const big = BigNumber('1000');
+ const fixed = FixedNumber.from('1.2345');
+ const product = mulBigAndFixed(big, fixed, true);
- expect(product).to.equal((1235).toString());
- });
+ expect(product).to.equal((1235).toString());
});
+});
- describe('BigNumberMin', () => {
- it('gets the min between the two BigNumber', () => {
- const big = BigNumber('1000');
- const bigger = BigNumber('10000');
- expect(BigNumberMin(big, bigger)).to.equal(big.toString());
- });
+describe('BigNumberMin', () => {
+ it('gets the min between the two BigNumber', () => {
+ const big = BigNumber('1000');
+ const bigger = BigNumber('10000');
+ expect(BigNumberMin(big, bigger)).to.equal(big.toString());
});
+});
- describe('BigNumberMax', () => {
- it('gets the max between the two BigNumber', () => {
- const big = BigNumber('1000');
- const bigger = BigNumber('10000');
- expect(BigNumberMax(big, bigger)).to.equal(bigger.toString());
- });
+describe('BigNumberMax', () => {
+ it('gets the max between the two BigNumber', () => {
+ const big = BigNumber('1000');
+ const bigger = BigNumber('10000');
+ expect(BigNumberMax(big, bigger)).to.equal(bigger.toString());
});
});