@waku/rln 0.1.3 → 0.1.4-2a94244.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/README.md +10 -186
- package/bundle/_virtual/__node-resolve_empty.js +6 -0
- package/bundle/_virtual/_assert.js +3 -0
- package/bundle/_virtual/_commonjs-dynamic-modules.js +5 -0
- package/bundle/_virtual/_commonjsHelpers.js +32 -0
- package/bundle/_virtual/_node-resolve_empty.js +3 -0
- package/bundle/_virtual/_sha2.js +3 -0
- package/bundle/_virtual/_u64.js +3 -0
- package/bundle/_virtual/aes.js +3 -0
- package/bundle/_virtual/bn.js +3 -0
- package/bundle/_virtual/browser.js +3 -0
- package/bundle/_virtual/checksum.js +3 -0
- package/bundle/_virtual/cipher.js +3 -0
- package/bundle/_virtual/class.js +3 -0
- package/bundle/_virtual/common.js +3 -0
- package/bundle/_virtual/common2.js +3 -0
- package/bundle/_virtual/cryptoBrowser.js +3 -0
- package/bundle/_virtual/functional.js +3 -0
- package/bundle/_virtual/hash.js +3 -0
- package/bundle/_virtual/hmac.js +3 -0
- package/bundle/_virtual/index.js +3 -0
- package/bundle/_virtual/index2.js +6 -0
- package/bundle/_virtual/inherits_browser.js +3 -0
- package/bundle/_virtual/kdf.js +3 -0
- package/bundle/_virtual/lodash.js +3 -0
- package/bundle/_virtual/password.js +3 -0
- package/bundle/_virtual/pbkdf2.js +3 -0
- package/bundle/_virtual/pbkdf22.js +3 -0
- package/bundle/_virtual/random.js +3 -0
- package/bundle/_virtual/ripemd.js +3 -0
- package/bundle/_virtual/schema-validation-generated.js +3 -0
- package/bundle/_virtual/schema-validation.js +3 -0
- package/bundle/_virtual/scrypt.js +3 -0
- package/bundle/_virtual/scrypt2.js +3 -0
- package/bundle/_virtual/sha.js +3 -0
- package/bundle/_virtual/sha256.js +3 -0
- package/bundle/_virtual/sha2562.js +3 -0
- package/bundle/_virtual/sha3.js +3 -0
- package/bundle/_virtual/sha512.js +3 -0
- package/bundle/_virtual/types.js +3 -0
- package/bundle/_virtual/utils.js +3 -0
- package/bundle/_virtual/utils2.js +3 -0
- package/bundle/_virtual/utils3.js +3 -0
- package/bundle/index.js +12 -74804
- package/bundle/node_modules/@ethersproject/abi/lib.esm/_version.js +3 -0
- package/bundle/node_modules/@ethersproject/abi/lib.esm/abi-coder.js +96 -0
- package/bundle/node_modules/@ethersproject/abi/lib.esm/coders/abstract-coder.js +148 -0
- package/bundle/node_modules/@ethersproject/abi/lib.esm/coders/address.js +26 -0
- package/bundle/node_modules/@ethersproject/abi/lib.esm/coders/anonymous.js +20 -0
- package/bundle/node_modules/@ethersproject/abi/lib.esm/coders/array.js +210 -0
- package/bundle/node_modules/@ethersproject/abi/lib.esm/coders/boolean.js +18 -0
- package/bundle/node_modules/@ethersproject/abi/lib.esm/coders/bytes.js +30 -0
- package/bundle/node_modules/@ethersproject/abi/lib.esm/coders/fixed-bytes.js +26 -0
- package/bundle/node_modules/@ethersproject/abi/lib.esm/coders/null.js +22 -0
- package/bundle/node_modules/@ethersproject/abi/lib.esm/coders/number.js +43 -0
- package/bundle/node_modules/@ethersproject/abi/lib.esm/coders/string.js +19 -0
- package/bundle/node_modules/@ethersproject/abi/lib.esm/coders/tuple.js +58 -0
- package/bundle/node_modules/@ethersproject/abi/lib.esm/fragments.js +854 -0
- package/bundle/node_modules/@ethersproject/abi/lib.esm/interface.js +609 -0
- package/bundle/node_modules/@ethersproject/abstract-provider/lib.esm/_version.js +3 -0
- package/bundle/node_modules/@ethersproject/abstract-provider/lib.esm/index.js +66 -0
- package/bundle/node_modules/@ethersproject/abstract-signer/lib.esm/_version.js +3 -0
- package/bundle/node_modules/@ethersproject/abstract-signer/lib.esm/index.js +302 -0
- package/bundle/node_modules/@ethersproject/address/lib.esm/_version.js +3 -0
- package/bundle/node_modules/@ethersproject/address/lib.esm/index.js +110 -0
- package/bundle/node_modules/@ethersproject/base64/lib.esm/base64.js +20 -0
- package/bundle/node_modules/@ethersproject/basex/lib.esm/index.js +120 -0
- package/bundle/node_modules/@ethersproject/bignumber/lib.esm/_version.js +3 -0
- package/bundle/node_modules/@ethersproject/bignumber/lib.esm/bignumber.js +287 -0
- package/bundle/node_modules/@ethersproject/bytes/lib.esm/_version.js +3 -0
- package/bundle/node_modules/@ethersproject/bytes/lib.esm/index.js +402 -0
- package/bundle/node_modules/@ethersproject/constants/lib.esm/addresses.js +3 -0
- package/bundle/node_modules/@ethersproject/constants/lib.esm/bignumbers.js +8 -0
- package/bundle/node_modules/@ethersproject/constants/lib.esm/hashes.js +3 -0
- package/bundle/node_modules/@ethersproject/contracts/lib.esm/_version.js +3 -0
- package/bundle/node_modules/@ethersproject/contracts/lib.esm/index.js +893 -0
- package/bundle/node_modules/@ethersproject/hash/lib.esm/_version.js +3 -0
- package/bundle/node_modules/@ethersproject/hash/lib.esm/ens-normalize/decoder.js +256 -0
- package/bundle/node_modules/@ethersproject/hash/lib.esm/ens-normalize/include.js +36 -0
- package/bundle/node_modules/@ethersproject/hash/lib.esm/ens-normalize/lib.js +135 -0
- package/bundle/node_modules/@ethersproject/hash/lib.esm/id.js +8 -0
- package/bundle/node_modules/@ethersproject/hash/lib.esm/namehash.js +64 -0
- package/bundle/node_modules/@ethersproject/hash/lib.esm/typed-data.js +443 -0
- package/bundle/node_modules/@ethersproject/keccak256/lib.esm/index.js +8 -0
- package/bundle/node_modules/@ethersproject/keccak256/node_modules/js-sha3/src/sha3.js +660 -0
- package/bundle/node_modules/@ethersproject/logger/lib.esm/_version.js +3 -0
- package/bundle/node_modules/@ethersproject/logger/lib.esm/index.js +352 -0
- package/bundle/node_modules/@ethersproject/networks/lib.esm/_version.js +3 -0
- package/bundle/node_modules/@ethersproject/networks/lib.esm/index.js +248 -0
- package/bundle/node_modules/@ethersproject/properties/lib.esm/_version.js +3 -0
- package/bundle/node_modules/@ethersproject/properties/lib.esm/index.js +127 -0
- package/bundle/node_modules/@ethersproject/providers/lib.esm/_version.js +3 -0
- package/bundle/node_modules/@ethersproject/providers/lib.esm/base-provider.js +2007 -0
- package/bundle/node_modules/@ethersproject/providers/lib.esm/formatter.js +422 -0
- package/bundle/node_modules/@ethersproject/providers/lib.esm/json-rpc-provider.js +674 -0
- package/bundle/node_modules/@ethersproject/providers/lib.esm/web3-provider.js +132 -0
- package/bundle/node_modules/@ethersproject/rlp/lib.esm/_version.js +3 -0
- package/bundle/node_modules/@ethersproject/rlp/lib.esm/index.js +120 -0
- package/bundle/node_modules/@ethersproject/sha2/lib.esm/sha2.js +8 -0
- package/bundle/node_modules/@ethersproject/signing-key/lib.esm/_version.js +3 -0
- package/bundle/node_modules/@ethersproject/signing-key/lib.esm/elliptic.js +2430 -0
- package/bundle/node_modules/@ethersproject/signing-key/lib.esm/index.js +76 -0
- package/bundle/node_modules/@ethersproject/strings/lib.esm/_version.js +3 -0
- package/bundle/node_modules/@ethersproject/strings/lib.esm/utf8.js +219 -0
- package/bundle/node_modules/@ethersproject/transactions/lib.esm/_version.js +3 -0
- package/bundle/node_modules/@ethersproject/transactions/lib.esm/index.js +279 -0
- package/bundle/node_modules/@ethersproject/web/lib.esm/_version.js +3 -0
- package/bundle/node_modules/@ethersproject/web/lib.esm/geturl.js +69 -0
- package/bundle/node_modules/@ethersproject/web/lib.esm/index.js +404 -0
- package/bundle/node_modules/@multiformats/multiaddr/dist/src/convert.js +15 -0
- package/bundle/node_modules/@multiformats/multiaddr/dist/src/multiaddr.js +20 -0
- package/bundle/node_modules/@multiformats/multiaddr/dist/src/protocols-table.js +92 -0
- package/bundle/node_modules/@noble/hashes/esm/_assert.js +37 -0
- package/bundle/node_modules/@noble/hashes/esm/_md.js +132 -0
- package/bundle/node_modules/@noble/hashes/esm/_u64.js +29 -0
- package/bundle/node_modules/@noble/hashes/esm/sha256.js +113 -0
- package/bundle/node_modules/@noble/hashes/esm/sha3.js +210 -0
- package/bundle/node_modules/@noble/hashes/esm/utils.js +144 -0
- package/bundle/node_modules/@waku/zerokit-rln-wasm/rln_wasm.js +756 -0
- package/bundle/node_modules/bech32/index.js +187 -0
- package/bundle/node_modules/bn.js/lib/bn.js +3361 -0
- package/bundle/node_modules/debug/src/browser.js +283 -0
- package/bundle/node_modules/debug/src/common.js +295 -0
- package/bundle/node_modules/ethereum-cryptography/esm/keccak.js +10 -0
- package/bundle/node_modules/ethereum-cryptography/esm/sha256.js +6 -0
- package/bundle/node_modules/ethereum-cryptography/esm/utils.js +24 -0
- package/bundle/node_modules/hash.js/lib/hash/common.js +97 -0
- package/bundle/node_modules/hash.js/lib/hash/hmac.js +51 -0
- package/bundle/node_modules/hash.js/lib/hash/ripemd.js +152 -0
- package/bundle/node_modules/hash.js/lib/hash/sha/1.js +81 -0
- package/bundle/node_modules/hash.js/lib/hash/sha/224.js +33 -0
- package/bundle/node_modules/hash.js/lib/hash/sha/256.js +113 -0
- package/bundle/node_modules/hash.js/lib/hash/sha/384.js +39 -0
- package/bundle/node_modules/hash.js/lib/hash/sha/512.js +336 -0
- package/bundle/node_modules/hash.js/lib/hash/sha/common.js +53 -0
- package/bundle/node_modules/hash.js/lib/hash/sha.js +14 -0
- package/bundle/node_modules/hash.js/lib/hash/utils.js +282 -0
- package/bundle/node_modules/hash.js/lib/hash.js +33 -0
- package/bundle/node_modules/inherits/inherits_browser.js +33 -0
- package/bundle/node_modules/it-length-prefixed/dist/src/decode.js +6 -0
- package/bundle/node_modules/lodash/lodash.js +17207 -0
- package/bundle/node_modules/minimalistic-assert/index.js +13 -0
- package/bundle/node_modules/ms/index.js +172 -0
- package/bundle/node_modules/multiformats/dist/src/bases/base.js +205 -0
- package/bundle/node_modules/multiformats/dist/src/bases/base10.js +9 -0
- package/bundle/node_modules/multiformats/dist/src/bases/base16.js +16 -0
- package/bundle/node_modules/multiformats/dist/src/bases/base2.js +10 -0
- package/bundle/node_modules/multiformats/dist/src/bases/base256emoji.js +41 -0
- package/bundle/node_modules/multiformats/dist/src/bases/base32.js +58 -0
- package/bundle/node_modules/multiformats/dist/src/bases/base36.js +14 -0
- package/bundle/node_modules/multiformats/dist/src/bases/base58.js +14 -0
- package/bundle/node_modules/multiformats/dist/src/bases/base64.js +28 -0
- package/bundle/node_modules/multiformats/dist/src/bases/base8.js +10 -0
- package/bundle/node_modules/multiformats/dist/src/bases/identity.js +11 -0
- package/bundle/node_modules/multiformats/dist/src/basics.js +15 -0
- package/bundle/node_modules/multiformats/dist/src/bytes.js +18 -0
- package/bundle/node_modules/multiformats/dist/src/codecs/json.js +2 -0
- package/bundle/node_modules/multiformats/dist/src/vendor/base-x.js +170 -0
- package/bundle/node_modules/protons-runtime/dist/src/codec.js +20 -0
- package/bundle/node_modules/protons-runtime/dist/src/codecs/enum.js +24 -0
- package/bundle/node_modules/protons-runtime/dist/src/codecs/message.js +7 -0
- package/bundle/node_modules/protons-runtime/dist/src/decode.js +8 -0
- package/bundle/node_modules/protons-runtime/dist/src/encode.js +11 -0
- package/bundle/node_modules/protons-runtime/dist/src/index.js +30 -0
- package/bundle/node_modules/protons-runtime/dist/src/utils/float.js +54 -0
- package/bundle/node_modules/protons-runtime/dist/src/utils/longbits.js +175 -0
- package/bundle/node_modules/protons-runtime/dist/src/utils/pool.js +28 -0
- package/bundle/node_modules/protons-runtime/dist/src/utils/reader.js +367 -0
- package/bundle/node_modules/protons-runtime/dist/src/utils/utf8.js +99 -0
- package/bundle/node_modules/protons-runtime/dist/src/utils/writer.js +438 -0
- package/bundle/node_modules/uint8-varint/dist/src/index.js +124 -0
- package/bundle/node_modules/uint8arrays/dist/src/alloc.js +17 -0
- package/bundle/node_modules/uint8arrays/dist/src/from-string.js +19 -0
- package/bundle/node_modules/uint8arrays/dist/src/util/bases.js +49 -0
- package/bundle/packages/core/dist/lib/connection_manager/connection_manager.js +21 -0
- package/bundle/packages/core/dist/lib/connection_manager/keep_alive_manager.js +18 -0
- package/bundle/packages/core/dist/lib/filter/filter.js +27 -0
- package/bundle/packages/core/dist/lib/light_push/light_push.js +27 -0
- package/bundle/packages/core/dist/lib/message/version_0.js +154 -0
- package/bundle/packages/core/dist/lib/metadata/metadata.js +27 -0
- package/bundle/packages/core/dist/lib/store/store.js +27 -0
- package/bundle/packages/interfaces/dist/connection_manager.js +19 -0
- package/bundle/packages/interfaces/dist/constants.js +6 -0
- package/bundle/packages/interfaces/dist/health_indicator.js +12 -0
- package/bundle/packages/interfaces/dist/protocols.js +92 -0
- package/bundle/packages/proto/dist/generated/filter.js +445 -0
- package/bundle/packages/proto/dist/generated/filter_v2.js +424 -0
- package/bundle/packages/proto/dist/generated/light_push.js +389 -0
- package/bundle/packages/proto/dist/generated/message.js +213 -0
- package/bundle/packages/proto/dist/generated/metadata.js +130 -0
- package/bundle/packages/proto/dist/generated/peer_exchange.js +209 -0
- package/bundle/packages/proto/dist/generated/sds_message.js +105 -0
- package/bundle/packages/proto/dist/generated/store_v3.js +490 -0
- package/bundle/packages/proto/dist/generated/topic_only_message.js +61 -0
- package/bundle/packages/rln/dist/codec.js +93 -0
- package/bundle/packages/rln/dist/contract/abi.js +394 -0
- package/bundle/packages/rln/dist/contract/constants.js +27 -0
- package/bundle/packages/rln/dist/contract/rln_contract.js +438 -0
- package/bundle/packages/rln/dist/create.js +9 -0
- package/bundle/packages/rln/dist/identity.js +30 -0
- package/bundle/packages/rln/dist/keystore/cipher.js +31 -0
- package/bundle/packages/rln/dist/keystore/credential_validation_generated.js +119 -0
- package/bundle/packages/rln/dist/keystore/keystore.js +223 -0
- package/bundle/packages/rln/dist/keystore/keystore_validation_generated.js +74 -0
- package/bundle/packages/rln/dist/keystore/schema_validator.js +20 -0
- package/bundle/packages/rln/dist/message.js +51 -0
- package/bundle/packages/rln/dist/proof.js +54 -0
- package/bundle/packages/rln/dist/resources/verification_key.js +112 -0
- package/bundle/packages/rln/dist/resources/witness_calculator.js +330 -0
- package/bundle/packages/rln/dist/rln.js +220 -0
- package/bundle/packages/rln/dist/root_tracker.js +76 -0
- package/bundle/packages/rln/dist/utils/bytes.js +65 -0
- package/bundle/packages/rln/dist/utils/epoch.js +39 -0
- package/bundle/packages/rln/dist/utils/hash.js +10 -0
- package/bundle/packages/rln/dist/utils/metamask.js +14 -0
- package/bundle/packages/rln/dist/zerokit.js +128 -0
- package/bundle/packages/rln/node_modules/@chainsafe/bls-keystore/lib/checksum.js +52 -0
- package/bundle/packages/rln/node_modules/@chainsafe/bls-keystore/lib/cipher.js +65 -0
- package/bundle/packages/rln/node_modules/@chainsafe/bls-keystore/lib/class.js +99 -0
- package/bundle/packages/rln/node_modules/@chainsafe/bls-keystore/lib/functional.js +103 -0
- package/bundle/packages/rln/node_modules/@chainsafe/bls-keystore/lib/index.js +28 -0
- package/bundle/packages/rln/node_modules/@chainsafe/bls-keystore/lib/kdf.js +78 -0
- package/bundle/packages/rln/node_modules/@chainsafe/bls-keystore/lib/password.js +17 -0
- package/bundle/packages/rln/node_modules/@chainsafe/bls-keystore/lib/schema-validation-generated.js +1253 -0
- package/bundle/packages/rln/node_modules/@chainsafe/bls-keystore/lib/schema-validation.js +40 -0
- package/bundle/packages/rln/node_modules/@chainsafe/bls-keystore/lib/types.js +5 -0
- package/bundle/packages/rln/node_modules/@chainsafe/bls-keystore/node_modules/ethereum-cryptography/aes.js +103 -0
- package/bundle/packages/rln/node_modules/@chainsafe/bls-keystore/node_modules/ethereum-cryptography/pbkdf2.js +41 -0
- package/bundle/packages/rln/node_modules/@chainsafe/bls-keystore/node_modules/ethereum-cryptography/random.js +17 -0
- package/bundle/packages/rln/node_modules/@chainsafe/bls-keystore/node_modules/ethereum-cryptography/scrypt.js +23 -0
- package/bundle/packages/rln/node_modules/@chainsafe/bls-keystore/node_modules/ethereum-cryptography/sha256.js +12 -0
- package/bundle/packages/rln/node_modules/@chainsafe/bls-keystore/node_modules/ethereum-cryptography/utils.js +77 -0
- package/bundle/packages/rln/node_modules/@chainsafe/bls-keystore/node_modules/uuid/dist/esm-browser/index.js +9 -0
- package/bundle/packages/rln/node_modules/@chainsafe/bls-keystore/node_modules/uuid/dist/esm-browser/md5.js +215 -0
- package/bundle/packages/rln/node_modules/@chainsafe/bls-keystore/node_modules/uuid/dist/esm-browser/nil.js +3 -0
- package/bundle/packages/rln/node_modules/@chainsafe/bls-keystore/node_modules/uuid/dist/esm-browser/parse.js +35 -0
- package/bundle/packages/rln/node_modules/@chainsafe/bls-keystore/node_modules/uuid/dist/esm-browser/regex.js +3 -0
- package/bundle/packages/rln/node_modules/@chainsafe/bls-keystore/node_modules/uuid/dist/esm-browser/rng.js +21 -0
- package/bundle/packages/rln/node_modules/@chainsafe/bls-keystore/node_modules/uuid/dist/esm-browser/sha1.js +96 -0
- package/bundle/packages/rln/node_modules/@chainsafe/bls-keystore/node_modules/uuid/dist/esm-browser/stringify.js +31 -0
- package/bundle/packages/rln/node_modules/@chainsafe/bls-keystore/node_modules/uuid/dist/esm-browser/v1.js +96 -0
- package/bundle/packages/rln/node_modules/@chainsafe/bls-keystore/node_modules/uuid/dist/esm-browser/v3.js +6 -0
- package/bundle/packages/rln/node_modules/@chainsafe/bls-keystore/node_modules/uuid/dist/esm-browser/v35.js +66 -0
- package/bundle/packages/rln/node_modules/@chainsafe/bls-keystore/node_modules/uuid/dist/esm-browser/v4.js +24 -0
- package/bundle/packages/rln/node_modules/@chainsafe/bls-keystore/node_modules/uuid/dist/esm-browser/v5.js +6 -0
- package/bundle/packages/rln/node_modules/@chainsafe/bls-keystore/node_modules/uuid/dist/esm-browser/validate.js +7 -0
- package/bundle/packages/rln/node_modules/@chainsafe/bls-keystore/node_modules/uuid/dist/esm-browser/version.js +11 -0
- package/bundle/packages/rln/node_modules/@noble/hashes/_assert.js +52 -0
- package/bundle/packages/rln/node_modules/@noble/hashes/_sha2.js +124 -0
- package/bundle/packages/rln/node_modules/@noble/hashes/_u64.js +71 -0
- package/bundle/packages/rln/node_modules/@noble/hashes/cryptoBrowser.js +10 -0
- package/bundle/packages/rln/node_modules/@noble/hashes/hmac.js +88 -0
- package/bundle/packages/rln/node_modules/@noble/hashes/pbkdf2.js +99 -0
- package/bundle/packages/rln/node_modules/@noble/hashes/scrypt.js +233 -0
- package/bundle/packages/rln/node_modules/@noble/hashes/sha256.js +133 -0
- package/bundle/packages/rln/node_modules/@noble/hashes/sha512.js +243 -0
- package/bundle/packages/rln/node_modules/@noble/hashes/utils.js +167 -0
- package/bundle/packages/rln/node_modules/uuid/dist/esm-browser/native.js +4 -0
- package/bundle/packages/rln/node_modules/uuid/dist/esm-browser/rng.js +13 -0
- package/bundle/packages/rln/node_modules/uuid/dist/esm-browser/stringify.js +28 -0
- package/bundle/packages/rln/node_modules/uuid/dist/esm-browser/v4.js +19 -0
- package/bundle/packages/utils/dist/bytes/index.js +44 -0
- package/bundle/packages/utils/dist/common/sharding/index.js +91 -0
- package/bundle/packages/utils/dist/logger/index.js +31 -0
- package/bundle/resources/verification_key.d.ts +13 -0
- package/bundle/resources/verification_key.js +112 -0
- package/bundle/resources/witness_calculator.d.ts +11 -0
- package/bundle/resources/witness_calculator.js +328 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/codec.d.ts +5 -5
- package/dist/codec.js +6 -6
- package/dist/codec.js.map +1 -1
- package/dist/contract/abi.d.ts +42 -0
- package/dist/contract/abi.js +393 -0
- package/dist/contract/abi.js.map +1 -0
- package/dist/contract/constants.d.ts +59 -3
- package/dist/contract/constants.js +21 -63
- package/dist/contract/constants.js.map +1 -1
- package/dist/contract/rln_contract.d.ts +98 -17
- package/dist/contract/rln_contract.js +292 -71
- package/dist/contract/rln_contract.js.map +1 -1
- package/dist/identity.js +5 -2
- package/dist/identity.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/keystore/cipher.js +3 -3
- package/dist/keystore/cipher.js.map +1 -1
- package/dist/keystore/credential_validation_generated.js.map +1 -1
- package/dist/keystore/keystore.js +4 -4
- package/dist/keystore/keystore.js.map +1 -1
- package/dist/keystore/keystore_validation_generated.js.map +1 -1
- package/dist/message.js +3 -3
- package/dist/message.js.map +1 -1
- package/dist/proof.js +3 -2
- package/dist/proof.js.map +1 -1
- package/dist/resources/verification_key.d.ts +12 -11
- package/dist/resources/verification_key.js +103 -103
- package/dist/resources/witness_calculator.d.ts +10 -15
- package/dist/resources/witness_calculator.js +302 -265
- package/dist/rln.d.ts +5 -1
- package/dist/rln.js +56 -28
- package/dist/rln.js.map +1 -1
- package/dist/root_tracker.js.map +1 -1
- package/dist/utils/epoch.js +5 -5
- package/dist/utils/epoch.js.map +1 -1
- package/dist/zerokit.d.ts +13 -9
- package/dist/zerokit.js +40 -20
- package/dist/zerokit.js.map +1 -1
- package/package.json +1 -146
- package/src/codec.ts +26 -22
- package/src/contract/abi.ts +392 -0
- package/src/contract/constants.ts +28 -0
- package/src/contract/index.ts +2 -0
- package/src/contract/rln_contract.ts +686 -0
- package/src/identity.ts +8 -4
- package/src/index.ts +4 -9
- package/src/keystore/cipher.ts +54 -0
- package/src/keystore/credential_validation_generated.ts +7 -0
- package/src/keystore/index.ts +5 -0
- package/src/keystore/keystore.ts +330 -0
- package/src/keystore/keystore_validation_generated.ts +7 -0
- package/src/keystore/schema_validator.ts +34 -0
- package/src/keystore/types.ts +36 -0
- package/src/message.ts +10 -10
- package/src/proof.ts +13 -11
- package/src/resources/verification_key.d.ts +13 -0
- package/src/resources/witness_calculator.d.ts +11 -0
- package/src/rln.ts +76 -31
- package/src/root_tracker.ts +7 -6
- package/src/utils/bytes.ts +84 -0
- package/src/utils/epoch.ts +30 -0
- package/src/utils/hash.ts +15 -0
- package/src/utils/index.ts +9 -0
- package/src/utils/metamask.ts +17 -0
- package/src/zerokit.ts +95 -33
- package/bundle/assets/rln_wasm_bg-a503e304.wasm +0 -0
- package/dist/resources/verification_key.js.map +0 -1
- package/dist/resources/witness_calculator.js.map +0 -1
- /package/bundle/{assets/rln-6ded2896.wasm → resources/rln.wasm} +0 -0
- /package/bundle/{assets/rln_final-8b299152.zkey → resources/rln_final.zkey} +0 -0
@@ -0,0 +1,2007 @@
|
|
1
|
+
import { Provider, ForkEvent } from '../../abstract-provider/lib.esm/index.js';
|
2
|
+
import { Base58 } from '../../basex/lib.esm/index.js';
|
3
|
+
import { hexlify, hexValue, hexDataLength, hexDataSlice, hexConcat, isHexString, arrayify, concat, hexZeroPad } from '../../bytes/lib.esm/index.js';
|
4
|
+
import { namehash, dnsEncode } from '../../hash/lib.esm/namehash.js';
|
5
|
+
import { getNetwork } from '../../networks/lib.esm/index.js';
|
6
|
+
import { defineReadOnly, getStatic, resolveProperties } from '../../properties/lib.esm/index.js';
|
7
|
+
import { sha256 } from '../../sha2/lib.esm/sha2.js';
|
8
|
+
import { toUtf8String, toUtf8Bytes } from '../../strings/lib.esm/utf8.js';
|
9
|
+
import { poll, fetchJson } from '../../web/lib.esm/index.js';
|
10
|
+
import bech32 from '../../../bech32/index.js';
|
11
|
+
import { Logger } from '../../logger/lib.esm/index.js';
|
12
|
+
import { version } from './_version.js';
|
13
|
+
import { Formatter } from './formatter.js';
|
14
|
+
import { BigNumber } from '../../bignumber/lib.esm/bignumber.js';
|
15
|
+
import { HashZero } from '../../constants/lib.esm/hashes.js';
|
16
|
+
import { encode } from '../../base64/lib.esm/base64.js';
|
17
|
+
|
18
|
+
var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
|
19
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
20
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
21
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
22
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
23
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
24
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
25
|
+
});
|
26
|
+
};
|
27
|
+
const logger = new Logger(version);
|
28
|
+
const MAX_CCIP_REDIRECTS = 10;
|
29
|
+
//////////////////////////////
|
30
|
+
// Event Serializeing
|
31
|
+
function checkTopic(topic) {
|
32
|
+
if (topic == null) {
|
33
|
+
return "null";
|
34
|
+
}
|
35
|
+
if (hexDataLength(topic) !== 32) {
|
36
|
+
logger.throwArgumentError("invalid topic", "topic", topic);
|
37
|
+
}
|
38
|
+
return topic.toLowerCase();
|
39
|
+
}
|
40
|
+
function serializeTopics(topics) {
|
41
|
+
// Remove trailing null AND-topics; they are redundant
|
42
|
+
topics = topics.slice();
|
43
|
+
while (topics.length > 0 && topics[topics.length - 1] == null) {
|
44
|
+
topics.pop();
|
45
|
+
}
|
46
|
+
return topics.map((topic) => {
|
47
|
+
if (Array.isArray(topic)) {
|
48
|
+
// Only track unique OR-topics
|
49
|
+
const unique = {};
|
50
|
+
topic.forEach((topic) => {
|
51
|
+
unique[checkTopic(topic)] = true;
|
52
|
+
});
|
53
|
+
// The order of OR-topics does not matter
|
54
|
+
const sorted = Object.keys(unique);
|
55
|
+
sorted.sort();
|
56
|
+
return sorted.join("|");
|
57
|
+
}
|
58
|
+
else {
|
59
|
+
return checkTopic(topic);
|
60
|
+
}
|
61
|
+
}).join("&");
|
62
|
+
}
|
63
|
+
function deserializeTopics(data) {
|
64
|
+
if (data === "") {
|
65
|
+
return [];
|
66
|
+
}
|
67
|
+
return data.split(/&/g).map((topic) => {
|
68
|
+
if (topic === "") {
|
69
|
+
return [];
|
70
|
+
}
|
71
|
+
const comps = topic.split("|").map((topic) => {
|
72
|
+
return ((topic === "null") ? null : topic);
|
73
|
+
});
|
74
|
+
return ((comps.length === 1) ? comps[0] : comps);
|
75
|
+
});
|
76
|
+
}
|
77
|
+
function getEventTag(eventName) {
|
78
|
+
if (typeof (eventName) === "string") {
|
79
|
+
eventName = eventName.toLowerCase();
|
80
|
+
if (hexDataLength(eventName) === 32) {
|
81
|
+
return "tx:" + eventName;
|
82
|
+
}
|
83
|
+
if (eventName.indexOf(":") === -1) {
|
84
|
+
return eventName;
|
85
|
+
}
|
86
|
+
}
|
87
|
+
else if (Array.isArray(eventName)) {
|
88
|
+
return "filter:*:" + serializeTopics(eventName);
|
89
|
+
}
|
90
|
+
else if (ForkEvent.isForkEvent(eventName)) {
|
91
|
+
logger.warn("not implemented");
|
92
|
+
throw new Error("not implemented");
|
93
|
+
}
|
94
|
+
else if (eventName && typeof (eventName) === "object") {
|
95
|
+
return "filter:" + (eventName.address || "*") + ":" + serializeTopics(eventName.topics || []);
|
96
|
+
}
|
97
|
+
throw new Error("invalid event - " + eventName);
|
98
|
+
}
|
99
|
+
//////////////////////////////
|
100
|
+
// Helper Object
|
101
|
+
function getTime() {
|
102
|
+
return (new Date()).getTime();
|
103
|
+
}
|
104
|
+
function stall(duration) {
|
105
|
+
return new Promise((resolve) => {
|
106
|
+
setTimeout(resolve, duration);
|
107
|
+
});
|
108
|
+
}
|
109
|
+
//////////////////////////////
|
110
|
+
// Provider Object
|
111
|
+
/**
|
112
|
+
* EventType
|
113
|
+
* - "block"
|
114
|
+
* - "poll"
|
115
|
+
* - "didPoll"
|
116
|
+
* - "pending"
|
117
|
+
* - "error"
|
118
|
+
* - "network"
|
119
|
+
* - filter
|
120
|
+
* - topics array
|
121
|
+
* - transaction hash
|
122
|
+
*/
|
123
|
+
const PollableEvents = ["block", "network", "pending", "poll"];
|
124
|
+
class Event {
|
125
|
+
constructor(tag, listener, once) {
|
126
|
+
defineReadOnly(this, "tag", tag);
|
127
|
+
defineReadOnly(this, "listener", listener);
|
128
|
+
defineReadOnly(this, "once", once);
|
129
|
+
this._lastBlockNumber = -2;
|
130
|
+
this._inflight = false;
|
131
|
+
}
|
132
|
+
get event() {
|
133
|
+
switch (this.type) {
|
134
|
+
case "tx":
|
135
|
+
return this.hash;
|
136
|
+
case "filter":
|
137
|
+
return this.filter;
|
138
|
+
}
|
139
|
+
return this.tag;
|
140
|
+
}
|
141
|
+
get type() {
|
142
|
+
return this.tag.split(":")[0];
|
143
|
+
}
|
144
|
+
get hash() {
|
145
|
+
const comps = this.tag.split(":");
|
146
|
+
if (comps[0] !== "tx") {
|
147
|
+
return null;
|
148
|
+
}
|
149
|
+
return comps[1];
|
150
|
+
}
|
151
|
+
get filter() {
|
152
|
+
const comps = this.tag.split(":");
|
153
|
+
if (comps[0] !== "filter") {
|
154
|
+
return null;
|
155
|
+
}
|
156
|
+
const address = comps[1];
|
157
|
+
const topics = deserializeTopics(comps[2]);
|
158
|
+
const filter = {};
|
159
|
+
if (topics.length > 0) {
|
160
|
+
filter.topics = topics;
|
161
|
+
}
|
162
|
+
if (address && address !== "*") {
|
163
|
+
filter.address = address;
|
164
|
+
}
|
165
|
+
return filter;
|
166
|
+
}
|
167
|
+
pollable() {
|
168
|
+
return (this.tag.indexOf(":") >= 0 || PollableEvents.indexOf(this.tag) >= 0);
|
169
|
+
}
|
170
|
+
}
|
171
|
+
// https://github.com/satoshilabs/slips/blob/master/slip-0044.md
|
172
|
+
const coinInfos = {
|
173
|
+
"0": { symbol: "btc", p2pkh: 0x00, p2sh: 0x05, prefix: "bc" },
|
174
|
+
"2": { symbol: "ltc", p2pkh: 0x30, p2sh: 0x32, prefix: "ltc" },
|
175
|
+
"3": { symbol: "doge", p2pkh: 0x1e, p2sh: 0x16 },
|
176
|
+
"60": { symbol: "eth", ilk: "eth" },
|
177
|
+
"61": { symbol: "etc", ilk: "eth" },
|
178
|
+
"700": { symbol: "xdai", ilk: "eth" },
|
179
|
+
};
|
180
|
+
function bytes32ify(value) {
|
181
|
+
return hexZeroPad(BigNumber.from(value).toHexString(), 32);
|
182
|
+
}
|
183
|
+
// Compute the Base58Check encoded data (checksum is first 4 bytes of sha256d)
|
184
|
+
function base58Encode(data) {
|
185
|
+
return Base58.encode(concat([data, hexDataSlice(sha256(sha256(data)), 0, 4)]));
|
186
|
+
}
|
187
|
+
const matcherIpfs = new RegExp("^(ipfs):/\/(.*)$", "i");
|
188
|
+
const matchers = [
|
189
|
+
new RegExp("^(https):/\/(.*)$", "i"),
|
190
|
+
new RegExp("^(data):(.*)$", "i"),
|
191
|
+
matcherIpfs,
|
192
|
+
new RegExp("^eip155:[0-9]+/(erc[0-9]+):(.*)$", "i"),
|
193
|
+
];
|
194
|
+
function _parseString(result, start) {
|
195
|
+
try {
|
196
|
+
return toUtf8String(_parseBytes(result, start));
|
197
|
+
}
|
198
|
+
catch (error) { }
|
199
|
+
return null;
|
200
|
+
}
|
201
|
+
function _parseBytes(result, start) {
|
202
|
+
if (result === "0x") {
|
203
|
+
return null;
|
204
|
+
}
|
205
|
+
const offset = BigNumber.from(hexDataSlice(result, start, start + 32)).toNumber();
|
206
|
+
const length = BigNumber.from(hexDataSlice(result, offset, offset + 32)).toNumber();
|
207
|
+
return hexDataSlice(result, offset + 32, offset + 32 + length);
|
208
|
+
}
|
209
|
+
// Trim off the ipfs:// prefix and return the default gateway URL
|
210
|
+
function getIpfsLink(link) {
|
211
|
+
if (link.match(/^ipfs:\/\/ipfs\//i)) {
|
212
|
+
link = link.substring(12);
|
213
|
+
}
|
214
|
+
else if (link.match(/^ipfs:\/\//i)) {
|
215
|
+
link = link.substring(7);
|
216
|
+
}
|
217
|
+
else {
|
218
|
+
logger.throwArgumentError("unsupported IPFS format", "link", link);
|
219
|
+
}
|
220
|
+
return `https:/\/gateway.ipfs.io/ipfs/${link}`;
|
221
|
+
}
|
222
|
+
function numPad(value) {
|
223
|
+
const result = arrayify(value);
|
224
|
+
if (result.length > 32) {
|
225
|
+
throw new Error("internal; should not happen");
|
226
|
+
}
|
227
|
+
const padded = new Uint8Array(32);
|
228
|
+
padded.set(result, 32 - result.length);
|
229
|
+
return padded;
|
230
|
+
}
|
231
|
+
function bytesPad(value) {
|
232
|
+
if ((value.length % 32) === 0) {
|
233
|
+
return value;
|
234
|
+
}
|
235
|
+
const result = new Uint8Array(Math.ceil(value.length / 32) * 32);
|
236
|
+
result.set(value);
|
237
|
+
return result;
|
238
|
+
}
|
239
|
+
// ABI Encodes a series of (bytes, bytes, ...)
|
240
|
+
function encodeBytes(datas) {
|
241
|
+
const result = [];
|
242
|
+
let byteCount = 0;
|
243
|
+
// Add place-holders for pointers as we add items
|
244
|
+
for (let i = 0; i < datas.length; i++) {
|
245
|
+
result.push(null);
|
246
|
+
byteCount += 32;
|
247
|
+
}
|
248
|
+
for (let i = 0; i < datas.length; i++) {
|
249
|
+
const data = arrayify(datas[i]);
|
250
|
+
// Update the bytes offset
|
251
|
+
result[i] = numPad(byteCount);
|
252
|
+
// The length and padded value of data
|
253
|
+
result.push(numPad(data.length));
|
254
|
+
result.push(bytesPad(data));
|
255
|
+
byteCount += 32 + Math.ceil(data.length / 32) * 32;
|
256
|
+
}
|
257
|
+
return hexConcat(result);
|
258
|
+
}
|
259
|
+
class Resolver {
|
260
|
+
// The resolvedAddress is only for creating a ReverseLookup resolver
|
261
|
+
constructor(provider, address, name, resolvedAddress) {
|
262
|
+
defineReadOnly(this, "provider", provider);
|
263
|
+
defineReadOnly(this, "name", name);
|
264
|
+
defineReadOnly(this, "address", provider.formatter.address(address));
|
265
|
+
defineReadOnly(this, "_resolvedAddress", resolvedAddress);
|
266
|
+
}
|
267
|
+
supportsWildcard() {
|
268
|
+
if (!this._supportsEip2544) {
|
269
|
+
// supportsInterface(bytes4 = selector("resolve(bytes,bytes)"))
|
270
|
+
this._supportsEip2544 = this.provider.call({
|
271
|
+
to: this.address,
|
272
|
+
data: "0x01ffc9a79061b92300000000000000000000000000000000000000000000000000000000"
|
273
|
+
}).then((result) => {
|
274
|
+
return BigNumber.from(result).eq(1);
|
275
|
+
}).catch((error) => {
|
276
|
+
if (error.code === Logger.errors.CALL_EXCEPTION) {
|
277
|
+
return false;
|
278
|
+
}
|
279
|
+
// Rethrow the error: link is down, etc. Let future attempts retry.
|
280
|
+
this._supportsEip2544 = null;
|
281
|
+
throw error;
|
282
|
+
});
|
283
|
+
}
|
284
|
+
return this._supportsEip2544;
|
285
|
+
}
|
286
|
+
_fetch(selector, parameters) {
|
287
|
+
return __awaiter(this, undefined, undefined, function* () {
|
288
|
+
// e.g. keccak256("addr(bytes32,uint256)")
|
289
|
+
const tx = {
|
290
|
+
to: this.address,
|
291
|
+
ccipReadEnabled: true,
|
292
|
+
data: hexConcat([selector, namehash(this.name), (parameters || "0x")])
|
293
|
+
};
|
294
|
+
// Wildcard support; use EIP-2544 to resolve the request
|
295
|
+
let parseBytes = false;
|
296
|
+
if (yield this.supportsWildcard()) {
|
297
|
+
parseBytes = true;
|
298
|
+
// selector("resolve(bytes,bytes)")
|
299
|
+
tx.data = hexConcat(["0x9061b923", encodeBytes([dnsEncode(this.name), tx.data])]);
|
300
|
+
}
|
301
|
+
try {
|
302
|
+
let result = yield this.provider.call(tx);
|
303
|
+
if ((arrayify(result).length % 32) === 4) {
|
304
|
+
logger.throwError("resolver threw error", Logger.errors.CALL_EXCEPTION, {
|
305
|
+
transaction: tx, data: result
|
306
|
+
});
|
307
|
+
}
|
308
|
+
if (parseBytes) {
|
309
|
+
result = _parseBytes(result, 0);
|
310
|
+
}
|
311
|
+
return result;
|
312
|
+
}
|
313
|
+
catch (error) {
|
314
|
+
if (error.code === Logger.errors.CALL_EXCEPTION) {
|
315
|
+
return null;
|
316
|
+
}
|
317
|
+
throw error;
|
318
|
+
}
|
319
|
+
});
|
320
|
+
}
|
321
|
+
_fetchBytes(selector, parameters) {
|
322
|
+
return __awaiter(this, undefined, undefined, function* () {
|
323
|
+
const result = yield this._fetch(selector, parameters);
|
324
|
+
if (result != null) {
|
325
|
+
return _parseBytes(result, 0);
|
326
|
+
}
|
327
|
+
return null;
|
328
|
+
});
|
329
|
+
}
|
330
|
+
_getAddress(coinType, hexBytes) {
|
331
|
+
const coinInfo = coinInfos[String(coinType)];
|
332
|
+
if (coinInfo == null) {
|
333
|
+
logger.throwError(`unsupported coin type: ${coinType}`, Logger.errors.UNSUPPORTED_OPERATION, {
|
334
|
+
operation: `getAddress(${coinType})`
|
335
|
+
});
|
336
|
+
}
|
337
|
+
if (coinInfo.ilk === "eth") {
|
338
|
+
return this.provider.formatter.address(hexBytes);
|
339
|
+
}
|
340
|
+
const bytes = arrayify(hexBytes);
|
341
|
+
// P2PKH: OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
|
342
|
+
if (coinInfo.p2pkh != null) {
|
343
|
+
const p2pkh = hexBytes.match(/^0x76a9([0-9a-f][0-9a-f])([0-9a-f]*)88ac$/);
|
344
|
+
if (p2pkh) {
|
345
|
+
const length = parseInt(p2pkh[1], 16);
|
346
|
+
if (p2pkh[2].length === length * 2 && length >= 1 && length <= 75) {
|
347
|
+
return base58Encode(concat([[coinInfo.p2pkh], ("0x" + p2pkh[2])]));
|
348
|
+
}
|
349
|
+
}
|
350
|
+
}
|
351
|
+
// P2SH: OP_HASH160 <scriptHash> OP_EQUAL
|
352
|
+
if (coinInfo.p2sh != null) {
|
353
|
+
const p2sh = hexBytes.match(/^0xa9([0-9a-f][0-9a-f])([0-9a-f]*)87$/);
|
354
|
+
if (p2sh) {
|
355
|
+
const length = parseInt(p2sh[1], 16);
|
356
|
+
if (p2sh[2].length === length * 2 && length >= 1 && length <= 75) {
|
357
|
+
return base58Encode(concat([[coinInfo.p2sh], ("0x" + p2sh[2])]));
|
358
|
+
}
|
359
|
+
}
|
360
|
+
}
|
361
|
+
// Bech32
|
362
|
+
if (coinInfo.prefix != null) {
|
363
|
+
const length = bytes[1];
|
364
|
+
// https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#witness-program
|
365
|
+
let version = bytes[0];
|
366
|
+
if (version === 0x00) {
|
367
|
+
if (length !== 20 && length !== 32) {
|
368
|
+
version = -1;
|
369
|
+
}
|
370
|
+
}
|
371
|
+
else {
|
372
|
+
version = -1;
|
373
|
+
}
|
374
|
+
if (version >= 0 && bytes.length === 2 + length && length >= 1 && length <= 75) {
|
375
|
+
const words = bech32.toWords(bytes.slice(2));
|
376
|
+
words.unshift(version);
|
377
|
+
return bech32.encode(coinInfo.prefix, words);
|
378
|
+
}
|
379
|
+
}
|
380
|
+
return null;
|
381
|
+
}
|
382
|
+
getAddress(coinType) {
|
383
|
+
return __awaiter(this, undefined, undefined, function* () {
|
384
|
+
if (coinType == null) {
|
385
|
+
coinType = 60;
|
386
|
+
}
|
387
|
+
// If Ethereum, use the standard `addr(bytes32)`
|
388
|
+
if (coinType === 60) {
|
389
|
+
try {
|
390
|
+
// keccak256("addr(bytes32)")
|
391
|
+
const result = yield this._fetch("0x3b3b57de");
|
392
|
+
// No address
|
393
|
+
if (result === "0x" || result === HashZero) {
|
394
|
+
return null;
|
395
|
+
}
|
396
|
+
return this.provider.formatter.callAddress(result);
|
397
|
+
}
|
398
|
+
catch (error) {
|
399
|
+
if (error.code === Logger.errors.CALL_EXCEPTION) {
|
400
|
+
return null;
|
401
|
+
}
|
402
|
+
throw error;
|
403
|
+
}
|
404
|
+
}
|
405
|
+
// keccak256("addr(bytes32,uint256")
|
406
|
+
const hexBytes = yield this._fetchBytes("0xf1cb7e06", bytes32ify(coinType));
|
407
|
+
// No address
|
408
|
+
if (hexBytes == null || hexBytes === "0x") {
|
409
|
+
return null;
|
410
|
+
}
|
411
|
+
// Compute the address
|
412
|
+
const address = this._getAddress(coinType, hexBytes);
|
413
|
+
if (address == null) {
|
414
|
+
logger.throwError(`invalid or unsupported coin data`, Logger.errors.UNSUPPORTED_OPERATION, {
|
415
|
+
operation: `getAddress(${coinType})`,
|
416
|
+
coinType: coinType,
|
417
|
+
data: hexBytes
|
418
|
+
});
|
419
|
+
}
|
420
|
+
return address;
|
421
|
+
});
|
422
|
+
}
|
423
|
+
getAvatar() {
|
424
|
+
return __awaiter(this, undefined, undefined, function* () {
|
425
|
+
const linkage = [{ type: "name", content: this.name }];
|
426
|
+
try {
|
427
|
+
// test data for ricmoo.eth
|
428
|
+
//const avatar = "eip155:1/erc721:0x265385c7f4132228A0d54EB1A9e7460b91c0cC68/29233";
|
429
|
+
const avatar = yield this.getText("avatar");
|
430
|
+
if (avatar == null) {
|
431
|
+
return null;
|
432
|
+
}
|
433
|
+
for (let i = 0; i < matchers.length; i++) {
|
434
|
+
const match = avatar.match(matchers[i]);
|
435
|
+
if (match == null) {
|
436
|
+
continue;
|
437
|
+
}
|
438
|
+
const scheme = match[1].toLowerCase();
|
439
|
+
switch (scheme) {
|
440
|
+
case "https":
|
441
|
+
linkage.push({ type: "url", content: avatar });
|
442
|
+
return { linkage, url: avatar };
|
443
|
+
case "data":
|
444
|
+
linkage.push({ type: "data", content: avatar });
|
445
|
+
return { linkage, url: avatar };
|
446
|
+
case "ipfs":
|
447
|
+
linkage.push({ type: "ipfs", content: avatar });
|
448
|
+
return { linkage, url: getIpfsLink(avatar) };
|
449
|
+
case "erc721":
|
450
|
+
case "erc1155": {
|
451
|
+
// Depending on the ERC type, use tokenURI(uint256) or url(uint256)
|
452
|
+
const selector = (scheme === "erc721") ? "0xc87b56dd" : "0x0e89341c";
|
453
|
+
linkage.push({ type: scheme, content: avatar });
|
454
|
+
// The owner of this name
|
455
|
+
const owner = (this._resolvedAddress || (yield this.getAddress()));
|
456
|
+
const comps = (match[2] || "").split("/");
|
457
|
+
if (comps.length !== 2) {
|
458
|
+
return null;
|
459
|
+
}
|
460
|
+
const addr = yield this.provider.formatter.address(comps[0]);
|
461
|
+
const tokenId = hexZeroPad(BigNumber.from(comps[1]).toHexString(), 32);
|
462
|
+
// Check that this account owns the token
|
463
|
+
if (scheme === "erc721") {
|
464
|
+
// ownerOf(uint256 tokenId)
|
465
|
+
const tokenOwner = this.provider.formatter.callAddress(yield this.provider.call({
|
466
|
+
to: addr, data: hexConcat(["0x6352211e", tokenId])
|
467
|
+
}));
|
468
|
+
if (owner !== tokenOwner) {
|
469
|
+
return null;
|
470
|
+
}
|
471
|
+
linkage.push({ type: "owner", content: tokenOwner });
|
472
|
+
}
|
473
|
+
else if (scheme === "erc1155") {
|
474
|
+
// balanceOf(address owner, uint256 tokenId)
|
475
|
+
const balance = BigNumber.from(yield this.provider.call({
|
476
|
+
to: addr, data: hexConcat(["0x00fdd58e", hexZeroPad(owner, 32), tokenId])
|
477
|
+
}));
|
478
|
+
if (balance.isZero()) {
|
479
|
+
return null;
|
480
|
+
}
|
481
|
+
linkage.push({ type: "balance", content: balance.toString() });
|
482
|
+
}
|
483
|
+
// Call the token contract for the metadata URL
|
484
|
+
const tx = {
|
485
|
+
to: this.provider.formatter.address(comps[0]),
|
486
|
+
data: hexConcat([selector, tokenId])
|
487
|
+
};
|
488
|
+
let metadataUrl = _parseString(yield this.provider.call(tx), 0);
|
489
|
+
if (metadataUrl == null) {
|
490
|
+
return null;
|
491
|
+
}
|
492
|
+
linkage.push({ type: "metadata-url-base", content: metadataUrl });
|
493
|
+
// ERC-1155 allows a generic {id} in the URL
|
494
|
+
if (scheme === "erc1155") {
|
495
|
+
metadataUrl = metadataUrl.replace("{id}", tokenId.substring(2));
|
496
|
+
linkage.push({ type: "metadata-url-expanded", content: metadataUrl });
|
497
|
+
}
|
498
|
+
// Transform IPFS metadata links
|
499
|
+
if (metadataUrl.match(/^ipfs:/i)) {
|
500
|
+
metadataUrl = getIpfsLink(metadataUrl);
|
501
|
+
}
|
502
|
+
linkage.push({ type: "metadata-url", content: metadataUrl });
|
503
|
+
// Get the token metadata
|
504
|
+
const metadata = yield fetchJson(metadataUrl);
|
505
|
+
if (!metadata) {
|
506
|
+
return null;
|
507
|
+
}
|
508
|
+
linkage.push({ type: "metadata", content: JSON.stringify(metadata) });
|
509
|
+
// Pull the image URL out
|
510
|
+
let imageUrl = metadata.image;
|
511
|
+
if (typeof (imageUrl) !== "string") {
|
512
|
+
return null;
|
513
|
+
}
|
514
|
+
if (imageUrl.match(/^(https:\/\/|data:)/i)) {
|
515
|
+
// Allow
|
516
|
+
}
|
517
|
+
else {
|
518
|
+
// Transform IPFS link to gateway
|
519
|
+
const ipfs = imageUrl.match(matcherIpfs);
|
520
|
+
if (ipfs == null) {
|
521
|
+
return null;
|
522
|
+
}
|
523
|
+
linkage.push({ type: "url-ipfs", content: imageUrl });
|
524
|
+
imageUrl = getIpfsLink(imageUrl);
|
525
|
+
}
|
526
|
+
linkage.push({ type: "url", content: imageUrl });
|
527
|
+
return { linkage, url: imageUrl };
|
528
|
+
}
|
529
|
+
}
|
530
|
+
}
|
531
|
+
}
|
532
|
+
catch (error) { }
|
533
|
+
return null;
|
534
|
+
});
|
535
|
+
}
|
536
|
+
getContentHash() {
|
537
|
+
return __awaiter(this, undefined, undefined, function* () {
|
538
|
+
// keccak256("contenthash()")
|
539
|
+
const hexBytes = yield this._fetchBytes("0xbc1c58d1");
|
540
|
+
// No contenthash
|
541
|
+
if (hexBytes == null || hexBytes === "0x") {
|
542
|
+
return null;
|
543
|
+
}
|
544
|
+
// IPFS (CID: 1, Type: DAG-PB)
|
545
|
+
const ipfs = hexBytes.match(/^0xe3010170(([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f]*))$/);
|
546
|
+
if (ipfs) {
|
547
|
+
const length = parseInt(ipfs[3], 16);
|
548
|
+
if (ipfs[4].length === length * 2) {
|
549
|
+
return "ipfs:/\/" + Base58.encode("0x" + ipfs[1]);
|
550
|
+
}
|
551
|
+
}
|
552
|
+
// IPNS (CID: 1, Type: libp2p-key)
|
553
|
+
const ipns = hexBytes.match(/^0xe5010172(([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f]*))$/);
|
554
|
+
if (ipns) {
|
555
|
+
const length = parseInt(ipns[3], 16);
|
556
|
+
if (ipns[4].length === length * 2) {
|
557
|
+
return "ipns:/\/" + Base58.encode("0x" + ipns[1]);
|
558
|
+
}
|
559
|
+
}
|
560
|
+
// Swarm (CID: 1, Type: swarm-manifest; hash/length hard-coded to keccak256/32)
|
561
|
+
const swarm = hexBytes.match(/^0xe40101fa011b20([0-9a-f]*)$/);
|
562
|
+
if (swarm) {
|
563
|
+
if (swarm[1].length === (32 * 2)) {
|
564
|
+
return "bzz:/\/" + swarm[1];
|
565
|
+
}
|
566
|
+
}
|
567
|
+
const skynet = hexBytes.match(/^0x90b2c605([0-9a-f]*)$/);
|
568
|
+
if (skynet) {
|
569
|
+
if (skynet[1].length === (34 * 2)) {
|
570
|
+
// URL Safe base64; https://datatracker.ietf.org/doc/html/rfc4648#section-5
|
571
|
+
const urlSafe = { "=": "", "+": "-", "/": "_" };
|
572
|
+
const hash = encode("0x" + skynet[1]).replace(/[=+\/]/g, (a) => (urlSafe[a]));
|
573
|
+
return "sia:/\/" + hash;
|
574
|
+
}
|
575
|
+
}
|
576
|
+
return logger.throwError(`invalid or unsupported content hash data`, Logger.errors.UNSUPPORTED_OPERATION, {
|
577
|
+
operation: "getContentHash()",
|
578
|
+
data: hexBytes
|
579
|
+
});
|
580
|
+
});
|
581
|
+
}
|
582
|
+
getText(key) {
|
583
|
+
return __awaiter(this, undefined, undefined, function* () {
|
584
|
+
// The key encoded as parameter to fetchBytes
|
585
|
+
let keyBytes = toUtf8Bytes(key);
|
586
|
+
// The nodehash consumes the first slot, so the string pointer targets
|
587
|
+
// offset 64, with the length at offset 64 and data starting at offset 96
|
588
|
+
keyBytes = concat([bytes32ify(64), bytes32ify(keyBytes.length), keyBytes]);
|
589
|
+
// Pad to word-size (32 bytes)
|
590
|
+
if ((keyBytes.length % 32) !== 0) {
|
591
|
+
keyBytes = concat([keyBytes, hexZeroPad("0x", 32 - (key.length % 32))]);
|
592
|
+
}
|
593
|
+
const hexBytes = yield this._fetchBytes("0x59d1d43c", hexlify(keyBytes));
|
594
|
+
if (hexBytes == null || hexBytes === "0x") {
|
595
|
+
return null;
|
596
|
+
}
|
597
|
+
return toUtf8String(hexBytes);
|
598
|
+
});
|
599
|
+
}
|
600
|
+
}
|
601
|
+
let defaultFormatter = null;
|
602
|
+
let nextPollId = 1;
|
603
|
+
class BaseProvider extends Provider {
|
604
|
+
/**
|
605
|
+
* ready
|
606
|
+
*
|
607
|
+
* A Promise<Network> that resolves only once the provider is ready.
|
608
|
+
*
|
609
|
+
* Sub-classes that call the super with a network without a chainId
|
610
|
+
* MUST set this. Standard named networks have a known chainId.
|
611
|
+
*
|
612
|
+
*/
|
613
|
+
constructor(network) {
|
614
|
+
super();
|
615
|
+
// Events being listened to
|
616
|
+
this._events = [];
|
617
|
+
this._emitted = { block: -2 };
|
618
|
+
this.disableCcipRead = false;
|
619
|
+
this.formatter = new.target.getFormatter();
|
620
|
+
// If network is any, this Provider allows the underlying
|
621
|
+
// network to change dynamically, and we auto-detect the
|
622
|
+
// current network
|
623
|
+
defineReadOnly(this, "anyNetwork", (network === "any"));
|
624
|
+
if (this.anyNetwork) {
|
625
|
+
network = this.detectNetwork();
|
626
|
+
}
|
627
|
+
if (network instanceof Promise) {
|
628
|
+
this._networkPromise = network;
|
629
|
+
// Squash any "unhandled promise" errors; that do not need to be handled
|
630
|
+
network.catch((error) => { });
|
631
|
+
// Trigger initial network setting (async)
|
632
|
+
this._ready().catch((error) => { });
|
633
|
+
}
|
634
|
+
else {
|
635
|
+
const knownNetwork = getStatic(new.target, "getNetwork")(network);
|
636
|
+
if (knownNetwork) {
|
637
|
+
defineReadOnly(this, "_network", knownNetwork);
|
638
|
+
this.emit("network", knownNetwork, null);
|
639
|
+
}
|
640
|
+
else {
|
641
|
+
logger.throwArgumentError("invalid network", "network", network);
|
642
|
+
}
|
643
|
+
}
|
644
|
+
this._maxInternalBlockNumber = -1024;
|
645
|
+
this._lastBlockNumber = -2;
|
646
|
+
this._maxFilterBlockRange = 10;
|
647
|
+
this._pollingInterval = 4000;
|
648
|
+
this._fastQueryDate = 0;
|
649
|
+
}
|
650
|
+
_ready() {
|
651
|
+
return __awaiter(this, undefined, undefined, function* () {
|
652
|
+
if (this._network == null) {
|
653
|
+
let network = null;
|
654
|
+
if (this._networkPromise) {
|
655
|
+
try {
|
656
|
+
network = yield this._networkPromise;
|
657
|
+
}
|
658
|
+
catch (error) { }
|
659
|
+
}
|
660
|
+
// Try the Provider's network detection (this MUST throw if it cannot)
|
661
|
+
if (network == null) {
|
662
|
+
network = yield this.detectNetwork();
|
663
|
+
}
|
664
|
+
// This should never happen; every Provider sub-class should have
|
665
|
+
// suggested a network by here (or have thrown).
|
666
|
+
if (!network) {
|
667
|
+
logger.throwError("no network detected", Logger.errors.UNKNOWN_ERROR, {});
|
668
|
+
}
|
669
|
+
// Possible this call stacked so do not call defineReadOnly again
|
670
|
+
if (this._network == null) {
|
671
|
+
if (this.anyNetwork) {
|
672
|
+
this._network = network;
|
673
|
+
}
|
674
|
+
else {
|
675
|
+
defineReadOnly(this, "_network", network);
|
676
|
+
}
|
677
|
+
this.emit("network", network, null);
|
678
|
+
}
|
679
|
+
}
|
680
|
+
return this._network;
|
681
|
+
});
|
682
|
+
}
|
683
|
+
// This will always return the most recently established network.
|
684
|
+
// For "any", this can change (a "network" event is emitted before
|
685
|
+
// any change is reflected); otherwise this cannot change
|
686
|
+
get ready() {
|
687
|
+
return poll(() => {
|
688
|
+
return this._ready().then((network) => {
|
689
|
+
return network;
|
690
|
+
}, (error) => {
|
691
|
+
// If the network isn't running yet, we will wait
|
692
|
+
if (error.code === Logger.errors.NETWORK_ERROR && error.event === "noNetwork") {
|
693
|
+
return undefined;
|
694
|
+
}
|
695
|
+
throw error;
|
696
|
+
});
|
697
|
+
});
|
698
|
+
}
|
699
|
+
// @TODO: Remove this and just create a singleton formatter
|
700
|
+
static getFormatter() {
|
701
|
+
if (defaultFormatter == null) {
|
702
|
+
defaultFormatter = new Formatter();
|
703
|
+
}
|
704
|
+
return defaultFormatter;
|
705
|
+
}
|
706
|
+
// @TODO: Remove this and just use getNetwork
|
707
|
+
static getNetwork(network) {
|
708
|
+
return getNetwork((network == null) ? "homestead" : network);
|
709
|
+
}
|
710
|
+
ccipReadFetch(tx, calldata, urls) {
|
711
|
+
return __awaiter(this, undefined, undefined, function* () {
|
712
|
+
if (this.disableCcipRead || urls.length === 0) {
|
713
|
+
return null;
|
714
|
+
}
|
715
|
+
const sender = tx.to.toLowerCase();
|
716
|
+
const data = calldata.toLowerCase();
|
717
|
+
const errorMessages = [];
|
718
|
+
for (let i = 0; i < urls.length; i++) {
|
719
|
+
const url = urls[i];
|
720
|
+
// URL expansion
|
721
|
+
const href = url.replace("{sender}", sender).replace("{data}", data);
|
722
|
+
// If no {data} is present, use POST; otherwise GET
|
723
|
+
const json = (url.indexOf("{data}") >= 0) ? null : JSON.stringify({ data, sender });
|
724
|
+
const result = yield fetchJson({ url: href, errorPassThrough: true }, json, (value, response) => {
|
725
|
+
value.status = response.statusCode;
|
726
|
+
return value;
|
727
|
+
});
|
728
|
+
if (result.data) {
|
729
|
+
return result.data;
|
730
|
+
}
|
731
|
+
const errorMessage = (result.message || "unknown error");
|
732
|
+
// 4xx indicates the result is not present; stop
|
733
|
+
if (result.status >= 400 && result.status < 500) {
|
734
|
+
return logger.throwError(`response not found during CCIP fetch: ${errorMessage}`, Logger.errors.SERVER_ERROR, { url, errorMessage });
|
735
|
+
}
|
736
|
+
// 5xx indicates server issue; try the next url
|
737
|
+
errorMessages.push(errorMessage);
|
738
|
+
}
|
739
|
+
return logger.throwError(`error encountered during CCIP fetch: ${errorMessages.map((m) => JSON.stringify(m)).join(", ")}`, Logger.errors.SERVER_ERROR, {
|
740
|
+
urls, errorMessages
|
741
|
+
});
|
742
|
+
});
|
743
|
+
}
|
744
|
+
// Fetches the blockNumber, but will reuse any result that is less
|
745
|
+
// than maxAge old or has been requested since the last request
|
746
|
+
_getInternalBlockNumber(maxAge) {
|
747
|
+
return __awaiter(this, undefined, undefined, function* () {
|
748
|
+
yield this._ready();
|
749
|
+
// Allowing stale data up to maxAge old
|
750
|
+
if (maxAge > 0) {
|
751
|
+
// While there are pending internal block requests...
|
752
|
+
while (this._internalBlockNumber) {
|
753
|
+
// ..."remember" which fetch we started with
|
754
|
+
const internalBlockNumber = this._internalBlockNumber;
|
755
|
+
try {
|
756
|
+
// Check the result is not too stale
|
757
|
+
const result = yield internalBlockNumber;
|
758
|
+
if ((getTime() - result.respTime) <= maxAge) {
|
759
|
+
return result.blockNumber;
|
760
|
+
}
|
761
|
+
// Too old; fetch a new value
|
762
|
+
break;
|
763
|
+
}
|
764
|
+
catch (error) {
|
765
|
+
// The fetch rejected; if we are the first to get the
|
766
|
+
// rejection, drop through so we replace it with a new
|
767
|
+
// fetch; all others blocked will then get that fetch
|
768
|
+
// which won't match the one they "remembered" and loop
|
769
|
+
if (this._internalBlockNumber === internalBlockNumber) {
|
770
|
+
break;
|
771
|
+
}
|
772
|
+
}
|
773
|
+
}
|
774
|
+
}
|
775
|
+
const reqTime = getTime();
|
776
|
+
const checkInternalBlockNumber = resolveProperties({
|
777
|
+
blockNumber: this.perform("getBlockNumber", {}),
|
778
|
+
networkError: this.getNetwork().then((network) => (null), (error) => (error))
|
779
|
+
}).then(({ blockNumber, networkError }) => {
|
780
|
+
if (networkError) {
|
781
|
+
// Unremember this bad internal block number
|
782
|
+
if (this._internalBlockNumber === checkInternalBlockNumber) {
|
783
|
+
this._internalBlockNumber = null;
|
784
|
+
}
|
785
|
+
throw networkError;
|
786
|
+
}
|
787
|
+
const respTime = getTime();
|
788
|
+
blockNumber = BigNumber.from(blockNumber).toNumber();
|
789
|
+
if (blockNumber < this._maxInternalBlockNumber) {
|
790
|
+
blockNumber = this._maxInternalBlockNumber;
|
791
|
+
}
|
792
|
+
this._maxInternalBlockNumber = blockNumber;
|
793
|
+
this._setFastBlockNumber(blockNumber); // @TODO: Still need this?
|
794
|
+
return { blockNumber, reqTime, respTime };
|
795
|
+
});
|
796
|
+
this._internalBlockNumber = checkInternalBlockNumber;
|
797
|
+
// Swallow unhandled exceptions; if needed they are handled else where
|
798
|
+
checkInternalBlockNumber.catch((error) => {
|
799
|
+
// Don't null the dead (rejected) fetch, if it has already been updated
|
800
|
+
if (this._internalBlockNumber === checkInternalBlockNumber) {
|
801
|
+
this._internalBlockNumber = null;
|
802
|
+
}
|
803
|
+
});
|
804
|
+
return (yield checkInternalBlockNumber).blockNumber;
|
805
|
+
});
|
806
|
+
}
|
807
|
+
poll() {
|
808
|
+
return __awaiter(this, undefined, undefined, function* () {
|
809
|
+
const pollId = nextPollId++;
|
810
|
+
// Track all running promises, so we can trigger a post-poll once they are complete
|
811
|
+
const runners = [];
|
812
|
+
let blockNumber = null;
|
813
|
+
try {
|
814
|
+
blockNumber = yield this._getInternalBlockNumber(100 + this.pollingInterval / 2);
|
815
|
+
}
|
816
|
+
catch (error) {
|
817
|
+
this.emit("error", error);
|
818
|
+
return;
|
819
|
+
}
|
820
|
+
this._setFastBlockNumber(blockNumber);
|
821
|
+
// Emit a poll event after we have the latest (fast) block number
|
822
|
+
this.emit("poll", pollId, blockNumber);
|
823
|
+
// If the block has not changed, meh.
|
824
|
+
if (blockNumber === this._lastBlockNumber) {
|
825
|
+
this.emit("didPoll", pollId);
|
826
|
+
return;
|
827
|
+
}
|
828
|
+
// First polling cycle, trigger a "block" events
|
829
|
+
if (this._emitted.block === -2) {
|
830
|
+
this._emitted.block = blockNumber - 1;
|
831
|
+
}
|
832
|
+
if (Math.abs((this._emitted.block) - blockNumber) > 1000) {
|
833
|
+
logger.warn(`network block skew detected; skipping block events (emitted=${this._emitted.block} blockNumber${blockNumber})`);
|
834
|
+
this.emit("error", logger.makeError("network block skew detected", Logger.errors.NETWORK_ERROR, {
|
835
|
+
blockNumber: blockNumber,
|
836
|
+
event: "blockSkew",
|
837
|
+
previousBlockNumber: this._emitted.block
|
838
|
+
}));
|
839
|
+
this.emit("block", blockNumber);
|
840
|
+
}
|
841
|
+
else {
|
842
|
+
// Notify all listener for each block that has passed
|
843
|
+
for (let i = this._emitted.block + 1; i <= blockNumber; i++) {
|
844
|
+
this.emit("block", i);
|
845
|
+
}
|
846
|
+
}
|
847
|
+
// The emitted block was updated, check for obsolete events
|
848
|
+
if (this._emitted.block !== blockNumber) {
|
849
|
+
this._emitted.block = blockNumber;
|
850
|
+
Object.keys(this._emitted).forEach((key) => {
|
851
|
+
// The block event does not expire
|
852
|
+
if (key === "block") {
|
853
|
+
return;
|
854
|
+
}
|
855
|
+
// The block we were at when we emitted this event
|
856
|
+
const eventBlockNumber = this._emitted[key];
|
857
|
+
// We cannot garbage collect pending transactions or blocks here
|
858
|
+
// They should be garbage collected by the Provider when setting
|
859
|
+
// "pending" events
|
860
|
+
if (eventBlockNumber === "pending") {
|
861
|
+
return;
|
862
|
+
}
|
863
|
+
// Evict any transaction hashes or block hashes over 12 blocks
|
864
|
+
// old, since they should not return null anyways
|
865
|
+
if (blockNumber - eventBlockNumber > 12) {
|
866
|
+
delete this._emitted[key];
|
867
|
+
}
|
868
|
+
});
|
869
|
+
}
|
870
|
+
// First polling cycle
|
871
|
+
if (this._lastBlockNumber === -2) {
|
872
|
+
this._lastBlockNumber = blockNumber - 1;
|
873
|
+
}
|
874
|
+
// Find all transaction hashes we are waiting on
|
875
|
+
this._events.forEach((event) => {
|
876
|
+
switch (event.type) {
|
877
|
+
case "tx": {
|
878
|
+
const hash = event.hash;
|
879
|
+
let runner = this.getTransactionReceipt(hash).then((receipt) => {
|
880
|
+
if (!receipt || receipt.blockNumber == null) {
|
881
|
+
return null;
|
882
|
+
}
|
883
|
+
this._emitted["t:" + hash] = receipt.blockNumber;
|
884
|
+
this.emit(hash, receipt);
|
885
|
+
return null;
|
886
|
+
}).catch((error) => { this.emit("error", error); });
|
887
|
+
runners.push(runner);
|
888
|
+
break;
|
889
|
+
}
|
890
|
+
case "filter": {
|
891
|
+
// We only allow a single getLogs to be in-flight at a time
|
892
|
+
if (!event._inflight) {
|
893
|
+
event._inflight = true;
|
894
|
+
// This is the first filter for this event, so we want to
|
895
|
+
// restrict events to events that happened no earlier than now
|
896
|
+
if (event._lastBlockNumber === -2) {
|
897
|
+
event._lastBlockNumber = blockNumber - 1;
|
898
|
+
}
|
899
|
+
// Filter from the last *known* event; due to load-balancing
|
900
|
+
// and some nodes returning updated block numbers before
|
901
|
+
// indexing events, a logs result with 0 entries cannot be
|
902
|
+
// trusted and we must retry a range which includes it again
|
903
|
+
const filter = event.filter;
|
904
|
+
filter.fromBlock = event._lastBlockNumber + 1;
|
905
|
+
filter.toBlock = blockNumber;
|
906
|
+
// Prevent fitler ranges from growing too wild, since it is quite
|
907
|
+
// likely there just haven't been any events to move the lastBlockNumber.
|
908
|
+
const minFromBlock = filter.toBlock - this._maxFilterBlockRange;
|
909
|
+
if (minFromBlock > filter.fromBlock) {
|
910
|
+
filter.fromBlock = minFromBlock;
|
911
|
+
}
|
912
|
+
if (filter.fromBlock < 0) {
|
913
|
+
filter.fromBlock = 0;
|
914
|
+
}
|
915
|
+
const runner = this.getLogs(filter).then((logs) => {
|
916
|
+
// Allow the next getLogs
|
917
|
+
event._inflight = false;
|
918
|
+
if (logs.length === 0) {
|
919
|
+
return;
|
920
|
+
}
|
921
|
+
logs.forEach((log) => {
|
922
|
+
// Only when we get an event for a given block number
|
923
|
+
// can we trust the events are indexed
|
924
|
+
if (log.blockNumber > event._lastBlockNumber) {
|
925
|
+
event._lastBlockNumber = log.blockNumber;
|
926
|
+
}
|
927
|
+
// Make sure we stall requests to fetch blocks and txs
|
928
|
+
this._emitted["b:" + log.blockHash] = log.blockNumber;
|
929
|
+
this._emitted["t:" + log.transactionHash] = log.blockNumber;
|
930
|
+
this.emit(filter, log);
|
931
|
+
});
|
932
|
+
}).catch((error) => {
|
933
|
+
this.emit("error", error);
|
934
|
+
// Allow another getLogs (the range was not updated)
|
935
|
+
event._inflight = false;
|
936
|
+
});
|
937
|
+
runners.push(runner);
|
938
|
+
}
|
939
|
+
break;
|
940
|
+
}
|
941
|
+
}
|
942
|
+
});
|
943
|
+
this._lastBlockNumber = blockNumber;
|
944
|
+
// Once all events for this loop have been processed, emit "didPoll"
|
945
|
+
Promise.all(runners).then(() => {
|
946
|
+
this.emit("didPoll", pollId);
|
947
|
+
}).catch((error) => { this.emit("error", error); });
|
948
|
+
return;
|
949
|
+
});
|
950
|
+
}
|
951
|
+
// Deprecated; do not use this
|
952
|
+
resetEventsBlock(blockNumber) {
|
953
|
+
this._lastBlockNumber = blockNumber - 1;
|
954
|
+
if (this.polling) {
|
955
|
+
this.poll();
|
956
|
+
}
|
957
|
+
}
|
958
|
+
get network() {
|
959
|
+
return this._network;
|
960
|
+
}
|
961
|
+
// This method should query the network if the underlying network
|
962
|
+
// can change, such as when connected to a JSON-RPC backend
|
963
|
+
detectNetwork() {
|
964
|
+
return __awaiter(this, undefined, undefined, function* () {
|
965
|
+
return logger.throwError("provider does not support network detection", Logger.errors.UNSUPPORTED_OPERATION, {
|
966
|
+
operation: "provider.detectNetwork"
|
967
|
+
});
|
968
|
+
});
|
969
|
+
}
|
970
|
+
getNetwork() {
|
971
|
+
return __awaiter(this, undefined, undefined, function* () {
|
972
|
+
const network = yield this._ready();
|
973
|
+
// Make sure we are still connected to the same network; this is
|
974
|
+
// only an external call for backends which can have the underlying
|
975
|
+
// network change spontaneously
|
976
|
+
const currentNetwork = yield this.detectNetwork();
|
977
|
+
if (network.chainId !== currentNetwork.chainId) {
|
978
|
+
// We are allowing network changes, things can get complex fast;
|
979
|
+
// make sure you know what you are doing if you use "any"
|
980
|
+
if (this.anyNetwork) {
|
981
|
+
this._network = currentNetwork;
|
982
|
+
// Reset all internal block number guards and caches
|
983
|
+
this._lastBlockNumber = -2;
|
984
|
+
this._fastBlockNumber = null;
|
985
|
+
this._fastBlockNumberPromise = null;
|
986
|
+
this._fastQueryDate = 0;
|
987
|
+
this._emitted.block = -2;
|
988
|
+
this._maxInternalBlockNumber = -1024;
|
989
|
+
this._internalBlockNumber = null;
|
990
|
+
// The "network" event MUST happen before this method resolves
|
991
|
+
// so any events have a chance to unregister, so we stall an
|
992
|
+
// additional event loop before returning from /this/ call
|
993
|
+
this.emit("network", currentNetwork, network);
|
994
|
+
yield stall(0);
|
995
|
+
return this._network;
|
996
|
+
}
|
997
|
+
const error = logger.makeError("underlying network changed", Logger.errors.NETWORK_ERROR, {
|
998
|
+
event: "changed",
|
999
|
+
network: network,
|
1000
|
+
detectedNetwork: currentNetwork
|
1001
|
+
});
|
1002
|
+
this.emit("error", error);
|
1003
|
+
throw error;
|
1004
|
+
}
|
1005
|
+
return network;
|
1006
|
+
});
|
1007
|
+
}
|
1008
|
+
get blockNumber() {
|
1009
|
+
this._getInternalBlockNumber(100 + this.pollingInterval / 2).then((blockNumber) => {
|
1010
|
+
this._setFastBlockNumber(blockNumber);
|
1011
|
+
}, (error) => { });
|
1012
|
+
return (this._fastBlockNumber != null) ? this._fastBlockNumber : -1;
|
1013
|
+
}
|
1014
|
+
get polling() {
|
1015
|
+
return (this._poller != null);
|
1016
|
+
}
|
1017
|
+
set polling(value) {
|
1018
|
+
if (value && !this._poller) {
|
1019
|
+
this._poller = setInterval(() => { this.poll(); }, this.pollingInterval);
|
1020
|
+
if (!this._bootstrapPoll) {
|
1021
|
+
this._bootstrapPoll = setTimeout(() => {
|
1022
|
+
this.poll();
|
1023
|
+
// We block additional polls until the polling interval
|
1024
|
+
// is done, to prevent overwhelming the poll function
|
1025
|
+
this._bootstrapPoll = setTimeout(() => {
|
1026
|
+
// If polling was disabled, something may require a poke
|
1027
|
+
// since starting the bootstrap poll and it was disabled
|
1028
|
+
if (!this._poller) {
|
1029
|
+
this.poll();
|
1030
|
+
}
|
1031
|
+
// Clear out the bootstrap so we can do another
|
1032
|
+
this._bootstrapPoll = null;
|
1033
|
+
}, this.pollingInterval);
|
1034
|
+
}, 0);
|
1035
|
+
}
|
1036
|
+
}
|
1037
|
+
else if (!value && this._poller) {
|
1038
|
+
clearInterval(this._poller);
|
1039
|
+
this._poller = null;
|
1040
|
+
}
|
1041
|
+
}
|
1042
|
+
get pollingInterval() {
|
1043
|
+
return this._pollingInterval;
|
1044
|
+
}
|
1045
|
+
set pollingInterval(value) {
|
1046
|
+
if (typeof (value) !== "number" || value <= 0 || parseInt(String(value)) != value) {
|
1047
|
+
throw new Error("invalid polling interval");
|
1048
|
+
}
|
1049
|
+
this._pollingInterval = value;
|
1050
|
+
if (this._poller) {
|
1051
|
+
clearInterval(this._poller);
|
1052
|
+
this._poller = setInterval(() => { this.poll(); }, this._pollingInterval);
|
1053
|
+
}
|
1054
|
+
}
|
1055
|
+
_getFastBlockNumber() {
|
1056
|
+
const now = getTime();
|
1057
|
+
// Stale block number, request a newer value
|
1058
|
+
if ((now - this._fastQueryDate) > 2 * this._pollingInterval) {
|
1059
|
+
this._fastQueryDate = now;
|
1060
|
+
this._fastBlockNumberPromise = this.getBlockNumber().then((blockNumber) => {
|
1061
|
+
if (this._fastBlockNumber == null || blockNumber > this._fastBlockNumber) {
|
1062
|
+
this._fastBlockNumber = blockNumber;
|
1063
|
+
}
|
1064
|
+
return this._fastBlockNumber;
|
1065
|
+
});
|
1066
|
+
}
|
1067
|
+
return this._fastBlockNumberPromise;
|
1068
|
+
}
|
1069
|
+
_setFastBlockNumber(blockNumber) {
|
1070
|
+
// Older block, maybe a stale request
|
1071
|
+
if (this._fastBlockNumber != null && blockNumber < this._fastBlockNumber) {
|
1072
|
+
return;
|
1073
|
+
}
|
1074
|
+
// Update the time we updated the blocknumber
|
1075
|
+
this._fastQueryDate = getTime();
|
1076
|
+
// Newer block number, use it
|
1077
|
+
if (this._fastBlockNumber == null || blockNumber > this._fastBlockNumber) {
|
1078
|
+
this._fastBlockNumber = blockNumber;
|
1079
|
+
this._fastBlockNumberPromise = Promise.resolve(blockNumber);
|
1080
|
+
}
|
1081
|
+
}
|
1082
|
+
waitForTransaction(transactionHash, confirmations, timeout) {
|
1083
|
+
return __awaiter(this, undefined, undefined, function* () {
|
1084
|
+
return this._waitForTransaction(transactionHash, (confirmations == null) ? 1 : confirmations, timeout || 0, null);
|
1085
|
+
});
|
1086
|
+
}
|
1087
|
+
_waitForTransaction(transactionHash, confirmations, timeout, replaceable) {
|
1088
|
+
return __awaiter(this, undefined, undefined, function* () {
|
1089
|
+
const receipt = yield this.getTransactionReceipt(transactionHash);
|
1090
|
+
// Receipt is already good
|
1091
|
+
if ((receipt ? receipt.confirmations : 0) >= confirmations) {
|
1092
|
+
return receipt;
|
1093
|
+
}
|
1094
|
+
// Poll until the receipt is good...
|
1095
|
+
return new Promise((resolve, reject) => {
|
1096
|
+
const cancelFuncs = [];
|
1097
|
+
let done = false;
|
1098
|
+
const alreadyDone = function () {
|
1099
|
+
if (done) {
|
1100
|
+
return true;
|
1101
|
+
}
|
1102
|
+
done = true;
|
1103
|
+
cancelFuncs.forEach((func) => { func(); });
|
1104
|
+
return false;
|
1105
|
+
};
|
1106
|
+
const minedHandler = (receipt) => {
|
1107
|
+
if (receipt.confirmations < confirmations) {
|
1108
|
+
return;
|
1109
|
+
}
|
1110
|
+
if (alreadyDone()) {
|
1111
|
+
return;
|
1112
|
+
}
|
1113
|
+
resolve(receipt);
|
1114
|
+
};
|
1115
|
+
this.on(transactionHash, minedHandler);
|
1116
|
+
cancelFuncs.push(() => { this.removeListener(transactionHash, minedHandler); });
|
1117
|
+
if (replaceable) {
|
1118
|
+
let lastBlockNumber = replaceable.startBlock;
|
1119
|
+
let scannedBlock = null;
|
1120
|
+
const replaceHandler = (blockNumber) => __awaiter(this, undefined, undefined, function* () {
|
1121
|
+
if (done) {
|
1122
|
+
return;
|
1123
|
+
}
|
1124
|
+
// Wait 1 second; this is only used in the case of a fault, so
|
1125
|
+
// we will trade off a little bit of latency for more consistent
|
1126
|
+
// results and fewer JSON-RPC calls
|
1127
|
+
yield stall(1000);
|
1128
|
+
this.getTransactionCount(replaceable.from).then((nonce) => __awaiter(this, undefined, undefined, function* () {
|
1129
|
+
if (done) {
|
1130
|
+
return;
|
1131
|
+
}
|
1132
|
+
if (nonce <= replaceable.nonce) {
|
1133
|
+
lastBlockNumber = blockNumber;
|
1134
|
+
}
|
1135
|
+
else {
|
1136
|
+
// First check if the transaction was mined
|
1137
|
+
{
|
1138
|
+
const mined = yield this.getTransaction(transactionHash);
|
1139
|
+
if (mined && mined.blockNumber != null) {
|
1140
|
+
return;
|
1141
|
+
}
|
1142
|
+
}
|
1143
|
+
// First time scanning. We start a little earlier for some
|
1144
|
+
// wiggle room here to handle the eventually consistent nature
|
1145
|
+
// of blockchain (e.g. the getTransactionCount was for a
|
1146
|
+
// different block)
|
1147
|
+
if (scannedBlock == null) {
|
1148
|
+
scannedBlock = lastBlockNumber - 3;
|
1149
|
+
if (scannedBlock < replaceable.startBlock) {
|
1150
|
+
scannedBlock = replaceable.startBlock;
|
1151
|
+
}
|
1152
|
+
}
|
1153
|
+
while (scannedBlock <= blockNumber) {
|
1154
|
+
if (done) {
|
1155
|
+
return;
|
1156
|
+
}
|
1157
|
+
const block = yield this.getBlockWithTransactions(scannedBlock);
|
1158
|
+
for (let ti = 0; ti < block.transactions.length; ti++) {
|
1159
|
+
const tx = block.transactions[ti];
|
1160
|
+
// Successfully mined!
|
1161
|
+
if (tx.hash === transactionHash) {
|
1162
|
+
return;
|
1163
|
+
}
|
1164
|
+
// Matches our transaction from and nonce; its a replacement
|
1165
|
+
if (tx.from === replaceable.from && tx.nonce === replaceable.nonce) {
|
1166
|
+
if (done) {
|
1167
|
+
return;
|
1168
|
+
}
|
1169
|
+
// Get the receipt of the replacement
|
1170
|
+
const receipt = yield this.waitForTransaction(tx.hash, confirmations);
|
1171
|
+
// Already resolved or rejected (prolly a timeout)
|
1172
|
+
if (alreadyDone()) {
|
1173
|
+
return;
|
1174
|
+
}
|
1175
|
+
// The reason we were replaced
|
1176
|
+
let reason = "replaced";
|
1177
|
+
if (tx.data === replaceable.data && tx.to === replaceable.to && tx.value.eq(replaceable.value)) {
|
1178
|
+
reason = "repriced";
|
1179
|
+
}
|
1180
|
+
else if (tx.data === "0x" && tx.from === tx.to && tx.value.isZero()) {
|
1181
|
+
reason = "cancelled";
|
1182
|
+
}
|
1183
|
+
// Explain why we were replaced
|
1184
|
+
reject(logger.makeError("transaction was replaced", Logger.errors.TRANSACTION_REPLACED, {
|
1185
|
+
cancelled: (reason === "replaced" || reason === "cancelled"),
|
1186
|
+
reason,
|
1187
|
+
replacement: this._wrapTransaction(tx),
|
1188
|
+
hash: transactionHash,
|
1189
|
+
receipt
|
1190
|
+
}));
|
1191
|
+
return;
|
1192
|
+
}
|
1193
|
+
}
|
1194
|
+
scannedBlock++;
|
1195
|
+
}
|
1196
|
+
}
|
1197
|
+
if (done) {
|
1198
|
+
return;
|
1199
|
+
}
|
1200
|
+
this.once("block", replaceHandler);
|
1201
|
+
}), (error) => {
|
1202
|
+
if (done) {
|
1203
|
+
return;
|
1204
|
+
}
|
1205
|
+
this.once("block", replaceHandler);
|
1206
|
+
});
|
1207
|
+
});
|
1208
|
+
if (done) {
|
1209
|
+
return;
|
1210
|
+
}
|
1211
|
+
this.once("block", replaceHandler);
|
1212
|
+
cancelFuncs.push(() => {
|
1213
|
+
this.removeListener("block", replaceHandler);
|
1214
|
+
});
|
1215
|
+
}
|
1216
|
+
if (typeof (timeout) === "number" && timeout > 0) {
|
1217
|
+
const timer = setTimeout(() => {
|
1218
|
+
if (alreadyDone()) {
|
1219
|
+
return;
|
1220
|
+
}
|
1221
|
+
reject(logger.makeError("timeout exceeded", Logger.errors.TIMEOUT, { timeout: timeout }));
|
1222
|
+
}, timeout);
|
1223
|
+
if (timer.unref) {
|
1224
|
+
timer.unref();
|
1225
|
+
}
|
1226
|
+
cancelFuncs.push(() => { clearTimeout(timer); });
|
1227
|
+
}
|
1228
|
+
});
|
1229
|
+
});
|
1230
|
+
}
|
1231
|
+
getBlockNumber() {
|
1232
|
+
return __awaiter(this, undefined, undefined, function* () {
|
1233
|
+
return this._getInternalBlockNumber(0);
|
1234
|
+
});
|
1235
|
+
}
|
1236
|
+
getGasPrice() {
|
1237
|
+
return __awaiter(this, undefined, undefined, function* () {
|
1238
|
+
yield this.getNetwork();
|
1239
|
+
const result = yield this.perform("getGasPrice", {});
|
1240
|
+
try {
|
1241
|
+
return BigNumber.from(result);
|
1242
|
+
}
|
1243
|
+
catch (error) {
|
1244
|
+
return logger.throwError("bad result from backend", Logger.errors.SERVER_ERROR, {
|
1245
|
+
method: "getGasPrice",
|
1246
|
+
result, error
|
1247
|
+
});
|
1248
|
+
}
|
1249
|
+
});
|
1250
|
+
}
|
1251
|
+
getBalance(addressOrName, blockTag) {
|
1252
|
+
return __awaiter(this, undefined, undefined, function* () {
|
1253
|
+
yield this.getNetwork();
|
1254
|
+
const params = yield resolveProperties({
|
1255
|
+
address: this._getAddress(addressOrName),
|
1256
|
+
blockTag: this._getBlockTag(blockTag)
|
1257
|
+
});
|
1258
|
+
const result = yield this.perform("getBalance", params);
|
1259
|
+
try {
|
1260
|
+
return BigNumber.from(result);
|
1261
|
+
}
|
1262
|
+
catch (error) {
|
1263
|
+
return logger.throwError("bad result from backend", Logger.errors.SERVER_ERROR, {
|
1264
|
+
method: "getBalance",
|
1265
|
+
params, result, error
|
1266
|
+
});
|
1267
|
+
}
|
1268
|
+
});
|
1269
|
+
}
|
1270
|
+
getTransactionCount(addressOrName, blockTag) {
|
1271
|
+
return __awaiter(this, undefined, undefined, function* () {
|
1272
|
+
yield this.getNetwork();
|
1273
|
+
const params = yield resolveProperties({
|
1274
|
+
address: this._getAddress(addressOrName),
|
1275
|
+
blockTag: this._getBlockTag(blockTag)
|
1276
|
+
});
|
1277
|
+
const result = yield this.perform("getTransactionCount", params);
|
1278
|
+
try {
|
1279
|
+
return BigNumber.from(result).toNumber();
|
1280
|
+
}
|
1281
|
+
catch (error) {
|
1282
|
+
return logger.throwError("bad result from backend", Logger.errors.SERVER_ERROR, {
|
1283
|
+
method: "getTransactionCount",
|
1284
|
+
params, result, error
|
1285
|
+
});
|
1286
|
+
}
|
1287
|
+
});
|
1288
|
+
}
|
1289
|
+
getCode(addressOrName, blockTag) {
|
1290
|
+
return __awaiter(this, undefined, undefined, function* () {
|
1291
|
+
yield this.getNetwork();
|
1292
|
+
const params = yield resolveProperties({
|
1293
|
+
address: this._getAddress(addressOrName),
|
1294
|
+
blockTag: this._getBlockTag(blockTag)
|
1295
|
+
});
|
1296
|
+
const result = yield this.perform("getCode", params);
|
1297
|
+
try {
|
1298
|
+
return hexlify(result);
|
1299
|
+
}
|
1300
|
+
catch (error) {
|
1301
|
+
return logger.throwError("bad result from backend", Logger.errors.SERVER_ERROR, {
|
1302
|
+
method: "getCode",
|
1303
|
+
params, result, error
|
1304
|
+
});
|
1305
|
+
}
|
1306
|
+
});
|
1307
|
+
}
|
1308
|
+
getStorageAt(addressOrName, position, blockTag) {
|
1309
|
+
return __awaiter(this, undefined, undefined, function* () {
|
1310
|
+
yield this.getNetwork();
|
1311
|
+
const params = yield resolveProperties({
|
1312
|
+
address: this._getAddress(addressOrName),
|
1313
|
+
blockTag: this._getBlockTag(blockTag),
|
1314
|
+
position: Promise.resolve(position).then((p) => hexValue(p))
|
1315
|
+
});
|
1316
|
+
const result = yield this.perform("getStorageAt", params);
|
1317
|
+
try {
|
1318
|
+
return hexlify(result);
|
1319
|
+
}
|
1320
|
+
catch (error) {
|
1321
|
+
return logger.throwError("bad result from backend", Logger.errors.SERVER_ERROR, {
|
1322
|
+
method: "getStorageAt",
|
1323
|
+
params, result, error
|
1324
|
+
});
|
1325
|
+
}
|
1326
|
+
});
|
1327
|
+
}
|
1328
|
+
// This should be called by any subclass wrapping a TransactionResponse
|
1329
|
+
_wrapTransaction(tx, hash, startBlock) {
|
1330
|
+
if (hash != null && hexDataLength(hash) !== 32) {
|
1331
|
+
throw new Error("invalid response - sendTransaction");
|
1332
|
+
}
|
1333
|
+
const result = tx;
|
1334
|
+
// Check the hash we expect is the same as the hash the server reported
|
1335
|
+
if (hash != null && tx.hash !== hash) {
|
1336
|
+
logger.throwError("Transaction hash mismatch from Provider.sendTransaction.", Logger.errors.UNKNOWN_ERROR, { expectedHash: tx.hash, returnedHash: hash });
|
1337
|
+
}
|
1338
|
+
result.wait = (confirms, timeout) => __awaiter(this, undefined, undefined, function* () {
|
1339
|
+
if (confirms == null) {
|
1340
|
+
confirms = 1;
|
1341
|
+
}
|
1342
|
+
if (timeout == null) {
|
1343
|
+
timeout = 0;
|
1344
|
+
}
|
1345
|
+
// Get the details to detect replacement
|
1346
|
+
let replacement = undefined;
|
1347
|
+
if (confirms !== 0 && startBlock != null) {
|
1348
|
+
replacement = {
|
1349
|
+
data: tx.data,
|
1350
|
+
from: tx.from,
|
1351
|
+
nonce: tx.nonce,
|
1352
|
+
to: tx.to,
|
1353
|
+
value: tx.value,
|
1354
|
+
startBlock
|
1355
|
+
};
|
1356
|
+
}
|
1357
|
+
const receipt = yield this._waitForTransaction(tx.hash, confirms, timeout, replacement);
|
1358
|
+
if (receipt == null && confirms === 0) {
|
1359
|
+
return null;
|
1360
|
+
}
|
1361
|
+
// No longer pending, allow the polling loop to garbage collect this
|
1362
|
+
this._emitted["t:" + tx.hash] = receipt.blockNumber;
|
1363
|
+
if (receipt.status === 0) {
|
1364
|
+
logger.throwError("transaction failed", Logger.errors.CALL_EXCEPTION, {
|
1365
|
+
transactionHash: tx.hash,
|
1366
|
+
transaction: tx,
|
1367
|
+
receipt: receipt
|
1368
|
+
});
|
1369
|
+
}
|
1370
|
+
return receipt;
|
1371
|
+
});
|
1372
|
+
return result;
|
1373
|
+
}
|
1374
|
+
sendTransaction(signedTransaction) {
|
1375
|
+
return __awaiter(this, undefined, undefined, function* () {
|
1376
|
+
yield this.getNetwork();
|
1377
|
+
const hexTx = yield Promise.resolve(signedTransaction).then(t => hexlify(t));
|
1378
|
+
const tx = this.formatter.transaction(signedTransaction);
|
1379
|
+
if (tx.confirmations == null) {
|
1380
|
+
tx.confirmations = 0;
|
1381
|
+
}
|
1382
|
+
const blockNumber = yield this._getInternalBlockNumber(100 + 2 * this.pollingInterval);
|
1383
|
+
try {
|
1384
|
+
const hash = yield this.perform("sendTransaction", { signedTransaction: hexTx });
|
1385
|
+
return this._wrapTransaction(tx, hash, blockNumber);
|
1386
|
+
}
|
1387
|
+
catch (error) {
|
1388
|
+
error.transaction = tx;
|
1389
|
+
error.transactionHash = tx.hash;
|
1390
|
+
throw error;
|
1391
|
+
}
|
1392
|
+
});
|
1393
|
+
}
|
1394
|
+
_getTransactionRequest(transaction) {
|
1395
|
+
return __awaiter(this, undefined, undefined, function* () {
|
1396
|
+
const values = yield transaction;
|
1397
|
+
const tx = {};
|
1398
|
+
["from", "to"].forEach((key) => {
|
1399
|
+
if (values[key] == null) {
|
1400
|
+
return;
|
1401
|
+
}
|
1402
|
+
tx[key] = Promise.resolve(values[key]).then((v) => (v ? this._getAddress(v) : null));
|
1403
|
+
});
|
1404
|
+
["gasLimit", "gasPrice", "maxFeePerGas", "maxPriorityFeePerGas", "value"].forEach((key) => {
|
1405
|
+
if (values[key] == null) {
|
1406
|
+
return;
|
1407
|
+
}
|
1408
|
+
tx[key] = Promise.resolve(values[key]).then((v) => (v ? BigNumber.from(v) : null));
|
1409
|
+
});
|
1410
|
+
["type"].forEach((key) => {
|
1411
|
+
if (values[key] == null) {
|
1412
|
+
return;
|
1413
|
+
}
|
1414
|
+
tx[key] = Promise.resolve(values[key]).then((v) => ((v != null) ? v : null));
|
1415
|
+
});
|
1416
|
+
if (values.accessList) {
|
1417
|
+
tx.accessList = this.formatter.accessList(values.accessList);
|
1418
|
+
}
|
1419
|
+
["data"].forEach((key) => {
|
1420
|
+
if (values[key] == null) {
|
1421
|
+
return;
|
1422
|
+
}
|
1423
|
+
tx[key] = Promise.resolve(values[key]).then((v) => (v ? hexlify(v) : null));
|
1424
|
+
});
|
1425
|
+
return this.formatter.transactionRequest(yield resolveProperties(tx));
|
1426
|
+
});
|
1427
|
+
}
|
1428
|
+
_getFilter(filter) {
|
1429
|
+
return __awaiter(this, undefined, undefined, function* () {
|
1430
|
+
filter = yield filter;
|
1431
|
+
const result = {};
|
1432
|
+
if (filter.address != null) {
|
1433
|
+
result.address = this._getAddress(filter.address);
|
1434
|
+
}
|
1435
|
+
["blockHash", "topics"].forEach((key) => {
|
1436
|
+
if (filter[key] == null) {
|
1437
|
+
return;
|
1438
|
+
}
|
1439
|
+
result[key] = filter[key];
|
1440
|
+
});
|
1441
|
+
["fromBlock", "toBlock"].forEach((key) => {
|
1442
|
+
if (filter[key] == null) {
|
1443
|
+
return;
|
1444
|
+
}
|
1445
|
+
result[key] = this._getBlockTag(filter[key]);
|
1446
|
+
});
|
1447
|
+
return this.formatter.filter(yield resolveProperties(result));
|
1448
|
+
});
|
1449
|
+
}
|
1450
|
+
_call(transaction, blockTag, attempt) {
|
1451
|
+
return __awaiter(this, undefined, undefined, function* () {
|
1452
|
+
if (attempt >= MAX_CCIP_REDIRECTS) {
|
1453
|
+
logger.throwError("CCIP read exceeded maximum redirections", Logger.errors.SERVER_ERROR, {
|
1454
|
+
redirects: attempt, transaction
|
1455
|
+
});
|
1456
|
+
}
|
1457
|
+
const txSender = transaction.to;
|
1458
|
+
const result = yield this.perform("call", { transaction, blockTag });
|
1459
|
+
// CCIP Read request via OffchainLookup(address,string[],bytes,bytes4,bytes)
|
1460
|
+
if (attempt >= 0 && blockTag === "latest" && txSender != null && result.substring(0, 10) === "0x556f1830" && (hexDataLength(result) % 32 === 4)) {
|
1461
|
+
try {
|
1462
|
+
const data = hexDataSlice(result, 4);
|
1463
|
+
// Check the sender of the OffchainLookup matches the transaction
|
1464
|
+
const sender = hexDataSlice(data, 0, 32);
|
1465
|
+
if (!BigNumber.from(sender).eq(txSender)) {
|
1466
|
+
logger.throwError("CCIP Read sender did not match", Logger.errors.CALL_EXCEPTION, {
|
1467
|
+
name: "OffchainLookup",
|
1468
|
+
signature: "OffchainLookup(address,string[],bytes,bytes4,bytes)",
|
1469
|
+
transaction, data: result
|
1470
|
+
});
|
1471
|
+
}
|
1472
|
+
// Read the URLs from the response
|
1473
|
+
const urls = [];
|
1474
|
+
const urlsOffset = BigNumber.from(hexDataSlice(data, 32, 64)).toNumber();
|
1475
|
+
const urlsLength = BigNumber.from(hexDataSlice(data, urlsOffset, urlsOffset + 32)).toNumber();
|
1476
|
+
const urlsData = hexDataSlice(data, urlsOffset + 32);
|
1477
|
+
for (let u = 0; u < urlsLength; u++) {
|
1478
|
+
const url = _parseString(urlsData, u * 32);
|
1479
|
+
if (url == null) {
|
1480
|
+
logger.throwError("CCIP Read contained corrupt URL string", Logger.errors.CALL_EXCEPTION, {
|
1481
|
+
name: "OffchainLookup",
|
1482
|
+
signature: "OffchainLookup(address,string[],bytes,bytes4,bytes)",
|
1483
|
+
transaction, data: result
|
1484
|
+
});
|
1485
|
+
}
|
1486
|
+
urls.push(url);
|
1487
|
+
}
|
1488
|
+
// Get the CCIP calldata to forward
|
1489
|
+
const calldata = _parseBytes(data, 64);
|
1490
|
+
// Get the callbackSelector (bytes4)
|
1491
|
+
if (!BigNumber.from(hexDataSlice(data, 100, 128)).isZero()) {
|
1492
|
+
logger.throwError("CCIP Read callback selector included junk", Logger.errors.CALL_EXCEPTION, {
|
1493
|
+
name: "OffchainLookup",
|
1494
|
+
signature: "OffchainLookup(address,string[],bytes,bytes4,bytes)",
|
1495
|
+
transaction, data: result
|
1496
|
+
});
|
1497
|
+
}
|
1498
|
+
const callbackSelector = hexDataSlice(data, 96, 100);
|
1499
|
+
// Get the extra data to send back to the contract as context
|
1500
|
+
const extraData = _parseBytes(data, 128);
|
1501
|
+
const ccipResult = yield this.ccipReadFetch(transaction, calldata, urls);
|
1502
|
+
if (ccipResult == null) {
|
1503
|
+
logger.throwError("CCIP Read disabled or provided no URLs", Logger.errors.CALL_EXCEPTION, {
|
1504
|
+
name: "OffchainLookup",
|
1505
|
+
signature: "OffchainLookup(address,string[],bytes,bytes4,bytes)",
|
1506
|
+
transaction, data: result
|
1507
|
+
});
|
1508
|
+
}
|
1509
|
+
const tx = {
|
1510
|
+
to: txSender,
|
1511
|
+
data: hexConcat([callbackSelector, encodeBytes([ccipResult, extraData])])
|
1512
|
+
};
|
1513
|
+
return this._call(tx, blockTag, attempt + 1);
|
1514
|
+
}
|
1515
|
+
catch (error) {
|
1516
|
+
if (error.code === Logger.errors.SERVER_ERROR) {
|
1517
|
+
throw error;
|
1518
|
+
}
|
1519
|
+
}
|
1520
|
+
}
|
1521
|
+
try {
|
1522
|
+
return hexlify(result);
|
1523
|
+
}
|
1524
|
+
catch (error) {
|
1525
|
+
return logger.throwError("bad result from backend", Logger.errors.SERVER_ERROR, {
|
1526
|
+
method: "call",
|
1527
|
+
params: { transaction, blockTag }, result, error
|
1528
|
+
});
|
1529
|
+
}
|
1530
|
+
});
|
1531
|
+
}
|
1532
|
+
call(transaction, blockTag) {
|
1533
|
+
return __awaiter(this, undefined, undefined, function* () {
|
1534
|
+
yield this.getNetwork();
|
1535
|
+
const resolved = yield resolveProperties({
|
1536
|
+
transaction: this._getTransactionRequest(transaction),
|
1537
|
+
blockTag: this._getBlockTag(blockTag),
|
1538
|
+
ccipReadEnabled: Promise.resolve(transaction.ccipReadEnabled)
|
1539
|
+
});
|
1540
|
+
return this._call(resolved.transaction, resolved.blockTag, resolved.ccipReadEnabled ? 0 : -1);
|
1541
|
+
});
|
1542
|
+
}
|
1543
|
+
estimateGas(transaction) {
|
1544
|
+
return __awaiter(this, undefined, undefined, function* () {
|
1545
|
+
yield this.getNetwork();
|
1546
|
+
const params = yield resolveProperties({
|
1547
|
+
transaction: this._getTransactionRequest(transaction)
|
1548
|
+
});
|
1549
|
+
const result = yield this.perform("estimateGas", params);
|
1550
|
+
try {
|
1551
|
+
return BigNumber.from(result);
|
1552
|
+
}
|
1553
|
+
catch (error) {
|
1554
|
+
return logger.throwError("bad result from backend", Logger.errors.SERVER_ERROR, {
|
1555
|
+
method: "estimateGas",
|
1556
|
+
params, result, error
|
1557
|
+
});
|
1558
|
+
}
|
1559
|
+
});
|
1560
|
+
}
|
1561
|
+
_getAddress(addressOrName) {
|
1562
|
+
return __awaiter(this, undefined, undefined, function* () {
|
1563
|
+
addressOrName = yield addressOrName;
|
1564
|
+
if (typeof (addressOrName) !== "string") {
|
1565
|
+
logger.throwArgumentError("invalid address or ENS name", "name", addressOrName);
|
1566
|
+
}
|
1567
|
+
const address = yield this.resolveName(addressOrName);
|
1568
|
+
if (address == null) {
|
1569
|
+
logger.throwError("ENS name not configured", Logger.errors.UNSUPPORTED_OPERATION, {
|
1570
|
+
operation: `resolveName(${JSON.stringify(addressOrName)})`
|
1571
|
+
});
|
1572
|
+
}
|
1573
|
+
return address;
|
1574
|
+
});
|
1575
|
+
}
|
1576
|
+
_getBlock(blockHashOrBlockTag, includeTransactions) {
|
1577
|
+
return __awaiter(this, undefined, undefined, function* () {
|
1578
|
+
yield this.getNetwork();
|
1579
|
+
blockHashOrBlockTag = yield blockHashOrBlockTag;
|
1580
|
+
// If blockTag is a number (not "latest", etc), this is the block number
|
1581
|
+
let blockNumber = -128;
|
1582
|
+
const params = {
|
1583
|
+
includeTransactions: !!includeTransactions
|
1584
|
+
};
|
1585
|
+
if (isHexString(blockHashOrBlockTag, 32)) {
|
1586
|
+
params.blockHash = blockHashOrBlockTag;
|
1587
|
+
}
|
1588
|
+
else {
|
1589
|
+
try {
|
1590
|
+
params.blockTag = yield this._getBlockTag(blockHashOrBlockTag);
|
1591
|
+
if (isHexString(params.blockTag)) {
|
1592
|
+
blockNumber = parseInt(params.blockTag.substring(2), 16);
|
1593
|
+
}
|
1594
|
+
}
|
1595
|
+
catch (error) {
|
1596
|
+
logger.throwArgumentError("invalid block hash or block tag", "blockHashOrBlockTag", blockHashOrBlockTag);
|
1597
|
+
}
|
1598
|
+
}
|
1599
|
+
return poll(() => __awaiter(this, undefined, undefined, function* () {
|
1600
|
+
const block = yield this.perform("getBlock", params);
|
1601
|
+
// Block was not found
|
1602
|
+
if (block == null) {
|
1603
|
+
// For blockhashes, if we didn't say it existed, that blockhash may
|
1604
|
+
// not exist. If we did see it though, perhaps from a log, we know
|
1605
|
+
// it exists, and this node is just not caught up yet.
|
1606
|
+
if (params.blockHash != null) {
|
1607
|
+
if (this._emitted["b:" + params.blockHash] == null) {
|
1608
|
+
return null;
|
1609
|
+
}
|
1610
|
+
}
|
1611
|
+
// For block tags, if we are asking for a future block, we return null
|
1612
|
+
if (params.blockTag != null) {
|
1613
|
+
if (blockNumber > this._emitted.block) {
|
1614
|
+
return null;
|
1615
|
+
}
|
1616
|
+
}
|
1617
|
+
// Retry on the next block
|
1618
|
+
return undefined;
|
1619
|
+
}
|
1620
|
+
// Add transactions
|
1621
|
+
if (includeTransactions) {
|
1622
|
+
let blockNumber = null;
|
1623
|
+
for (let i = 0; i < block.transactions.length; i++) {
|
1624
|
+
const tx = block.transactions[i];
|
1625
|
+
if (tx.blockNumber == null) {
|
1626
|
+
tx.confirmations = 0;
|
1627
|
+
}
|
1628
|
+
else if (tx.confirmations == null) {
|
1629
|
+
if (blockNumber == null) {
|
1630
|
+
blockNumber = yield this._getInternalBlockNumber(100 + 2 * this.pollingInterval);
|
1631
|
+
}
|
1632
|
+
// Add the confirmations using the fast block number (pessimistic)
|
1633
|
+
let confirmations = (blockNumber - tx.blockNumber) + 1;
|
1634
|
+
if (confirmations <= 0) {
|
1635
|
+
confirmations = 1;
|
1636
|
+
}
|
1637
|
+
tx.confirmations = confirmations;
|
1638
|
+
}
|
1639
|
+
}
|
1640
|
+
const blockWithTxs = this.formatter.blockWithTransactions(block);
|
1641
|
+
blockWithTxs.transactions = blockWithTxs.transactions.map((tx) => this._wrapTransaction(tx));
|
1642
|
+
return blockWithTxs;
|
1643
|
+
}
|
1644
|
+
return this.formatter.block(block);
|
1645
|
+
}), { oncePoll: this });
|
1646
|
+
});
|
1647
|
+
}
|
1648
|
+
getBlock(blockHashOrBlockTag) {
|
1649
|
+
return (this._getBlock(blockHashOrBlockTag, false));
|
1650
|
+
}
|
1651
|
+
getBlockWithTransactions(blockHashOrBlockTag) {
|
1652
|
+
return (this._getBlock(blockHashOrBlockTag, true));
|
1653
|
+
}
|
1654
|
+
getTransaction(transactionHash) {
|
1655
|
+
return __awaiter(this, undefined, undefined, function* () {
|
1656
|
+
yield this.getNetwork();
|
1657
|
+
transactionHash = yield transactionHash;
|
1658
|
+
const params = { transactionHash: this.formatter.hash(transactionHash, true) };
|
1659
|
+
return poll(() => __awaiter(this, undefined, undefined, function* () {
|
1660
|
+
const result = yield this.perform("getTransaction", params);
|
1661
|
+
if (result == null) {
|
1662
|
+
if (this._emitted["t:" + transactionHash] == null) {
|
1663
|
+
return null;
|
1664
|
+
}
|
1665
|
+
return undefined;
|
1666
|
+
}
|
1667
|
+
const tx = this.formatter.transactionResponse(result);
|
1668
|
+
if (tx.blockNumber == null) {
|
1669
|
+
tx.confirmations = 0;
|
1670
|
+
}
|
1671
|
+
else if (tx.confirmations == null) {
|
1672
|
+
const blockNumber = yield this._getInternalBlockNumber(100 + 2 * this.pollingInterval);
|
1673
|
+
// Add the confirmations using the fast block number (pessimistic)
|
1674
|
+
let confirmations = (blockNumber - tx.blockNumber) + 1;
|
1675
|
+
if (confirmations <= 0) {
|
1676
|
+
confirmations = 1;
|
1677
|
+
}
|
1678
|
+
tx.confirmations = confirmations;
|
1679
|
+
}
|
1680
|
+
return this._wrapTransaction(tx);
|
1681
|
+
}), { oncePoll: this });
|
1682
|
+
});
|
1683
|
+
}
|
1684
|
+
getTransactionReceipt(transactionHash) {
|
1685
|
+
return __awaiter(this, undefined, undefined, function* () {
|
1686
|
+
yield this.getNetwork();
|
1687
|
+
transactionHash = yield transactionHash;
|
1688
|
+
const params = { transactionHash: this.formatter.hash(transactionHash, true) };
|
1689
|
+
return poll(() => __awaiter(this, undefined, undefined, function* () {
|
1690
|
+
const result = yield this.perform("getTransactionReceipt", params);
|
1691
|
+
if (result == null) {
|
1692
|
+
if (this._emitted["t:" + transactionHash] == null) {
|
1693
|
+
return null;
|
1694
|
+
}
|
1695
|
+
return undefined;
|
1696
|
+
}
|
1697
|
+
// "geth-etc" returns receipts before they are ready
|
1698
|
+
if (result.blockHash == null) {
|
1699
|
+
return undefined;
|
1700
|
+
}
|
1701
|
+
const receipt = this.formatter.receipt(result);
|
1702
|
+
if (receipt.blockNumber == null) {
|
1703
|
+
receipt.confirmations = 0;
|
1704
|
+
}
|
1705
|
+
else if (receipt.confirmations == null) {
|
1706
|
+
const blockNumber = yield this._getInternalBlockNumber(100 + 2 * this.pollingInterval);
|
1707
|
+
// Add the confirmations using the fast block number (pessimistic)
|
1708
|
+
let confirmations = (blockNumber - receipt.blockNumber) + 1;
|
1709
|
+
if (confirmations <= 0) {
|
1710
|
+
confirmations = 1;
|
1711
|
+
}
|
1712
|
+
receipt.confirmations = confirmations;
|
1713
|
+
}
|
1714
|
+
return receipt;
|
1715
|
+
}), { oncePoll: this });
|
1716
|
+
});
|
1717
|
+
}
|
1718
|
+
getLogs(filter) {
|
1719
|
+
return __awaiter(this, undefined, undefined, function* () {
|
1720
|
+
yield this.getNetwork();
|
1721
|
+
const params = yield resolveProperties({ filter: this._getFilter(filter) });
|
1722
|
+
const logs = yield this.perform("getLogs", params);
|
1723
|
+
logs.forEach((log) => {
|
1724
|
+
if (log.removed == null) {
|
1725
|
+
log.removed = false;
|
1726
|
+
}
|
1727
|
+
});
|
1728
|
+
return Formatter.arrayOf(this.formatter.filterLog.bind(this.formatter))(logs);
|
1729
|
+
});
|
1730
|
+
}
|
1731
|
+
getEtherPrice() {
|
1732
|
+
return __awaiter(this, undefined, undefined, function* () {
|
1733
|
+
yield this.getNetwork();
|
1734
|
+
return this.perform("getEtherPrice", {});
|
1735
|
+
});
|
1736
|
+
}
|
1737
|
+
_getBlockTag(blockTag) {
|
1738
|
+
return __awaiter(this, undefined, undefined, function* () {
|
1739
|
+
blockTag = yield blockTag;
|
1740
|
+
if (typeof (blockTag) === "number" && blockTag < 0) {
|
1741
|
+
if (blockTag % 1) {
|
1742
|
+
logger.throwArgumentError("invalid BlockTag", "blockTag", blockTag);
|
1743
|
+
}
|
1744
|
+
let blockNumber = yield this._getInternalBlockNumber(100 + 2 * this.pollingInterval);
|
1745
|
+
blockNumber += blockTag;
|
1746
|
+
if (blockNumber < 0) {
|
1747
|
+
blockNumber = 0;
|
1748
|
+
}
|
1749
|
+
return this.formatter.blockTag(blockNumber);
|
1750
|
+
}
|
1751
|
+
return this.formatter.blockTag(blockTag);
|
1752
|
+
});
|
1753
|
+
}
|
1754
|
+
getResolver(name) {
|
1755
|
+
return __awaiter(this, undefined, undefined, function* () {
|
1756
|
+
let currentName = name;
|
1757
|
+
while (true) {
|
1758
|
+
if (currentName === "" || currentName === ".") {
|
1759
|
+
return null;
|
1760
|
+
}
|
1761
|
+
// Optimization since the eth node cannot change and does
|
1762
|
+
// not have a wildcard resolver
|
1763
|
+
if (name !== "eth" && currentName === "eth") {
|
1764
|
+
return null;
|
1765
|
+
}
|
1766
|
+
// Check the current node for a resolver
|
1767
|
+
const addr = yield this._getResolver(currentName, "getResolver");
|
1768
|
+
// Found a resolver!
|
1769
|
+
if (addr != null) {
|
1770
|
+
const resolver = new Resolver(this, addr, name);
|
1771
|
+
// Legacy resolver found, using EIP-2544 so it isn't safe to use
|
1772
|
+
if (currentName !== name && !(yield resolver.supportsWildcard())) {
|
1773
|
+
return null;
|
1774
|
+
}
|
1775
|
+
return resolver;
|
1776
|
+
}
|
1777
|
+
// Get the parent node
|
1778
|
+
currentName = currentName.split(".").slice(1).join(".");
|
1779
|
+
}
|
1780
|
+
});
|
1781
|
+
}
|
1782
|
+
_getResolver(name, operation) {
|
1783
|
+
return __awaiter(this, undefined, undefined, function* () {
|
1784
|
+
if (operation == null) {
|
1785
|
+
operation = "ENS";
|
1786
|
+
}
|
1787
|
+
const network = yield this.getNetwork();
|
1788
|
+
// No ENS...
|
1789
|
+
if (!network.ensAddress) {
|
1790
|
+
logger.throwError("network does not support ENS", Logger.errors.UNSUPPORTED_OPERATION, { operation, network: network.name });
|
1791
|
+
}
|
1792
|
+
try {
|
1793
|
+
// keccak256("resolver(bytes32)")
|
1794
|
+
const addrData = yield this.call({
|
1795
|
+
to: network.ensAddress,
|
1796
|
+
data: ("0x0178b8bf" + namehash(name).substring(2))
|
1797
|
+
});
|
1798
|
+
return this.formatter.callAddress(addrData);
|
1799
|
+
}
|
1800
|
+
catch (error) {
|
1801
|
+
// ENS registry cannot throw errors on resolver(bytes32)
|
1802
|
+
}
|
1803
|
+
return null;
|
1804
|
+
});
|
1805
|
+
}
|
1806
|
+
resolveName(name) {
|
1807
|
+
return __awaiter(this, undefined, undefined, function* () {
|
1808
|
+
name = yield name;
|
1809
|
+
// If it is already an address, nothing to resolve
|
1810
|
+
try {
|
1811
|
+
return Promise.resolve(this.formatter.address(name));
|
1812
|
+
}
|
1813
|
+
catch (error) {
|
1814
|
+
// If is is a hexstring, the address is bad (See #694)
|
1815
|
+
if (isHexString(name)) {
|
1816
|
+
throw error;
|
1817
|
+
}
|
1818
|
+
}
|
1819
|
+
if (typeof (name) !== "string") {
|
1820
|
+
logger.throwArgumentError("invalid ENS name", "name", name);
|
1821
|
+
}
|
1822
|
+
// Get the addr from the resolver
|
1823
|
+
const resolver = yield this.getResolver(name);
|
1824
|
+
if (!resolver) {
|
1825
|
+
return null;
|
1826
|
+
}
|
1827
|
+
return yield resolver.getAddress();
|
1828
|
+
});
|
1829
|
+
}
|
1830
|
+
lookupAddress(address) {
|
1831
|
+
return __awaiter(this, undefined, undefined, function* () {
|
1832
|
+
address = yield address;
|
1833
|
+
address = this.formatter.address(address);
|
1834
|
+
const node = address.substring(2).toLowerCase() + ".addr.reverse";
|
1835
|
+
const resolverAddr = yield this._getResolver(node, "lookupAddress");
|
1836
|
+
if (resolverAddr == null) {
|
1837
|
+
return null;
|
1838
|
+
}
|
1839
|
+
// keccak("name(bytes32)")
|
1840
|
+
const name = _parseString(yield this.call({
|
1841
|
+
to: resolverAddr,
|
1842
|
+
data: ("0x691f3431" + namehash(node).substring(2))
|
1843
|
+
}), 0);
|
1844
|
+
const addr = yield this.resolveName(name);
|
1845
|
+
if (addr != address) {
|
1846
|
+
return null;
|
1847
|
+
}
|
1848
|
+
return name;
|
1849
|
+
});
|
1850
|
+
}
|
1851
|
+
getAvatar(nameOrAddress) {
|
1852
|
+
return __awaiter(this, undefined, undefined, function* () {
|
1853
|
+
let resolver = null;
|
1854
|
+
if (isHexString(nameOrAddress)) {
|
1855
|
+
// Address; reverse lookup
|
1856
|
+
const address = this.formatter.address(nameOrAddress);
|
1857
|
+
const node = address.substring(2).toLowerCase() + ".addr.reverse";
|
1858
|
+
const resolverAddress = yield this._getResolver(node, "getAvatar");
|
1859
|
+
if (!resolverAddress) {
|
1860
|
+
return null;
|
1861
|
+
}
|
1862
|
+
// Try resolving the avatar against the addr.reverse resolver
|
1863
|
+
resolver = new Resolver(this, resolverAddress, node);
|
1864
|
+
try {
|
1865
|
+
const avatar = yield resolver.getAvatar();
|
1866
|
+
if (avatar) {
|
1867
|
+
return avatar.url;
|
1868
|
+
}
|
1869
|
+
}
|
1870
|
+
catch (error) {
|
1871
|
+
if (error.code !== Logger.errors.CALL_EXCEPTION) {
|
1872
|
+
throw error;
|
1873
|
+
}
|
1874
|
+
}
|
1875
|
+
// Try getting the name and performing forward lookup; allowing wildcards
|
1876
|
+
try {
|
1877
|
+
// keccak("name(bytes32)")
|
1878
|
+
const name = _parseString(yield this.call({
|
1879
|
+
to: resolverAddress,
|
1880
|
+
data: ("0x691f3431" + namehash(node).substring(2))
|
1881
|
+
}), 0);
|
1882
|
+
resolver = yield this.getResolver(name);
|
1883
|
+
}
|
1884
|
+
catch (error) {
|
1885
|
+
if (error.code !== Logger.errors.CALL_EXCEPTION) {
|
1886
|
+
throw error;
|
1887
|
+
}
|
1888
|
+
return null;
|
1889
|
+
}
|
1890
|
+
}
|
1891
|
+
else {
|
1892
|
+
// ENS name; forward lookup with wildcard
|
1893
|
+
resolver = yield this.getResolver(nameOrAddress);
|
1894
|
+
if (!resolver) {
|
1895
|
+
return null;
|
1896
|
+
}
|
1897
|
+
}
|
1898
|
+
const avatar = yield resolver.getAvatar();
|
1899
|
+
if (avatar == null) {
|
1900
|
+
return null;
|
1901
|
+
}
|
1902
|
+
return avatar.url;
|
1903
|
+
});
|
1904
|
+
}
|
1905
|
+
perform(method, params) {
|
1906
|
+
return logger.throwError(method + " not implemented", Logger.errors.NOT_IMPLEMENTED, { operation: method });
|
1907
|
+
}
|
1908
|
+
_startEvent(event) {
|
1909
|
+
this.polling = (this._events.filter((e) => e.pollable()).length > 0);
|
1910
|
+
}
|
1911
|
+
_stopEvent(event) {
|
1912
|
+
this.polling = (this._events.filter((e) => e.pollable()).length > 0);
|
1913
|
+
}
|
1914
|
+
_addEventListener(eventName, listener, once) {
|
1915
|
+
const event = new Event(getEventTag(eventName), listener, once);
|
1916
|
+
this._events.push(event);
|
1917
|
+
this._startEvent(event);
|
1918
|
+
return this;
|
1919
|
+
}
|
1920
|
+
on(eventName, listener) {
|
1921
|
+
return this._addEventListener(eventName, listener, false);
|
1922
|
+
}
|
1923
|
+
once(eventName, listener) {
|
1924
|
+
return this._addEventListener(eventName, listener, true);
|
1925
|
+
}
|
1926
|
+
emit(eventName, ...args) {
|
1927
|
+
let result = false;
|
1928
|
+
let stopped = [];
|
1929
|
+
let eventTag = getEventTag(eventName);
|
1930
|
+
this._events = this._events.filter((event) => {
|
1931
|
+
if (event.tag !== eventTag) {
|
1932
|
+
return true;
|
1933
|
+
}
|
1934
|
+
setTimeout(() => {
|
1935
|
+
event.listener.apply(this, args);
|
1936
|
+
}, 0);
|
1937
|
+
result = true;
|
1938
|
+
if (event.once) {
|
1939
|
+
stopped.push(event);
|
1940
|
+
return false;
|
1941
|
+
}
|
1942
|
+
return true;
|
1943
|
+
});
|
1944
|
+
stopped.forEach((event) => { this._stopEvent(event); });
|
1945
|
+
return result;
|
1946
|
+
}
|
1947
|
+
listenerCount(eventName) {
|
1948
|
+
if (!eventName) {
|
1949
|
+
return this._events.length;
|
1950
|
+
}
|
1951
|
+
let eventTag = getEventTag(eventName);
|
1952
|
+
return this._events.filter((event) => {
|
1953
|
+
return (event.tag === eventTag);
|
1954
|
+
}).length;
|
1955
|
+
}
|
1956
|
+
listeners(eventName) {
|
1957
|
+
if (eventName == null) {
|
1958
|
+
return this._events.map((event) => event.listener);
|
1959
|
+
}
|
1960
|
+
let eventTag = getEventTag(eventName);
|
1961
|
+
return this._events
|
1962
|
+
.filter((event) => (event.tag === eventTag))
|
1963
|
+
.map((event) => event.listener);
|
1964
|
+
}
|
1965
|
+
off(eventName, listener) {
|
1966
|
+
if (listener == null) {
|
1967
|
+
return this.removeAllListeners(eventName);
|
1968
|
+
}
|
1969
|
+
const stopped = [];
|
1970
|
+
let found = false;
|
1971
|
+
let eventTag = getEventTag(eventName);
|
1972
|
+
this._events = this._events.filter((event) => {
|
1973
|
+
if (event.tag !== eventTag || event.listener != listener) {
|
1974
|
+
return true;
|
1975
|
+
}
|
1976
|
+
if (found) {
|
1977
|
+
return true;
|
1978
|
+
}
|
1979
|
+
found = true;
|
1980
|
+
stopped.push(event);
|
1981
|
+
return false;
|
1982
|
+
});
|
1983
|
+
stopped.forEach((event) => { this._stopEvent(event); });
|
1984
|
+
return this;
|
1985
|
+
}
|
1986
|
+
removeAllListeners(eventName) {
|
1987
|
+
let stopped = [];
|
1988
|
+
if (eventName == null) {
|
1989
|
+
stopped = this._events;
|
1990
|
+
this._events = [];
|
1991
|
+
}
|
1992
|
+
else {
|
1993
|
+
const eventTag = getEventTag(eventName);
|
1994
|
+
this._events = this._events.filter((event) => {
|
1995
|
+
if (event.tag !== eventTag) {
|
1996
|
+
return true;
|
1997
|
+
}
|
1998
|
+
stopped.push(event);
|
1999
|
+
return false;
|
2000
|
+
});
|
2001
|
+
}
|
2002
|
+
stopped.forEach((event) => { this._stopEvent(event); });
|
2003
|
+
return this;
|
2004
|
+
}
|
2005
|
+
}
|
2006
|
+
|
2007
|
+
export { BaseProvider, Event, Resolver };
|