essential-eth 1.0.0 → 1.1.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/dist/{chunk-CLIQ4S3P.js → chunk-4V2QY6OK.js} +1 -1
- package/dist/index.cjs +78 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.js +79 -3
- package/dist/utils.js +1 -1
- package/package.json +1 -1
- package/readme.md +4 -4
package/dist/index.cjs
CHANGED
|
@@ -522,7 +522,7 @@ function buildRPCPostBody(method, params) {
|
|
|
522
522
|
}
|
|
523
523
|
|
|
524
524
|
// src/logger/package-version.ts
|
|
525
|
-
var version = "1.
|
|
525
|
+
var version = "1.1.0";
|
|
526
526
|
|
|
527
527
|
// src/logger/logger.ts
|
|
528
528
|
var Logger = class {
|
|
@@ -1486,6 +1486,82 @@ var BaseProvider = class {
|
|
|
1486
1486
|
}
|
|
1487
1487
|
return toChecksumAddress(rawAddress);
|
|
1488
1488
|
}
|
|
1489
|
+
/**
|
|
1490
|
+
* Performs reverse ENS resolution to get the ENS name associated with an address.
|
|
1491
|
+
*
|
|
1492
|
+
* Performs the full ENS reverse resolution process:
|
|
1493
|
+
* 1. Formats the address as a reverse lookup: `{address}.addr.reverse`
|
|
1494
|
+
* 2. Computes the namehash of the reverse name
|
|
1495
|
+
* 3. Queries the ENS Registry for the resolver contract
|
|
1496
|
+
* 4. Queries the resolver for the name
|
|
1497
|
+
* 5. Verifies the name resolves back to the original address (per ENSIP-3)
|
|
1498
|
+
*
|
|
1499
|
+
* * [Identical](/docs/api#isd) to [`viem.getEnsName`](https://viem.sh/docs/ens/actions/getEnsName) in viem
|
|
1500
|
+
* @param address the Ethereum address to look up (e.g. '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045')
|
|
1501
|
+
* @returns the ENS name the address resolves to, or null if not found or verification fails
|
|
1502
|
+
* @example
|
|
1503
|
+
* ```javascript
|
|
1504
|
+
* await provider.lookupAddress('0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045');
|
|
1505
|
+
* // 'vitalik.eth'
|
|
1506
|
+
* ```
|
|
1507
|
+
* @example
|
|
1508
|
+
* ```javascript
|
|
1509
|
+
* await provider.lookupAddress('0x0000000000000000000000000000000000000000');
|
|
1510
|
+
* // null
|
|
1511
|
+
* ```
|
|
1512
|
+
*/
|
|
1513
|
+
async lookupAddress(address) {
|
|
1514
|
+
const ENS_REGISTRY = "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e";
|
|
1515
|
+
const RESOLVER_SELECTOR = "0x0178b8bf";
|
|
1516
|
+
const NAME_SELECTOR = "0x691f3431";
|
|
1517
|
+
const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000000000000000000000000000";
|
|
1518
|
+
const addressLower = address.toLowerCase();
|
|
1519
|
+
const addressWithoutPrefix = addressLower.startsWith("0x") ? addressLower.slice(2) : addressLower;
|
|
1520
|
+
const reverseName = `${addressWithoutPrefix}.addr.reverse`;
|
|
1521
|
+
const node = namehash(reverseName);
|
|
1522
|
+
const nodeWithoutPrefix = node.slice(2);
|
|
1523
|
+
const resolverData = RESOLVER_SELECTOR + nodeWithoutPrefix;
|
|
1524
|
+
const resolverResult = await this.call({
|
|
1525
|
+
to: ENS_REGISTRY,
|
|
1526
|
+
data: resolverData
|
|
1527
|
+
});
|
|
1528
|
+
if (!resolverResult || resolverResult === ZERO_ADDRESS) {
|
|
1529
|
+
return null;
|
|
1530
|
+
}
|
|
1531
|
+
const resolverAddress = "0x" + resolverResult.slice(26);
|
|
1532
|
+
if (resolverAddress === "0x0000000000000000000000000000000000000000" || resolverAddress === "0x" + "0".repeat(resolverResult.length - 2)) {
|
|
1533
|
+
return null;
|
|
1534
|
+
}
|
|
1535
|
+
const nameData = NAME_SELECTOR + nodeWithoutPrefix;
|
|
1536
|
+
const nameResult = await this.call({
|
|
1537
|
+
to: resolverAddress,
|
|
1538
|
+
data: nameData
|
|
1539
|
+
});
|
|
1540
|
+
if (!nameResult || nameResult === ZERO_ADDRESS) {
|
|
1541
|
+
return null;
|
|
1542
|
+
}
|
|
1543
|
+
const lengthHex = nameResult.slice(2 + 64, 2 + 128);
|
|
1544
|
+
const length = parseInt(lengthHex, 16);
|
|
1545
|
+
if (length === 0) {
|
|
1546
|
+
return null;
|
|
1547
|
+
}
|
|
1548
|
+
const dataHex = nameResult.slice(2 + 128);
|
|
1549
|
+
const name = dataHex.slice(0, length * 2).match(/.{1,2}/g)?.map((byte) => String.fromCharCode(parseInt(byte, 16))).join("");
|
|
1550
|
+
if (!name) {
|
|
1551
|
+
return null;
|
|
1552
|
+
}
|
|
1553
|
+
try {
|
|
1554
|
+
const verifyAddress = await this.resolveName(name);
|
|
1555
|
+
const normalizedAddress = addressLower.startsWith("0x") ? addressLower : "0x" + addressLower;
|
|
1556
|
+
const normalizedVerifyAddress = verifyAddress?.toLowerCase();
|
|
1557
|
+
if (normalizedVerifyAddress !== normalizedAddress) {
|
|
1558
|
+
return null;
|
|
1559
|
+
}
|
|
1560
|
+
} catch {
|
|
1561
|
+
return null;
|
|
1562
|
+
}
|
|
1563
|
+
return name;
|
|
1564
|
+
}
|
|
1489
1565
|
};
|
|
1490
1566
|
|
|
1491
1567
|
// src/providers/JsonRpcProvider.ts
|
|
@@ -1520,7 +1596,7 @@ function jsonRpcProvider(rpcUrl) {
|
|
|
1520
1596
|
// src/providers/AlchemyProvider.ts
|
|
1521
1597
|
var AlchemyProvider = class extends JsonRpcProvider {
|
|
1522
1598
|
constructor(apiKey, network = "mainnet") {
|
|
1523
|
-
const alchemyUrl = `https://eth-${network}.
|
|
1599
|
+
const alchemyUrl = `https://eth-${network}.g.alchemy.com/v2/${apiKey}`;
|
|
1524
1600
|
super(alchemyUrl);
|
|
1525
1601
|
}
|
|
1526
1602
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -195,6 +195,7 @@ declare abstract class BaseProvider {
|
|
|
195
195
|
getLogs(filter: Filter | FilterByBlockHash): Promise<Array<Log>>;
|
|
196
196
|
call(transaction: TransactionRequest, blockTag?: BlockTag): Promise<string>;
|
|
197
197
|
resolveName(name: string): Promise<string | null>;
|
|
198
|
+
lookupAddress(address: string): Promise<string | null>;
|
|
198
199
|
}
|
|
199
200
|
|
|
200
201
|
declare class JsonRpcProvider extends BaseProvider {
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { keccak256, toUtf8Bytes, logger, encodeData, decodeRPCResponse, arrayify, hexlify, toChecksumAddress, hexToDecimal } from './chunk-
|
|
2
|
-
export { arrayify, computeAddress, computePublicKey, concat, hashMessage, hexConcat, hexDataLength, hexDataSlice, hexStripZeros, hexValue, hexZeroPad, hexlify, isAddress, isBytes, isBytesLike, isHexString, keccak256, pack, solidityKeccak256, splitSignature, stripZeros, toChecksumAddress, toUtf8Bytes, zeroPad } from './chunk-
|
|
1
|
+
import { keccak256, toUtf8Bytes, logger, encodeData, decodeRPCResponse, arrayify, hexlify, toChecksumAddress, hexToDecimal } from './chunk-4V2QY6OK.js';
|
|
2
|
+
export { arrayify, computeAddress, computePublicKey, concat, hashMessage, hexConcat, hexDataLength, hexDataSlice, hexStripZeros, hexValue, hexZeroPad, hexlify, isAddress, isBytes, isBytesLike, isHexString, keccak256, pack, solidityKeccak256, splitSignature, stripZeros, toChecksumAddress, toUtf8Bytes, zeroPad } from './chunk-4V2QY6OK.js';
|
|
3
3
|
import { formatFixed, toBigInt, parseFixed } from './chunk-GFWRB7PT.js';
|
|
4
4
|
export { etherToGwei, etherToWei, gweiToEther, weiToEther } from './chunk-GFWRB7PT.js';
|
|
5
5
|
import unfetch from 'isomorphic-unfetch';
|
|
@@ -896,6 +896,82 @@ var BaseProvider = class {
|
|
|
896
896
|
}
|
|
897
897
|
return toChecksumAddress(rawAddress);
|
|
898
898
|
}
|
|
899
|
+
/**
|
|
900
|
+
* Performs reverse ENS resolution to get the ENS name associated with an address.
|
|
901
|
+
*
|
|
902
|
+
* Performs the full ENS reverse resolution process:
|
|
903
|
+
* 1. Formats the address as a reverse lookup: `{address}.addr.reverse`
|
|
904
|
+
* 2. Computes the namehash of the reverse name
|
|
905
|
+
* 3. Queries the ENS Registry for the resolver contract
|
|
906
|
+
* 4. Queries the resolver for the name
|
|
907
|
+
* 5. Verifies the name resolves back to the original address (per ENSIP-3)
|
|
908
|
+
*
|
|
909
|
+
* * [Identical](/docs/api#isd) to [`viem.getEnsName`](https://viem.sh/docs/ens/actions/getEnsName) in viem
|
|
910
|
+
* @param address the Ethereum address to look up (e.g. '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045')
|
|
911
|
+
* @returns the ENS name the address resolves to, or null if not found or verification fails
|
|
912
|
+
* @example
|
|
913
|
+
* ```javascript
|
|
914
|
+
* await provider.lookupAddress('0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045');
|
|
915
|
+
* // 'vitalik.eth'
|
|
916
|
+
* ```
|
|
917
|
+
* @example
|
|
918
|
+
* ```javascript
|
|
919
|
+
* await provider.lookupAddress('0x0000000000000000000000000000000000000000');
|
|
920
|
+
* // null
|
|
921
|
+
* ```
|
|
922
|
+
*/
|
|
923
|
+
async lookupAddress(address) {
|
|
924
|
+
const ENS_REGISTRY = "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e";
|
|
925
|
+
const RESOLVER_SELECTOR = "0x0178b8bf";
|
|
926
|
+
const NAME_SELECTOR = "0x691f3431";
|
|
927
|
+
const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000000000000000000000000000";
|
|
928
|
+
const addressLower = address.toLowerCase();
|
|
929
|
+
const addressWithoutPrefix = addressLower.startsWith("0x") ? addressLower.slice(2) : addressLower;
|
|
930
|
+
const reverseName = `${addressWithoutPrefix}.addr.reverse`;
|
|
931
|
+
const node = namehash(reverseName);
|
|
932
|
+
const nodeWithoutPrefix = node.slice(2);
|
|
933
|
+
const resolverData = RESOLVER_SELECTOR + nodeWithoutPrefix;
|
|
934
|
+
const resolverResult = await this.call({
|
|
935
|
+
to: ENS_REGISTRY,
|
|
936
|
+
data: resolverData
|
|
937
|
+
});
|
|
938
|
+
if (!resolverResult || resolverResult === ZERO_ADDRESS) {
|
|
939
|
+
return null;
|
|
940
|
+
}
|
|
941
|
+
const resolverAddress = "0x" + resolverResult.slice(26);
|
|
942
|
+
if (resolverAddress === "0x0000000000000000000000000000000000000000" || resolverAddress === "0x" + "0".repeat(resolverResult.length - 2)) {
|
|
943
|
+
return null;
|
|
944
|
+
}
|
|
945
|
+
const nameData = NAME_SELECTOR + nodeWithoutPrefix;
|
|
946
|
+
const nameResult = await this.call({
|
|
947
|
+
to: resolverAddress,
|
|
948
|
+
data: nameData
|
|
949
|
+
});
|
|
950
|
+
if (!nameResult || nameResult === ZERO_ADDRESS) {
|
|
951
|
+
return null;
|
|
952
|
+
}
|
|
953
|
+
const lengthHex = nameResult.slice(2 + 64, 2 + 128);
|
|
954
|
+
const length = parseInt(lengthHex, 16);
|
|
955
|
+
if (length === 0) {
|
|
956
|
+
return null;
|
|
957
|
+
}
|
|
958
|
+
const dataHex = nameResult.slice(2 + 128);
|
|
959
|
+
const name = dataHex.slice(0, length * 2).match(/.{1,2}/g)?.map((byte) => String.fromCharCode(parseInt(byte, 16))).join("");
|
|
960
|
+
if (!name) {
|
|
961
|
+
return null;
|
|
962
|
+
}
|
|
963
|
+
try {
|
|
964
|
+
const verifyAddress = await this.resolveName(name);
|
|
965
|
+
const normalizedAddress = addressLower.startsWith("0x") ? addressLower : "0x" + addressLower;
|
|
966
|
+
const normalizedVerifyAddress = verifyAddress?.toLowerCase();
|
|
967
|
+
if (normalizedVerifyAddress !== normalizedAddress) {
|
|
968
|
+
return null;
|
|
969
|
+
}
|
|
970
|
+
} catch {
|
|
971
|
+
return null;
|
|
972
|
+
}
|
|
973
|
+
return name;
|
|
974
|
+
}
|
|
899
975
|
};
|
|
900
976
|
|
|
901
977
|
// src/providers/JsonRpcProvider.ts
|
|
@@ -930,7 +1006,7 @@ function jsonRpcProvider(rpcUrl) {
|
|
|
930
1006
|
// src/providers/AlchemyProvider.ts
|
|
931
1007
|
var AlchemyProvider = class extends JsonRpcProvider {
|
|
932
1008
|
constructor(apiKey, network = "mainnet") {
|
|
933
|
-
const alchemyUrl = `https://eth-${network}.
|
|
1009
|
+
const alchemyUrl = `https://eth-${network}.g.alchemy.com/v2/${apiKey}`;
|
|
934
1010
|
super(alchemyUrl);
|
|
935
1011
|
}
|
|
936
1012
|
};
|
package/dist/utils.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { arrayify, computeAddress, computePublicKey, concat, hashMessage, hexConcat, hexDataLength, hexDataSlice, hexStripZeros, hexValue, hexZeroPad, hexlify, isAddress, isBytes, isBytesLike, isHexString, keccak256, pack, solidityKeccak256, splitSignature, stripZeros, toChecksumAddress, toUtf8Bytes, zeroPad } from './chunk-
|
|
1
|
+
export { arrayify, computeAddress, computePublicKey, concat, hashMessage, hexConcat, hexDataLength, hexDataSlice, hexStripZeros, hexValue, hexZeroPad, hexlify, isAddress, isBytes, isBytesLike, isHexString, keccak256, pack, solidityKeccak256, splitSignature, stripZeros, toChecksumAddress, toUtf8Bytes, zeroPad } from './chunk-4V2QY6OK.js';
|
|
2
2
|
export { etherToGwei, etherToWei, gweiToEther, weiToEther } from './chunk-GFWRB7PT.js';
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -27,10 +27,10 @@
|
|
|
27
27
|
|
|
28
28
|
Measured with esbuild. Smaller is better.
|
|
29
29
|
|
|
30
|
-
| What you import | essential-eth@1.
|
|
30
|
+
| What you import | essential-eth@1.1.0 | ethers@6.16.0 | viem@2.45.1 | web3@4.16.0 | ox@0.12.0 |
|
|
31
31
|
| ---------------------------------------- | :-----------------: | :-----------: | :---------: | :---------: | :------------: |
|
|
32
|
-
| **Full library** | **
|
|
33
|
-
| **Provider** (getBalance, getBlock, etc) |
|
|
32
|
+
| **Full library** | **43.1 kB** 🏆 | 394.0 kB | 348.3 kB | 495.8 kB | 612.8 kB |
|
|
33
|
+
| **Provider** (getBalance, getBlock, etc) | 30.8 kB | 260.0 kB | 269.5 kB | 454.5 kB | **10.9 kB** 🏆 |
|
|
34
34
|
| **Contract** (read-only calls) | **24.8 kB** 🏆 | 86.6 kB | 179.8 kB | 264.9 kB | 49.9 kB |
|
|
35
35
|
| **Conversions** (wei, gwei, ether) | **1.2 kB** 🏆 | 10.4 kB | 2.7 kB | 454.5 kB | 3.7 kB |
|
|
36
36
|
|
|
@@ -174,7 +174,7 @@ Browsers:
|
|
|
174
174
|
```html
|
|
175
175
|
|
|
176
176
|
<!-- index.html -->
|
|
177
|
-
<script src="https://unpkg.com/essential-eth@1.
|
|
177
|
+
<script src="https://unpkg.com/essential-eth@1.1.0"></script>
|
|
178
178
|
```
|
|
179
179
|
|
|
180
180
|
|