@multiplatform.one/web3 7.26.0 → 7.28.1
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 +157 -8
- package/dist/cjs/bridge/base58.cjs +48 -0
- package/dist/cjs/bridge/base58.native.js +51 -0
- package/dist/cjs/bridge/base58.native.js.map +1 -0
- package/dist/cjs/bridge/core.cjs +5 -1
- package/dist/cjs/bridge/core.native.js +5 -1
- package/dist/cjs/bridge/core.native.js.map +1 -1
- package/dist/cjs/bridge/drivers.cjs +141 -0
- package/dist/cjs/bridge/drivers.native.js +161 -0
- package/dist/cjs/bridge/drivers.native.js.map +1 -0
- package/dist/cjs/bridge/nativeHost.cjs +49 -9
- package/dist/cjs/bridge/nativeHost.native.js +56 -9
- package/dist/cjs/bridge/nativeHost.native.js.map +1 -1
- package/dist/cjs/clients/adapter.native.js.map +1 -1
- package/dist/cjs/clients/connector.native.js.map +1 -1
- package/dist/cjs/clients/evm.cjs +1 -0
- package/dist/cjs/clients/evm.native.js +1 -0
- package/dist/cjs/clients/evm.native.js.map +1 -1
- package/dist/cjs/clients/evmRead.cjs +104 -0
- package/dist/cjs/clients/evmRead.native.js +124 -0
- package/dist/cjs/clients/evmRead.native.js.map +1 -0
- package/dist/cjs/clients/hooks.cjs +37 -7
- package/dist/cjs/clients/hooks.native.js +43 -5
- package/dist/cjs/clients/hooks.native.js.map +1 -1
- package/dist/cjs/clients/index.cjs +5 -0
- package/dist/cjs/clients/index.native.js +5 -0
- package/dist/cjs/clients/index.native.js.map +1 -1
- package/dist/cjs/clients/types.cjs +7 -0
- package/dist/cjs/clients/types.native.js +14 -0
- package/dist/cjs/clients/types.native.js.map +1 -1
- package/dist/cjs/connectkit/adapters/BitcoinAdapter.cjs +44 -2
- package/dist/cjs/connectkit/adapters/BitcoinAdapter.native.js +73 -5
- package/dist/cjs/connectkit/adapters/BitcoinAdapter.native.js.map +1 -1
- package/dist/cjs/connectkit/adapters/SolanaAdapter.cjs +46 -0
- package/dist/cjs/connectkit/adapters/SolanaAdapter.native.js +55 -0
- package/dist/cjs/connectkit/adapters/SolanaAdapter.native.js.map +1 -1
- package/dist/cjs/connectkit/adapters/SuiAdapter.cjs +40 -0
- package/dist/cjs/connectkit/adapters/SuiAdapter.native.js +50 -0
- package/dist/cjs/connectkit/adapters/SuiAdapter.native.js.map +1 -1
- package/dist/cjs/connectkit/connectors/ensureWalletConnectors.cjs +4 -1
- package/dist/cjs/connectkit/connectors/ensureWalletConnectors.native.js +8 -1
- package/dist/cjs/connectkit/connectors/ensureWalletConnectors.native.js.map +1 -1
- package/dist/cjs/connectkit/connectors/getWalletConnectors.native.js.map +1 -1
- package/dist/cjs/connectkit/connectors/syntheticChains.native.js.map +1 -1
- package/dist/cjs/connectkit/connectors/walletAdapterConnector.native.js.map +1 -1
- package/dist/cjs/connectkit/defaultConfig.cjs +5 -2
- package/dist/cjs/connectkit/defaultConfig.native.js +9 -2
- package/dist/cjs/connectkit/defaultConfig.native.js.map +1 -1
- package/dist/cjs/connectkit/siwe/SIWEContext.native.js.map +1 -1
- package/dist/cjs/connectkit/siwe/SIWEProvider.cjs +6 -4
- package/dist/cjs/connectkit/siwe/SIWEProvider.native.js +8 -4
- package/dist/cjs/connectkit/siwe/SIWEProvider.native.js.map +1 -1
- package/dist/cjs/connectkit/siwe/connectIntent.cjs +56 -16
- package/dist/cjs/connectkit/siwe/connectIntent.native.js +100 -16
- package/dist/cjs/connectkit/siwe/connectIntent.native.js.map +1 -1
- package/dist/cjs/connectkit/siwe/useSIWE.native.js.map +1 -1
- package/dist/cjs/connectkit/web3Bridge.cjs +58 -12
- package/dist/cjs/connectkit/web3Bridge.native.js +64 -14
- package/dist/cjs/connectkit/web3Bridge.native.js.map +1 -1
- package/dist/cjs/core/family.cjs +17 -0
- package/dist/cjs/core/family.native.js +17 -0
- package/dist/cjs/core/family.native.js.map +1 -1
- package/dist/cjs/core/index.cjs +10 -1
- package/dist/cjs/core/index.native.js +10 -1
- package/dist/cjs/core/index.native.js.map +1 -1
- package/dist/cjs/core/lightDriver.cjs +182 -0
- package/dist/cjs/core/lightDriver.native.js +260 -0
- package/dist/cjs/core/lightDriver.native.js.map +1 -0
- package/dist/cjs/core/react.cjs +12 -1
- package/dist/cjs/core/react.native.js +16 -1
- package/dist/cjs/core/react.native.js.map +1 -1
- package/dist/cjs/core/signIn.cjs +201 -0
- package/dist/cjs/core/signIn.native.js +240 -0
- package/dist/cjs/core/signIn.native.js.map +1 -0
- package/dist/cjs/core/store.cjs +47 -2
- package/dist/cjs/core/store.native.js +49 -2
- package/dist/cjs/core/store.native.js.map +1 -1
- package/dist/cjs/families/btc.cjs +44 -0
- package/dist/cjs/families/btc.native.js +49 -0
- package/dist/cjs/families/btc.native.js.map +1 -0
- package/dist/cjs/families/eth.cjs +57 -0
- package/dist/cjs/families/eth.native.js +61 -0
- package/dist/cjs/families/eth.native.js.map +1 -0
- package/dist/cjs/families/gpg.cjs +40 -0
- package/dist/cjs/families/gpg.native.js +43 -0
- package/dist/cjs/families/gpg.native.js.map +1 -0
- package/dist/cjs/families/host.cjs +38 -0
- package/dist/cjs/families/host.native.js +41 -0
- package/dist/cjs/families/host.native.js.map +1 -0
- package/dist/cjs/families/index.cjs +53 -0
- package/dist/cjs/families/index.native.js +56 -0
- package/dist/cjs/families/index.native.js.map +1 -0
- package/dist/cjs/families/messages.cjs +61 -0
- package/dist/cjs/families/messages.native.js +66 -0
- package/dist/cjs/families/messages.native.js.map +1 -0
- package/dist/cjs/families/sol.cjs +55 -0
- package/dist/cjs/families/sol.native.js +64 -0
- package/dist/cjs/families/sol.native.js.map +1 -0
- package/dist/cjs/families/sui.cjs +48 -0
- package/dist/cjs/families/sui.native.js +53 -0
- package/dist/cjs/families/sui.native.js.map +1 -0
- package/dist/cjs/index.cjs +22 -2
- package/dist/cjs/index.native.js +21 -1
- package/dist/cjs/index.native.js.map +1 -1
- package/dist/cjs/keycloak/keycloakWallet.cjs +13 -0
- package/dist/cjs/keycloak/keycloakWallet.native.js +15 -0
- package/dist/cjs/keycloak/keycloakWallet.native.js.map +1 -1
- package/dist/cjs/keycloak/useDirectLogin.cjs +10 -5
- package/dist/cjs/keycloak/useDirectLogin.native.js +12 -5
- package/dist/cjs/keycloak/useDirectLogin.native.js.map +1 -1
- package/dist/cjs/keycloak/useWalletLogin.cjs +16 -8
- package/dist/cjs/light/drivers.cjs +73 -0
- package/dist/cjs/light/drivers.native.js +97 -0
- package/dist/cjs/light/drivers.native.js.map +1 -0
- package/dist/cjs/light/index.cjs +30 -0
- package/dist/cjs/light/index.native.js +33 -0
- package/dist/cjs/light/index.native.js.map +1 -0
- package/dist/cjs/providers/WalletProvider.cjs +59 -17
- package/dist/cjs/providers/WalletProvider.native.js +99 -56
- package/dist/cjs/providers/WalletProvider.native.js.map +1 -1
- package/dist/cjs/providers/families.cjs +53 -0
- package/dist/cjs/providers/families.native.js +59 -0
- package/dist/cjs/providers/families.native.js.map +1 -0
- package/dist/cjs/providers/index.cjs +1 -0
- package/dist/cjs/providers/index.native.js +1 -0
- package/dist/cjs/providers/index.native.js.map +1 -1
- package/dist/cjs/providers/walletConfig.cjs +41 -0
- package/dist/cjs/providers/walletConfig.native.js +68 -0
- package/dist/cjs/providers/walletConfig.native.js.map +1 -1
- package/dist/cjs/wagmi/driver.cjs +257 -0
- package/dist/cjs/wagmi/driver.native.js +331 -0
- package/dist/cjs/wagmi/driver.native.js.map +1 -0
- package/dist/cjs/wagmi/host.cjs +239 -0
- package/dist/cjs/wagmi/host.native.js +320 -0
- package/dist/cjs/wagmi/host.native.js.map +1 -0
- package/dist/cjs/wagmi/index.cjs +28 -0
- package/dist/cjs/wagmi/index.native.js +31 -0
- package/dist/cjs/wagmi/index.native.js.map +1 -0
- package/dist/cjs/web.cjs +84 -0
- package/dist/esm/bridge/base58.mjs +23 -0
- package/dist/esm/bridge/base58.mjs.map +1 -0
- package/dist/esm/bridge/base58.native.js +23 -0
- package/dist/esm/bridge/base58.native.js.map +1 -0
- package/dist/esm/bridge/core.mjs +3 -2
- package/dist/esm/bridge/core.mjs.map +1 -1
- package/dist/esm/bridge/core.native.js +3 -2
- package/dist/esm/bridge/core.native.js.map +1 -1
- package/dist/esm/bridge/drivers.mjs +113 -0
- package/dist/esm/bridge/drivers.mjs.map +1 -0
- package/dist/esm/bridge/drivers.native.js +130 -0
- package/dist/esm/bridge/drivers.native.js.map +1 -0
- package/dist/esm/bridge/nativeHost.mjs +50 -11
- package/dist/esm/bridge/nativeHost.mjs.map +1 -1
- package/dist/esm/bridge/nativeHost.native.js +57 -11
- package/dist/esm/bridge/nativeHost.native.js.map +1 -1
- package/dist/esm/clients/adapter.mjs.map +1 -1
- package/dist/esm/clients/adapter.native.js.map +1 -1
- package/dist/esm/clients/connector.mjs.map +1 -1
- package/dist/esm/clients/connector.native.js.map +1 -1
- package/dist/esm/clients/evm.mjs +1 -0
- package/dist/esm/clients/evm.mjs.map +1 -1
- package/dist/esm/clients/evm.native.js +1 -0
- package/dist/esm/clients/evm.native.js.map +1 -1
- package/dist/esm/clients/evmRead.mjs +78 -0
- package/dist/esm/clients/evmRead.mjs.map +1 -0
- package/dist/esm/clients/evmRead.native.js +95 -0
- package/dist/esm/clients/evmRead.native.js.map +1 -0
- package/dist/esm/clients/hooks.mjs +38 -9
- package/dist/esm/clients/hooks.mjs.map +1 -1
- package/dist/esm/clients/hooks.native.js +44 -7
- package/dist/esm/clients/hooks.native.js.map +1 -1
- package/dist/esm/clients/index.mjs +4 -3
- package/dist/esm/clients/index.mjs.map +1 -1
- package/dist/esm/clients/index.native.js +4 -3
- package/dist/esm/clients/index.native.js.map +1 -1
- package/dist/esm/clients/types.mjs +7 -1
- package/dist/esm/clients/types.mjs.map +1 -1
- package/dist/esm/clients/types.native.js +14 -1
- package/dist/esm/clients/types.native.js.map +1 -1
- package/dist/esm/connectkit/adapters/BitcoinAdapter.mjs +44 -2
- package/dist/esm/connectkit/adapters/BitcoinAdapter.mjs.map +1 -1
- package/dist/esm/connectkit/adapters/BitcoinAdapter.native.js +73 -5
- package/dist/esm/connectkit/adapters/BitcoinAdapter.native.js.map +1 -1
- package/dist/esm/connectkit/adapters/SolanaAdapter.mjs +46 -0
- package/dist/esm/connectkit/adapters/SolanaAdapter.mjs.map +1 -1
- package/dist/esm/connectkit/adapters/SolanaAdapter.native.js +55 -0
- package/dist/esm/connectkit/adapters/SolanaAdapter.native.js.map +1 -1
- package/dist/esm/connectkit/adapters/SuiAdapter.mjs +40 -0
- package/dist/esm/connectkit/adapters/SuiAdapter.mjs.map +1 -1
- package/dist/esm/connectkit/adapters/SuiAdapter.native.js +50 -0
- package/dist/esm/connectkit/adapters/SuiAdapter.native.js.map +1 -1
- package/dist/esm/connectkit/connectors/ensureWalletConnectors.mjs +4 -1
- package/dist/esm/connectkit/connectors/ensureWalletConnectors.mjs.map +1 -1
- package/dist/esm/connectkit/connectors/ensureWalletConnectors.native.js +8 -1
- package/dist/esm/connectkit/connectors/ensureWalletConnectors.native.js.map +1 -1
- package/dist/esm/connectkit/connectors/getWalletConnectors.mjs.map +1 -1
- package/dist/esm/connectkit/connectors/getWalletConnectors.native.js.map +1 -1
- package/dist/esm/connectkit/connectors/syntheticChains.mjs.map +1 -1
- package/dist/esm/connectkit/connectors/syntheticChains.native.js.map +1 -1
- package/dist/esm/connectkit/connectors/walletAdapterConnector.mjs.map +1 -1
- package/dist/esm/connectkit/connectors/walletAdapterConnector.native.js.map +1 -1
- package/dist/esm/connectkit/defaultConfig.mjs +6 -3
- package/dist/esm/connectkit/defaultConfig.mjs.map +1 -1
- package/dist/esm/connectkit/defaultConfig.native.js +10 -3
- package/dist/esm/connectkit/defaultConfig.native.js.map +1 -1
- package/dist/esm/connectkit/siwe/SIWEContext.mjs.map +1 -1
- package/dist/esm/connectkit/siwe/SIWEContext.native.js.map +1 -1
- package/dist/esm/connectkit/siwe/SIWEProvider.mjs +6 -4
- package/dist/esm/connectkit/siwe/SIWEProvider.mjs.map +1 -1
- package/dist/esm/connectkit/siwe/SIWEProvider.native.js +8 -4
- package/dist/esm/connectkit/siwe/SIWEProvider.native.js.map +1 -1
- package/dist/esm/connectkit/siwe/connectIntent.mjs +54 -16
- package/dist/esm/connectkit/siwe/connectIntent.mjs.map +1 -1
- package/dist/esm/connectkit/siwe/connectIntent.native.js +98 -16
- package/dist/esm/connectkit/siwe/connectIntent.native.js.map +1 -1
- package/dist/esm/connectkit/siwe/useSIWE.mjs.map +1 -1
- package/dist/esm/connectkit/siwe/useSIWE.native.js.map +1 -1
- package/dist/esm/connectkit/web3Bridge.mjs +61 -16
- package/dist/esm/connectkit/web3Bridge.mjs.map +1 -1
- package/dist/esm/connectkit/web3Bridge.native.js +67 -18
- package/dist/esm/connectkit/web3Bridge.native.js.map +1 -1
- package/dist/esm/core/family.mjs +17 -0
- package/dist/esm/core/family.mjs.map +1 -1
- package/dist/esm/core/family.native.js +17 -0
- package/dist/esm/core/family.native.js.map +1 -1
- package/dist/esm/core/index.mjs +5 -3
- package/dist/esm/core/index.mjs.map +1 -1
- package/dist/esm/core/index.native.js +5 -3
- package/dist/esm/core/index.native.js.map +1 -1
- package/dist/esm/core/lightDriver.mjs +157 -0
- package/dist/esm/core/lightDriver.mjs.map +1 -0
- package/dist/esm/core/lightDriver.native.js +232 -0
- package/dist/esm/core/lightDriver.native.js.map +1 -0
- package/dist/esm/core/react.mjs +10 -1
- package/dist/esm/core/react.mjs.map +1 -1
- package/dist/esm/core/react.native.js +14 -1
- package/dist/esm/core/react.native.js.map +1 -1
- package/dist/esm/core/signIn.mjs +173 -0
- package/dist/esm/core/signIn.mjs.map +1 -0
- package/dist/esm/core/signIn.native.js +209 -0
- package/dist/esm/core/signIn.native.js.map +1 -0
- package/dist/esm/core/store.mjs +47 -2
- package/dist/esm/core/store.mjs.map +1 -1
- package/dist/esm/core/store.native.js +49 -2
- package/dist/esm/core/store.native.js.map +1 -1
- package/dist/esm/families/btc.mjs +19 -0
- package/dist/esm/families/btc.mjs.map +1 -0
- package/dist/esm/families/btc.native.js +21 -0
- package/dist/esm/families/btc.native.js.map +1 -0
- package/dist/esm/families/eth.mjs +32 -0
- package/dist/esm/families/eth.mjs.map +1 -0
- package/dist/esm/families/eth.native.js +33 -0
- package/dist/esm/families/eth.native.js.map +1 -0
- package/dist/esm/families/gpg.mjs +15 -0
- package/dist/esm/families/gpg.mjs.map +1 -0
- package/dist/esm/families/gpg.native.js +15 -0
- package/dist/esm/families/gpg.native.js.map +1 -0
- package/dist/esm/families/host.mjs +12 -0
- package/dist/esm/families/host.mjs.map +1 -0
- package/dist/esm/families/host.native.js +12 -0
- package/dist/esm/families/host.native.js.map +1 -0
- package/dist/esm/families/index.mjs +23 -0
- package/dist/esm/families/index.mjs.map +1 -0
- package/dist/esm/families/index.native.js +23 -0
- package/dist/esm/families/index.native.js.map +1 -0
- package/dist/esm/families/messages.mjs +32 -0
- package/dist/esm/families/messages.mjs.map +1 -0
- package/dist/esm/families/messages.native.js +34 -0
- package/dist/esm/families/messages.native.js.map +1 -0
- package/dist/esm/families/sol.mjs +30 -0
- package/dist/esm/families/sol.mjs.map +1 -0
- package/dist/esm/families/sol.native.js +36 -0
- package/dist/esm/families/sol.native.js.map +1 -0
- package/dist/esm/families/sui.mjs +23 -0
- package/dist/esm/families/sui.mjs.map +1 -0
- package/dist/esm/families/sui.native.js +25 -0
- package/dist/esm/families/sui.native.js.map +1 -0
- package/dist/esm/index.mjs +6 -3
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/index.native.js +6 -3
- package/dist/esm/index.native.js.map +1 -1
- package/dist/esm/keycloak/keycloakWallet.mjs +13 -0
- package/dist/esm/keycloak/keycloakWallet.mjs.map +1 -1
- package/dist/esm/keycloak/keycloakWallet.native.js +15 -0
- package/dist/esm/keycloak/keycloakWallet.native.js.map +1 -1
- package/dist/esm/keycloak/useDirectLogin.mjs +10 -5
- package/dist/esm/keycloak/useDirectLogin.mjs.map +1 -1
- package/dist/esm/keycloak/useDirectLogin.native.js +12 -5
- package/dist/esm/keycloak/useDirectLogin.native.js.map +1 -1
- package/dist/esm/keycloak/useWalletLogin.mjs +16 -8
- package/dist/esm/keycloak/useWalletLogin.mjs.map +1 -1
- package/dist/esm/light/drivers.mjs +46 -0
- package/dist/esm/light/drivers.mjs.map +1 -0
- package/dist/esm/light/drivers.native.js +67 -0
- package/dist/esm/light/drivers.native.js.map +1 -0
- package/dist/esm/light/index.mjs +3 -0
- package/dist/esm/light/index.mjs.map +1 -0
- package/dist/esm/light/index.native.js +3 -0
- package/dist/esm/light/index.native.js.map +1 -0
- package/dist/esm/providers/WalletProvider.mjs +60 -19
- package/dist/esm/providers/WalletProvider.mjs.map +1 -1
- package/dist/esm/providers/WalletProvider.native.js +101 -59
- package/dist/esm/providers/WalletProvider.native.js.map +1 -1
- package/dist/esm/providers/families.mjs +27 -0
- package/dist/esm/providers/families.mjs.map +1 -0
- package/dist/esm/providers/families.native.js +30 -0
- package/dist/esm/providers/families.native.js.map +1 -0
- package/dist/esm/providers/index.mjs +2 -2
- package/dist/esm/providers/index.mjs.map +1 -1
- package/dist/esm/providers/index.native.js +2 -2
- package/dist/esm/providers/index.native.js.map +1 -1
- package/dist/esm/providers/walletConfig.mjs +40 -1
- package/dist/esm/providers/walletConfig.mjs.map +1 -1
- package/dist/esm/providers/walletConfig.native.js +67 -1
- package/dist/esm/providers/walletConfig.native.js.map +1 -1
- package/dist/esm/wagmi/driver.mjs +232 -0
- package/dist/esm/wagmi/driver.mjs.map +1 -0
- package/dist/esm/wagmi/driver.native.js +303 -0
- package/dist/esm/wagmi/driver.native.js.map +1 -0
- package/dist/esm/wagmi/host.mjs +213 -0
- package/dist/esm/wagmi/host.mjs.map +1 -0
- package/dist/esm/wagmi/host.native.js +291 -0
- package/dist/esm/wagmi/host.native.js.map +1 -0
- package/dist/esm/wagmi/index.mjs +3 -0
- package/dist/esm/wagmi/index.mjs.map +1 -0
- package/dist/esm/wagmi/index.native.js +3 -0
- package/dist/esm/wagmi/index.native.js.map +1 -0
- package/dist/esm/web.mjs +13 -0
- package/dist/esm/web.mjs.map +1 -0
- package/dist/jsx/bridge/base58.mjs +23 -0
- package/dist/jsx/bridge/base58.mjs.map +1 -0
- package/dist/jsx/bridge/base58.native.js +51 -0
- package/dist/jsx/bridge/base58.native.js.map +1 -0
- package/dist/jsx/bridge/core.mjs +3 -2
- package/dist/jsx/bridge/core.mjs.map +1 -1
- package/dist/jsx/bridge/core.native.js +5 -1
- package/dist/jsx/bridge/core.native.js.map +1 -1
- package/dist/jsx/bridge/drivers.mjs +113 -0
- package/dist/jsx/bridge/drivers.mjs.map +1 -0
- package/dist/jsx/bridge/drivers.native.js +161 -0
- package/dist/jsx/bridge/drivers.native.js.map +1 -0
- package/dist/jsx/bridge/nativeHost.mjs +50 -11
- package/dist/jsx/bridge/nativeHost.mjs.map +1 -1
- package/dist/jsx/bridge/nativeHost.native.js +56 -9
- package/dist/jsx/bridge/nativeHost.native.js.map +1 -1
- package/dist/jsx/clients/adapter.mjs.map +1 -1
- package/dist/jsx/clients/adapter.native.js.map +1 -1
- package/dist/jsx/clients/connector.mjs.map +1 -1
- package/dist/jsx/clients/connector.native.js.map +1 -1
- package/dist/jsx/clients/evm.mjs +1 -0
- package/dist/jsx/clients/evm.mjs.map +1 -1
- package/dist/jsx/clients/evm.native.js +1 -0
- package/dist/jsx/clients/evm.native.js.map +1 -1
- package/dist/jsx/clients/evmRead.mjs +78 -0
- package/dist/jsx/clients/evmRead.mjs.map +1 -0
- package/dist/jsx/clients/evmRead.native.js +124 -0
- package/dist/jsx/clients/evmRead.native.js.map +1 -0
- package/dist/jsx/clients/hooks.mjs +38 -9
- package/dist/jsx/clients/hooks.mjs.map +1 -1
- package/dist/jsx/clients/hooks.native.js +43 -5
- package/dist/jsx/clients/hooks.native.js.map +1 -1
- package/dist/jsx/clients/index.mjs +4 -3
- package/dist/jsx/clients/index.mjs.map +1 -1
- package/dist/jsx/clients/index.native.js +5 -0
- package/dist/jsx/clients/index.native.js.map +1 -1
- package/dist/jsx/clients/types.mjs +7 -1
- package/dist/jsx/clients/types.mjs.map +1 -1
- package/dist/jsx/clients/types.native.js +14 -0
- package/dist/jsx/clients/types.native.js.map +1 -1
- package/dist/jsx/connectkit/adapters/BitcoinAdapter.mjs +44 -2
- package/dist/jsx/connectkit/adapters/BitcoinAdapter.mjs.map +1 -1
- package/dist/jsx/connectkit/adapters/BitcoinAdapter.native.js +73 -5
- package/dist/jsx/connectkit/adapters/BitcoinAdapter.native.js.map +1 -1
- package/dist/jsx/connectkit/adapters/SolanaAdapter.mjs +46 -0
- package/dist/jsx/connectkit/adapters/SolanaAdapter.mjs.map +1 -1
- package/dist/jsx/connectkit/adapters/SolanaAdapter.native.js +55 -0
- package/dist/jsx/connectkit/adapters/SolanaAdapter.native.js.map +1 -1
- package/dist/jsx/connectkit/adapters/SuiAdapter.mjs +40 -0
- package/dist/jsx/connectkit/adapters/SuiAdapter.mjs.map +1 -1
- package/dist/jsx/connectkit/adapters/SuiAdapter.native.js +50 -0
- package/dist/jsx/connectkit/adapters/SuiAdapter.native.js.map +1 -1
- package/dist/jsx/connectkit/connectors/ensureWalletConnectors.mjs +4 -1
- package/dist/jsx/connectkit/connectors/ensureWalletConnectors.mjs.map +1 -1
- package/dist/jsx/connectkit/connectors/ensureWalletConnectors.native.js +8 -1
- package/dist/jsx/connectkit/connectors/ensureWalletConnectors.native.js.map +1 -1
- package/dist/jsx/connectkit/connectors/getWalletConnectors.mjs.map +1 -1
- package/dist/jsx/connectkit/connectors/getWalletConnectors.native.js.map +1 -1
- package/dist/jsx/connectkit/connectors/syntheticChains.mjs.map +1 -1
- package/dist/jsx/connectkit/connectors/syntheticChains.native.js.map +1 -1
- package/dist/jsx/connectkit/connectors/walletAdapterConnector.mjs.map +1 -1
- package/dist/jsx/connectkit/connectors/walletAdapterConnector.native.js.map +1 -1
- package/dist/jsx/connectkit/defaultConfig.mjs +6 -3
- package/dist/jsx/connectkit/defaultConfig.mjs.map +1 -1
- package/dist/jsx/connectkit/defaultConfig.native.js +9 -2
- package/dist/jsx/connectkit/defaultConfig.native.js.map +1 -1
- package/dist/jsx/connectkit/siwe/SIWEContext.mjs.map +1 -1
- package/dist/jsx/connectkit/siwe/SIWEContext.native.js.map +1 -1
- package/dist/jsx/connectkit/siwe/SIWEProvider.mjs +6 -4
- package/dist/jsx/connectkit/siwe/SIWEProvider.mjs.map +1 -1
- package/dist/jsx/connectkit/siwe/SIWEProvider.native.js +8 -4
- package/dist/jsx/connectkit/siwe/SIWEProvider.native.js.map +1 -1
- package/dist/jsx/connectkit/siwe/connectIntent.mjs +54 -16
- package/dist/jsx/connectkit/siwe/connectIntent.mjs.map +1 -1
- package/dist/jsx/connectkit/siwe/connectIntent.native.js +100 -16
- package/dist/jsx/connectkit/siwe/connectIntent.native.js.map +1 -1
- package/dist/jsx/connectkit/siwe/useSIWE.mjs.map +1 -1
- package/dist/jsx/connectkit/siwe/useSIWE.native.js.map +1 -1
- package/dist/jsx/connectkit/web3Bridge.mjs +61 -16
- package/dist/jsx/connectkit/web3Bridge.mjs.map +1 -1
- package/dist/jsx/connectkit/web3Bridge.native.js +64 -14
- package/dist/jsx/connectkit/web3Bridge.native.js.map +1 -1
- package/dist/jsx/core/family.mjs +17 -0
- package/dist/jsx/core/family.mjs.map +1 -1
- package/dist/jsx/core/family.native.js +17 -0
- package/dist/jsx/core/family.native.js.map +1 -1
- package/dist/jsx/core/index.mjs +5 -3
- package/dist/jsx/core/index.mjs.map +1 -1
- package/dist/jsx/core/index.native.js +10 -1
- package/dist/jsx/core/index.native.js.map +1 -1
- package/dist/jsx/core/lightDriver.mjs +157 -0
- package/dist/jsx/core/lightDriver.mjs.map +1 -0
- package/dist/jsx/core/lightDriver.native.js +260 -0
- package/dist/jsx/core/lightDriver.native.js.map +1 -0
- package/dist/jsx/core/react.mjs +10 -1
- package/dist/jsx/core/react.mjs.map +1 -1
- package/dist/jsx/core/react.native.js +16 -1
- package/dist/jsx/core/react.native.js.map +1 -1
- package/dist/jsx/core/signIn.mjs +173 -0
- package/dist/jsx/core/signIn.mjs.map +1 -0
- package/dist/jsx/core/signIn.native.js +240 -0
- package/dist/jsx/core/signIn.native.js.map +1 -0
- package/dist/jsx/core/store.mjs +47 -2
- package/dist/jsx/core/store.mjs.map +1 -1
- package/dist/jsx/core/store.native.js +49 -2
- package/dist/jsx/core/store.native.js.map +1 -1
- package/dist/jsx/families/btc.mjs +19 -0
- package/dist/jsx/families/btc.mjs.map +1 -0
- package/dist/jsx/families/btc.native.js +49 -0
- package/dist/jsx/families/btc.native.js.map +1 -0
- package/dist/jsx/families/eth.mjs +32 -0
- package/dist/jsx/families/eth.mjs.map +1 -0
- package/dist/jsx/families/eth.native.js +61 -0
- package/dist/jsx/families/eth.native.js.map +1 -0
- package/dist/jsx/families/gpg.mjs +15 -0
- package/dist/jsx/families/gpg.mjs.map +1 -0
- package/dist/jsx/families/gpg.native.js +43 -0
- package/dist/jsx/families/gpg.native.js.map +1 -0
- package/dist/jsx/families/host.mjs +12 -0
- package/dist/jsx/families/host.mjs.map +1 -0
- package/dist/jsx/families/host.native.js +41 -0
- package/dist/jsx/families/host.native.js.map +1 -0
- package/dist/jsx/families/index.mjs +23 -0
- package/dist/jsx/families/index.mjs.map +1 -0
- package/dist/jsx/families/index.native.js +56 -0
- package/dist/jsx/families/index.native.js.map +1 -0
- package/dist/jsx/families/messages.mjs +32 -0
- package/dist/jsx/families/messages.mjs.map +1 -0
- package/dist/jsx/families/messages.native.js +66 -0
- package/dist/jsx/families/messages.native.js.map +1 -0
- package/dist/jsx/families/sol.mjs +30 -0
- package/dist/jsx/families/sol.mjs.map +1 -0
- package/dist/jsx/families/sol.native.js +64 -0
- package/dist/jsx/families/sol.native.js.map +1 -0
- package/dist/jsx/families/sui.mjs +23 -0
- package/dist/jsx/families/sui.mjs.map +1 -0
- package/dist/jsx/families/sui.native.js +53 -0
- package/dist/jsx/families/sui.native.js.map +1 -0
- package/dist/jsx/index.js +6 -3
- package/dist/jsx/index.js.map +1 -1
- package/dist/jsx/index.mjs +6 -3
- package/dist/jsx/index.mjs.map +1 -1
- package/dist/jsx/index.native.js +21 -1
- package/dist/jsx/index.native.js.map +1 -1
- package/dist/jsx/keycloak/keycloakWallet.mjs +13 -0
- package/dist/jsx/keycloak/keycloakWallet.mjs.map +1 -1
- package/dist/jsx/keycloak/keycloakWallet.native.js +15 -0
- package/dist/jsx/keycloak/keycloakWallet.native.js.map +1 -1
- package/dist/jsx/keycloak/useDirectLogin.mjs +10 -5
- package/dist/jsx/keycloak/useDirectLogin.mjs.map +1 -1
- package/dist/jsx/keycloak/useDirectLogin.native.js +12 -5
- package/dist/jsx/keycloak/useDirectLogin.native.js.map +1 -1
- package/dist/jsx/keycloak/useWalletLogin.mjs +16 -8
- package/dist/jsx/keycloak/useWalletLogin.mjs.map +1 -1
- package/dist/jsx/light/drivers.mjs +46 -0
- package/dist/jsx/light/drivers.mjs.map +1 -0
- package/dist/jsx/light/drivers.native.js +97 -0
- package/dist/jsx/light/drivers.native.js.map +1 -0
- package/dist/jsx/light/index.mjs +3 -0
- package/dist/jsx/light/index.mjs.map +1 -0
- package/dist/jsx/light/index.native.js +33 -0
- package/dist/jsx/light/index.native.js.map +1 -0
- package/dist/jsx/providers/WalletProvider.mjs +60 -19
- package/dist/jsx/providers/WalletProvider.mjs.map +1 -1
- package/dist/jsx/providers/WalletProvider.native.js +99 -56
- package/dist/jsx/providers/WalletProvider.native.js.map +1 -1
- package/dist/jsx/providers/families.mjs +27 -0
- package/dist/jsx/providers/families.mjs.map +1 -0
- package/dist/jsx/providers/families.native.js +59 -0
- package/dist/jsx/providers/families.native.js.map +1 -0
- package/dist/jsx/providers/index.mjs +2 -2
- package/dist/jsx/providers/index.mjs.map +1 -1
- package/dist/jsx/providers/index.native.js +1 -0
- package/dist/jsx/providers/index.native.js.map +1 -1
- package/dist/jsx/providers/walletConfig.mjs +40 -1
- package/dist/jsx/providers/walletConfig.mjs.map +1 -1
- package/dist/jsx/providers/walletConfig.native.js +68 -0
- package/dist/jsx/providers/walletConfig.native.js.map +1 -1
- package/dist/jsx/wagmi/driver.mjs +232 -0
- package/dist/jsx/wagmi/driver.mjs.map +1 -0
- package/dist/jsx/wagmi/driver.native.js +331 -0
- package/dist/jsx/wagmi/driver.native.js.map +1 -0
- package/dist/jsx/wagmi/host.mjs +213 -0
- package/dist/jsx/wagmi/host.mjs.map +1 -0
- package/dist/jsx/wagmi/host.native.js +320 -0
- package/dist/jsx/wagmi/host.native.js.map +1 -0
- package/dist/jsx/wagmi/index.mjs +3 -0
- package/dist/jsx/wagmi/index.mjs.map +1 -0
- package/dist/jsx/wagmi/index.native.js +31 -0
- package/dist/jsx/wagmi/index.native.js.map +1 -0
- package/dist/jsx/web.mjs +13 -0
- package/dist/jsx/web.mjs.map +1 -0
- package/dist/keycloak/login.iife.js +449 -443
- package/docs/bridge-protocol.md +41 -14
- package/package.json +13 -6
- package/src/bridge/base58.spec.ts +18 -0
- package/src/bridge/base58.ts +25 -0
- package/src/bridge/core.ts +2 -0
- package/src/bridge/drivers.spec.ts +283 -0
- package/src/bridge/drivers.ts +155 -0
- package/src/bridge/index.spec.ts +3 -0
- package/src/bridge/nativeHost.spec.ts +139 -15
- package/src/bridge/nativeHost.ts +84 -14
- package/src/bundler/metaMaskConnectTimeouts.spec.ts +3 -0
- package/src/clients/adapter.ts +5 -1
- package/src/clients/connector.ts +2 -0
- package/src/clients/evm.spec.ts +8 -0
- package/src/clients/evm.ts +3 -0
- package/src/clients/evmRead.spec.ts +180 -0
- package/src/clients/evmRead.ts +140 -0
- package/src/clients/hooks.spec.tsx +58 -0
- package/src/clients/hooks.ts +73 -14
- package/src/clients/index.ts +11 -1
- package/src/clients/types.ts +15 -1
- package/src/clients/useEvmReadClient.spec.tsx +93 -0
- package/src/connectkit/adapters/BitcoinAdapter.ts +64 -4
- package/src/connectkit/adapters/SolanaAdapter.ts +49 -0
- package/src/connectkit/adapters/SuiAdapter.ts +47 -1
- package/src/connectkit/connectors/ensureWalletConnectors.ts +10 -1
- package/src/connectkit/connectors/getWalletConnectors.ts +2 -0
- package/src/connectkit/connectors/syntheticChains.ts +8 -0
- package/src/connectkit/connectors/walletAdapterConnector.ts +2 -0
- package/src/connectkit/defaultConfig.ts +21 -7
- package/src/connectkit/siwe/SIWEContext.tsx +3 -0
- package/src/connectkit/siwe/SIWEProvider.spec.tsx +109 -0
- package/src/connectkit/siwe/SIWEProvider.tsx +16 -7
- package/src/connectkit/siwe/connectIntent.spec.ts +100 -30
- package/src/connectkit/siwe/connectIntent.ts +99 -25
- package/src/connectkit/siwe/useSIWE.ts +4 -1
- package/src/connectkit/web3Bridge.tsx +75 -15
- package/src/core/family.spec.ts +19 -0
- package/src/core/family.ts +43 -0
- package/src/core/imports.spec.ts +1 -1
- package/src/core/index.ts +23 -0
- package/src/core/lightDriver.spec.ts +284 -0
- package/src/core/lightDriver.ts +235 -0
- package/src/core/react.ts +18 -0
- package/src/core/signIn.spec.tsx +305 -0
- package/src/core/signIn.ts +282 -0
- package/src/core/store.spec.ts +83 -0
- package/src/core/store.ts +60 -9
- package/src/core/types.ts +15 -1
- package/src/families/btc.ts +16 -0
- package/src/families/eth.ts +35 -0
- package/src/families/families.spec.ts +180 -0
- package/src/families/gpg.ts +13 -0
- package/src/families/host.ts +34 -0
- package/src/families/index.ts +32 -0
- package/src/families/messages.ts +39 -0
- package/src/families/sol.ts +25 -0
- package/src/families/sui.ts +17 -0
- package/src/index.ts +38 -1
- package/src/keycloak/KeycloakWalletLogin.spec.tsx +211 -4
- package/src/keycloak/keycloakWallet.spec.ts +81 -1
- package/src/keycloak/keycloakWallet.ts +24 -2
- package/src/keycloak/useDirectLogin.spec.tsx +77 -4
- package/src/keycloak/useDirectLogin.ts +23 -11
- package/src/keycloak/useWalletLogin.spec.tsx +52 -0
- package/src/keycloak/useWalletLogin.ts +24 -6
- package/src/light/drivers.spec.ts +330 -0
- package/src/light/drivers.ts +54 -0
- package/src/light/index.ts +1 -0
- package/src/light/native.spec.ts +22 -0
- package/src/providers/WalletProvider.native.spec.tsx +288 -0
- package/src/providers/WalletProvider.native.tsx +132 -59
- package/src/providers/WalletProvider.spec.tsx +521 -0
- package/src/providers/WalletProvider.tsx +90 -19
- package/src/providers/families.tsx +39 -0
- package/src/providers/index.ts +3 -0
- package/src/providers/walletConfig.spec.ts +19 -1
- package/src/providers/walletConfig.ts +80 -2
- package/src/wagmi/driver.spec.ts +407 -0
- package/src/wagmi/driver.ts +303 -0
- package/src/wagmi/host.spec.tsx +416 -0
- package/src/wagmi/host.tsx +260 -0
- package/src/wagmi/index.ts +1 -0
- package/src/web.spec.ts +58 -0
- package/src/web.ts +82 -0
- package/types/bridge/base58.d.ts +2 -0
- package/types/bridge/base58.d.ts.map +1 -0
- package/types/bridge/core.d.ts +2 -1
- package/types/bridge/core.d.ts.map +1 -1
- package/types/bridge/drivers.d.ts +24 -0
- package/types/bridge/drivers.d.ts.map +1 -0
- package/types/bridge/nativeHost.d.ts +34 -4
- package/types/bridge/nativeHost.d.ts.map +1 -1
- package/types/clients/adapter.d.ts +5 -1
- package/types/clients/adapter.d.ts.map +1 -1
- package/types/clients/connector.d.ts +2 -0
- package/types/clients/connector.d.ts.map +1 -1
- package/types/clients/evm.d.ts +2 -0
- package/types/clients/evm.d.ts.map +1 -1
- package/types/clients/evmRead.d.ts +54 -0
- package/types/clients/evmRead.d.ts.map +1 -0
- package/types/clients/hooks.d.ts +23 -3
- package/types/clients/hooks.d.ts.map +1 -1
- package/types/clients/index.d.ts +4 -2
- package/types/clients/index.d.ts.map +1 -1
- package/types/clients/types.d.ts +11 -1
- package/types/clients/types.d.ts.map +1 -1
- package/types/connectkit/adapters/BitcoinAdapter.d.ts +9 -0
- package/types/connectkit/adapters/BitcoinAdapter.d.ts.map +1 -1
- package/types/connectkit/adapters/SolanaAdapter.d.ts +12 -0
- package/types/connectkit/adapters/SolanaAdapter.d.ts.map +1 -1
- package/types/connectkit/adapters/SuiAdapter.d.ts +8 -0
- package/types/connectkit/adapters/SuiAdapter.d.ts.map +1 -1
- package/types/connectkit/connectors/ensureWalletConnectors.d.ts +3 -0
- package/types/connectkit/connectors/ensureWalletConnectors.d.ts.map +1 -1
- package/types/connectkit/connectors/getWalletConnectors.d.ts +2 -0
- package/types/connectkit/connectors/getWalletConnectors.d.ts.map +1 -1
- package/types/connectkit/connectors/syntheticChains.d.ts +8 -0
- package/types/connectkit/connectors/syntheticChains.d.ts.map +1 -1
- package/types/connectkit/connectors/walletAdapterConnector.d.ts +2 -0
- package/types/connectkit/connectors/walletAdapterConnector.d.ts.map +1 -1
- package/types/connectkit/defaultConfig.d.ts +2 -1
- package/types/connectkit/defaultConfig.d.ts.map +1 -1
- package/types/connectkit/siwe/SIWEContext.d.ts.map +1 -1
- package/types/connectkit/siwe/SIWEProvider.d.ts +6 -0
- package/types/connectkit/siwe/SIWEProvider.d.ts.map +1 -1
- package/types/connectkit/siwe/connectIntent.d.ts +16 -5
- package/types/connectkit/siwe/connectIntent.d.ts.map +1 -1
- package/types/connectkit/siwe/useSIWE.d.ts +4 -0
- package/types/connectkit/siwe/useSIWE.d.ts.map +1 -1
- package/types/connectkit/web3Bridge.d.ts +2 -0
- package/types/connectkit/web3Bridge.d.ts.map +1 -1
- package/types/core/family.d.ts +26 -0
- package/types/core/family.d.ts.map +1 -1
- package/types/core/index.d.ts +6 -4
- package/types/core/index.d.ts.map +1 -1
- package/types/core/lightDriver.d.ts +52 -0
- package/types/core/lightDriver.d.ts.map +1 -0
- package/types/core/react.d.ts +4 -0
- package/types/core/react.d.ts.map +1 -1
- package/types/core/signIn.d.ts +85 -0
- package/types/core/signIn.d.ts.map +1 -0
- package/types/core/store.d.ts +12 -3
- package/types/core/store.d.ts.map +1 -1
- package/types/core/types.d.ts +14 -1
- package/types/core/types.d.ts.map +1 -1
- package/types/families/btc.d.ts +4 -0
- package/types/families/btc.d.ts.map +1 -0
- package/types/families/eth.d.ts +13 -0
- package/types/families/eth.d.ts.map +1 -0
- package/types/families/gpg.d.ts +4 -0
- package/types/families/gpg.d.ts.map +1 -0
- package/types/families/host.d.ts +24 -0
- package/types/families/host.d.ts.map +1 -0
- package/types/families/index.d.ts +14 -0
- package/types/families/index.d.ts.map +1 -0
- package/types/families/messages.d.ts +7 -0
- package/types/families/messages.d.ts.map +1 -0
- package/types/families/sol.d.ts +9 -0
- package/types/families/sol.d.ts.map +1 -0
- package/types/families/sui.d.ts +4 -0
- package/types/families/sui.d.ts.map +1 -0
- package/types/index.d.ts +5 -2
- package/types/index.d.ts.map +1 -1
- package/types/keycloak/keycloakWallet.d.ts +15 -2
- package/types/keycloak/keycloakWallet.d.ts.map +1 -1
- package/types/keycloak/useDirectLogin.d.ts +11 -6
- package/types/keycloak/useDirectLogin.d.ts.map +1 -1
- package/types/keycloak/useWalletLogin.d.ts +8 -1
- package/types/keycloak/useWalletLogin.d.ts.map +1 -1
- package/types/light/drivers.d.ts +13 -0
- package/types/light/drivers.d.ts.map +1 -0
- package/types/light/index.d.ts +2 -0
- package/types/light/index.d.ts.map +1 -0
- package/types/providers/WalletProvider.d.ts +37 -6
- package/types/providers/WalletProvider.d.ts.map +1 -1
- package/types/providers/WalletProvider.native.d.ts +32 -3
- package/types/providers/WalletProvider.native.d.ts.map +1 -1
- package/types/providers/families.d.ts +12 -0
- package/types/providers/families.d.ts.map +1 -0
- package/types/providers/index.d.ts +1 -1
- package/types/providers/index.d.ts.map +1 -1
- package/types/providers/walletConfig.d.ts +32 -2
- package/types/providers/walletConfig.d.ts.map +1 -1
- package/types/wagmi/driver.d.ts +44 -0
- package/types/wagmi/driver.d.ts.map +1 -0
- package/types/wagmi/host.d.ts +31 -0
- package/types/wagmi/host.d.ts.map +1 -0
- package/types/wagmi/index.d.ts +2 -0
- package/types/wagmi/index.d.ts.map +1 -0
- package/types/web.d.ts +13 -0
- package/types/web.d.ts.map +1 -0
|
@@ -1,23 +1,30 @@
|
|
|
1
1
|
import { describe, expect, it } from "vitest";
|
|
2
2
|
import { BridgeHost } from "./BridgeHost";
|
|
3
|
-
import { buildInjectScript, createNativeBridge } from "./nativeHost";
|
|
3
|
+
import { NativeBridgeErrorCode, buildInjectScript, createNativeBridge } from "./nativeHost";
|
|
4
4
|
import { createPostMessageTransport } from "./postMessageTransport";
|
|
5
|
-
import { BRIDGE_PROTOCOL_VERSION } from "./protocol";
|
|
5
|
+
import { BRIDGE_PROTOCOL_VERSION, BridgeRequestError } from "./protocol";
|
|
6
|
+
|
|
7
|
+
const pageUrl = "https://wallet.example.com/webview.html";
|
|
8
|
+
const foreign = "https://evil.example/";
|
|
6
9
|
|
|
7
10
|
/**
|
|
8
11
|
* A fake page: `inject` runs the native side's script against a fake window
|
|
9
12
|
* whose `__bridgeReceive` feeds a BridgeHost, and the host's replies come back
|
|
10
13
|
* through `native.receive` with the page's URL.
|
|
11
14
|
*/
|
|
12
|
-
function setup(
|
|
15
|
+
function setup(url = pageUrl) {
|
|
13
16
|
const injected: string[] = [];
|
|
17
|
+
let pageLost = 0;
|
|
14
18
|
const win: { location: { origin: string }; __bridgeReceive?: (raw: string) => void } = {
|
|
15
|
-
location: { origin: new URL(
|
|
19
|
+
location: { origin: new URL(url).origin },
|
|
16
20
|
};
|
|
17
|
-
let postedFrom =
|
|
21
|
+
let postedFrom = url;
|
|
18
22
|
const native = createNativeBridge({
|
|
19
|
-
pageUrl,
|
|
23
|
+
pageUrl: url,
|
|
20
24
|
allowDevHosts: true,
|
|
25
|
+
onPageLost() {
|
|
26
|
+
pageLost += 1;
|
|
27
|
+
},
|
|
21
28
|
inject(script) {
|
|
22
29
|
injected.push(script);
|
|
23
30
|
new Function("window", script)(win);
|
|
@@ -31,12 +38,25 @@ function setup(pageUrl = "https://wallet.example.com/webview.html") {
|
|
|
31
38
|
host,
|
|
32
39
|
injected,
|
|
33
40
|
win,
|
|
34
|
-
|
|
35
|
-
|
|
41
|
+
get pageLost() {
|
|
42
|
+
return pageLost;
|
|
43
|
+
},
|
|
44
|
+
postFrom(from: string) {
|
|
45
|
+
postedFrom = from;
|
|
36
46
|
},
|
|
37
47
|
};
|
|
38
48
|
}
|
|
39
49
|
|
|
50
|
+
/** Spend the remount budget: every remount lands (the page starts loading) and the page never says ready. */
|
|
51
|
+
function strand(native: ReturnType<typeof createNativeBridge>) {
|
|
52
|
+
expect(native.navigated(foreign)).toBe(true);
|
|
53
|
+
expect(native.navigated(pageUrl)).toBe(false);
|
|
54
|
+
expect(native.navigated(foreign)).toBe(true);
|
|
55
|
+
expect(native.navigated(pageUrl)).toBe(false);
|
|
56
|
+
expect(native.navigated(foreign)).toBe(false);
|
|
57
|
+
expect(native.stranded).toBe(true);
|
|
58
|
+
}
|
|
59
|
+
|
|
40
60
|
describe("createNativeBridge", () => {
|
|
41
61
|
it("refuses a page that is not hosted", () => {
|
|
42
62
|
expect(() =>
|
|
@@ -104,7 +124,10 @@ describe("createNativeBridge", () => {
|
|
|
104
124
|
expect(native.navigated("about:blank")).toBe(false);
|
|
105
125
|
expect(native.peer).not.toBeNull();
|
|
106
126
|
expect(native.navigated("https://evil.example/form")).toBe(true);
|
|
107
|
-
await expect(lost).rejects.
|
|
127
|
+
await expect(lost).rejects.toMatchObject({
|
|
128
|
+
code: NativeBridgeErrorCode.pageGone,
|
|
129
|
+
message: expect.stringMatching(/went away/),
|
|
130
|
+
});
|
|
108
131
|
expect(native.peer).toBeNull();
|
|
109
132
|
const before = injected.length;
|
|
110
133
|
const next = native.client.request("evm", "eth_chainId");
|
|
@@ -119,7 +142,10 @@ describe("createNativeBridge", () => {
|
|
|
119
142
|
host.ready();
|
|
120
143
|
const lost = native.client.request("evm", "eth_requestAccounts");
|
|
121
144
|
host.ready();
|
|
122
|
-
await expect(lost).rejects.
|
|
145
|
+
await expect(lost).rejects.toMatchObject({
|
|
146
|
+
code: NativeBridgeErrorCode.pageGone,
|
|
147
|
+
message: expect.stringMatching(/reloaded/),
|
|
148
|
+
});
|
|
123
149
|
});
|
|
124
150
|
|
|
125
151
|
it("pageGone fails what is in flight and queues until the next ready", async () => {
|
|
@@ -130,7 +156,7 @@ describe("createNativeBridge", () => {
|
|
|
130
156
|
host.ready();
|
|
131
157
|
const lost = native.client.request("evm", "eth_requestAccounts");
|
|
132
158
|
native.pageGone();
|
|
133
|
-
await expect(lost).rejects.
|
|
159
|
+
await expect(lost).rejects.toMatchObject({ code: NativeBridgeErrorCode.pageGone });
|
|
134
160
|
const before = injected.length;
|
|
135
161
|
const next = native.client.request("evm", "eth_chainId");
|
|
136
162
|
expect(injected).toHaveLength(before);
|
|
@@ -141,11 +167,109 @@ describe("createNativeBridge", () => {
|
|
|
141
167
|
it("asks for the page back twice at most until it announces itself again", () => {
|
|
142
168
|
const { native, host } = setup();
|
|
143
169
|
host.ready();
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
expect(native.
|
|
170
|
+
strand(native);
|
|
171
|
+
host.ready();
|
|
172
|
+
expect(native.stranded).toBe(false);
|
|
173
|
+
expect(native.navigated(foreign)).toBe(true);
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
it("a foreign pushState or client redirect before the remount lands costs one remount, not two", () => {
|
|
177
|
+
const { native, host } = setup();
|
|
178
|
+
host.ready();
|
|
179
|
+
expect(native.navigated(foreign)).toBe(true);
|
|
180
|
+
// Android's doUpdateVisitedHistory reports the foreign document again.
|
|
181
|
+
expect(native.navigated(`${foreign}next`)).toBe(false);
|
|
182
|
+
expect(native.navigated(pageUrl)).toBe(false);
|
|
183
|
+
expect(native.navigated(foreign)).toBe(true);
|
|
184
|
+
expect(native.navigated(foreign)).toBe(false);
|
|
185
|
+
expect(native.stranded).toBe(false);
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
it("past the remount cap, fails what is in flight and every new request at once, naming the page", async () => {
|
|
189
|
+
const { native, host, injected } = setup();
|
|
190
|
+
host.register("evm", () => "0x1");
|
|
147
191
|
host.ready();
|
|
148
|
-
expect(native.navigated(
|
|
192
|
+
expect(native.navigated(foreign)).toBe(true);
|
|
193
|
+
expect(native.navigated(pageUrl)).toBe(false);
|
|
194
|
+
expect(native.navigated(foreign)).toBe(true);
|
|
195
|
+
expect(native.navigated(pageUrl)).toBe(false);
|
|
196
|
+
const queued = native.client.request("evm", "eth_chainId");
|
|
197
|
+
expect(native.navigated(foreign)).toBe(false);
|
|
198
|
+
const stranded = {
|
|
199
|
+
name: "BridgeRequestError",
|
|
200
|
+
code: NativeBridgeErrorCode.pageStranded,
|
|
201
|
+
message: expect.stringContaining("https://wallet.example.com"),
|
|
202
|
+
data: { pageOrigin: "https://wallet.example.com" },
|
|
203
|
+
};
|
|
204
|
+
await expect(queued).rejects.toMatchObject(stranded);
|
|
205
|
+
const before = injected.length;
|
|
206
|
+
// Far longer than the test's own timeout: only an immediate rejection passes.
|
|
207
|
+
const next = native.client.request("evm", "eth_chainId", undefined, { timeoutMs: 600_000 });
|
|
208
|
+
await expect(next).rejects.toBeInstanceOf(BridgeRequestError);
|
|
209
|
+
await expect(next).rejects.toMatchObject(stranded);
|
|
210
|
+
expect(injected).toHaveLength(before);
|
|
211
|
+
expect(native.navigated(foreign)).toBe(false);
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
it("a page that comes back by itself clears the stranded state", async () => {
|
|
215
|
+
const { native, host } = setup();
|
|
216
|
+
host.register("evm", () => "0x1");
|
|
217
|
+
host.ready();
|
|
218
|
+
strand(native);
|
|
219
|
+
expect(native.navigated(pageUrl)).toBe(false);
|
|
220
|
+
host.ready();
|
|
221
|
+
expect(native.stranded).toBe(false);
|
|
222
|
+
await expect(native.client.request("evm", "eth_chainId")).resolves.toBe("0x1");
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
it("recover gives a stranded bridge a fresh budget and asks for the page back", async () => {
|
|
226
|
+
const { native, host } = setup();
|
|
227
|
+
host.register("evm", () => "0x1");
|
|
228
|
+
host.ready();
|
|
229
|
+
expect(native.recover()).toBe(false);
|
|
230
|
+
strand(native);
|
|
231
|
+
expect(native.recover()).toBe(true);
|
|
232
|
+
expect(native.stranded).toBe(false);
|
|
233
|
+
const next = native.client.request("evm", "eth_chainId");
|
|
234
|
+
// The stranded document may still report itself before the remount lands.
|
|
235
|
+
expect(native.navigated(foreign)).toBe(false);
|
|
236
|
+
expect(native.navigated(pageUrl)).toBe(false);
|
|
237
|
+
host.ready();
|
|
238
|
+
await expect(next).resolves.toBe("0x1");
|
|
239
|
+
expect(native.recover()).toBe(false);
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
it("recover also restarts a remount whose own load never showed up", () => {
|
|
243
|
+
const { native, host } = setup();
|
|
244
|
+
host.ready();
|
|
245
|
+
expect(native.navigated(foreign)).toBe(true);
|
|
246
|
+
// The remounted WebView's first report is foreign (the page URL redirected away).
|
|
247
|
+
expect(native.navigated(foreign)).toBe(false);
|
|
248
|
+
expect(native.stranded).toBe(false);
|
|
249
|
+
expect(native.recover()).toBe(true);
|
|
250
|
+
expect(native.navigated(pageUrl)).toBe(false);
|
|
251
|
+
expect(native.recover()).toBe(false);
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
it("reports every loss of the page so the host can release its sheet", () => {
|
|
255
|
+
const setupA = setup();
|
|
256
|
+
setupA.host.ready();
|
|
257
|
+
expect(setupA.pageLost).toBe(0);
|
|
258
|
+
expect(setupA.native.navigated(pageUrl)).toBe(false);
|
|
259
|
+
expect(setupA.pageLost).toBe(0);
|
|
260
|
+
setupA.native.navigated(foreign);
|
|
261
|
+
expect(setupA.pageLost).toBe(1);
|
|
262
|
+
setupA.native.navigated(pageUrl);
|
|
263
|
+
setupA.native.navigated(foreign);
|
|
264
|
+
setupA.native.navigated(pageUrl);
|
|
265
|
+
setupA.native.navigated(foreign);
|
|
266
|
+
expect(setupA.native.stranded).toBe(true);
|
|
267
|
+
expect(setupA.pageLost).toBe(3);
|
|
268
|
+
|
|
269
|
+
const setupB = setup();
|
|
270
|
+
setupB.host.ready();
|
|
271
|
+
setupB.native.pageGone();
|
|
272
|
+
expect(setupB.pageLost).toBe(1);
|
|
149
273
|
});
|
|
150
274
|
|
|
151
275
|
it("exposes the page origin", () => {
|
package/src/bridge/nativeHost.ts
CHANGED
|
@@ -1,7 +1,21 @@
|
|
|
1
1
|
import { BridgeClient } from "./BridgeClient";
|
|
2
2
|
import { hostedPageOrigin, parseOrigin } from "./hosting";
|
|
3
3
|
import { createPostMessageTransport } from "./postMessageTransport";
|
|
4
|
-
import { BRIDGE_PROTOCOL_VERSION, type BridgeReady } from "./protocol";
|
|
4
|
+
import { BRIDGE_PROTOCOL_VERSION, BridgeRequestError, type BridgeReady } from "./protocol";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Codes the native end raises itself when the page cannot answer. They never
|
|
8
|
+
* cross the wire, and sit outside JSON-RPC's reserved band so a wallet error
|
|
9
|
+
* passed through `evm` is unlikely to share one.
|
|
10
|
+
*/
|
|
11
|
+
export const NativeBridgeErrorCode = {
|
|
12
|
+
/** The page went away (reload, crash, a foreign document) before it answered. */
|
|
13
|
+
pageGone: -33001,
|
|
14
|
+
/** The host stopped loading the page back: requests fail at once until `recover()`. */
|
|
15
|
+
pageStranded: -33002,
|
|
16
|
+
} as const;
|
|
17
|
+
|
|
18
|
+
const MAX_REMOUNTS = 2;
|
|
5
19
|
|
|
6
20
|
export interface NativeBridgeOptions {
|
|
7
21
|
/** The hosted wallet page. Must pass `isHostedPageUrl`. */
|
|
@@ -14,6 +28,11 @@ export interface NativeBridgeOptions {
|
|
|
14
28
|
timeoutMs?: number;
|
|
15
29
|
/** Called once the page reports `sys.ready`. */
|
|
16
30
|
onReady?(ready: BridgeReady): void;
|
|
31
|
+
/**
|
|
32
|
+
* Called when the page goes away or strands (not on a reload that sends
|
|
33
|
+
* `sys.ready` again): close anything showing it, it no longer holds that state.
|
|
34
|
+
*/
|
|
35
|
+
onPageLost?(): void;
|
|
17
36
|
}
|
|
18
37
|
|
|
19
38
|
export interface NativeBridge {
|
|
@@ -22,22 +41,36 @@ export interface NativeBridge {
|
|
|
22
41
|
readonly pageOrigin: string;
|
|
23
42
|
/** What the page announced in `sys.ready`, or null before it has. */
|
|
24
43
|
readonly peer: BridgeReady | null;
|
|
44
|
+
/** True once the page was lost past the remount cap; see `navigated`. */
|
|
45
|
+
readonly stranded: boolean;
|
|
25
46
|
/**
|
|
26
47
|
* Feed a WebView message in: `receive(e.nativeEvent.data, e.nativeEvent.url)`.
|
|
27
48
|
* A message whose `fromUrl` is missing or on another origin is dropped.
|
|
28
49
|
*/
|
|
29
50
|
receive(data: string, fromUrl: string): void;
|
|
30
51
|
/**
|
|
31
|
-
* The top frame
|
|
52
|
+
* The top frame is on `url` (react-native-webview's `onLoadStart`, which
|
|
53
|
+
* Android fires when history updates, after the document commits).
|
|
32
54
|
* A document on another origin is not the page: what is in flight fails,
|
|
33
55
|
* nothing more is delivered until the page announces itself again, and the
|
|
34
|
-
* answer is true so the host loads `pageUrl` back.
|
|
35
|
-
*
|
|
56
|
+
* answer is true so the host loads `pageUrl` back. Another foreign report
|
|
57
|
+
* before that load starts costs nothing: Android reports a foreign
|
|
58
|
+
* pushState or client redirect too. Twice at most between two `sys.ready`s;
|
|
59
|
+
* past that the bridge is stranded and fails every request at once with
|
|
60
|
+
* `pageStranded` instead of looping, until the page announces itself or
|
|
61
|
+
* the host calls `recover()`.
|
|
36
62
|
*/
|
|
37
63
|
navigated(url: string): boolean;
|
|
64
|
+
/**
|
|
65
|
+
* On a user action (the app returning to the foreground): leave the
|
|
66
|
+
* stranded state, or a remount whose own page load never showed up, with a
|
|
67
|
+
* fresh remount budget. True when the host should now load `pageUrl` back.
|
|
68
|
+
*/
|
|
69
|
+
recover(): boolean;
|
|
38
70
|
/**
|
|
39
71
|
* The page died (WebView content process gone) or is being reloaded: fail
|
|
40
|
-
* the requests in flight and queue new ones until the next `sys.ready
|
|
72
|
+
* the requests in flight and queue new ones until the next `sys.ready`
|
|
73
|
+
* (while stranded they fail at once instead).
|
|
41
74
|
*/
|
|
42
75
|
pageGone(): void;
|
|
43
76
|
dispose(): void;
|
|
@@ -66,17 +99,32 @@ export function createNativeBridge(options: NativeBridgeOptions): NativeBridge {
|
|
|
66
99
|
const pageOrigin = hostedPageOrigin(options.pageUrl, { allowDevHosts: options.allowDevHosts });
|
|
67
100
|
const queue: string[] = [];
|
|
68
101
|
let peer: BridgeReady | null = null;
|
|
69
|
-
let
|
|
102
|
+
let remounts = 0;
|
|
103
|
+
let remountPending = false;
|
|
104
|
+
let stranded = false;
|
|
105
|
+
|
|
106
|
+
const pageGoneError = (message: string) =>
|
|
107
|
+
new BridgeRequestError(NativeBridgeErrorCode.pageGone, message, { pageOrigin });
|
|
108
|
+
const strandedError = () =>
|
|
109
|
+
new BridgeRequestError(
|
|
110
|
+
NativeBridgeErrorCode.pageStranded,
|
|
111
|
+
`The wallet page ${pageOrigin} is gone and is no longer loaded back`,
|
|
112
|
+
{ pageOrigin },
|
|
113
|
+
);
|
|
70
114
|
|
|
71
115
|
const transport = createPostMessageTransport((raw) => {
|
|
72
|
-
|
|
116
|
+
// The request is already pending in the client, so this rejects it at once.
|
|
117
|
+
if (stranded) client.rejectPending(strandedError());
|
|
118
|
+
else if (peer) options.inject(buildInjectScript(raw, pageOrigin));
|
|
73
119
|
else queue.push(raw);
|
|
74
120
|
});
|
|
75
121
|
const offReady = transport.subscribe((message) => {
|
|
76
122
|
if (message.ns !== "sys" || message.kind !== "event" || message.method !== "ready") return;
|
|
77
123
|
// A second ready is a new document: whatever the old one was answering is lost.
|
|
78
|
-
if (peer) client.rejectPending(
|
|
79
|
-
|
|
124
|
+
if (peer) client.rejectPending(pageGoneError("The wallet page reloaded"));
|
|
125
|
+
remounts = 0;
|
|
126
|
+
remountPending = false;
|
|
127
|
+
stranded = false;
|
|
80
128
|
const params = message.params as Partial<BridgeReady> | undefined;
|
|
81
129
|
peer = {
|
|
82
130
|
protocol: typeof params?.protocol === "number" ? params.protocol : BRIDGE_PROTOCOL_VERSION,
|
|
@@ -87,11 +135,13 @@ export function createNativeBridge(options: NativeBridgeOptions): NativeBridge {
|
|
|
87
135
|
});
|
|
88
136
|
const client = new BridgeClient(transport, { timeoutMs: options.timeoutMs });
|
|
89
137
|
|
|
90
|
-
const
|
|
138
|
+
const lose = (error: Error) => {
|
|
91
139
|
peer = null;
|
|
92
140
|
queue.length = 0;
|
|
93
|
-
client.rejectPending(
|
|
141
|
+
client.rejectPending(error);
|
|
142
|
+
options.onPageLost?.();
|
|
94
143
|
};
|
|
144
|
+
const pageGone = () => lose(pageGoneError("The wallet page went away"));
|
|
95
145
|
|
|
96
146
|
return {
|
|
97
147
|
client,
|
|
@@ -99,16 +149,36 @@ export function createNativeBridge(options: NativeBridgeOptions): NativeBridge {
|
|
|
99
149
|
get peer() {
|
|
100
150
|
return peer;
|
|
101
151
|
},
|
|
152
|
+
get stranded() {
|
|
153
|
+
return stranded;
|
|
154
|
+
},
|
|
102
155
|
receive(data, fromUrl) {
|
|
103
156
|
if (!fromUrl || parseOrigin(fromUrl)?.origin !== pageOrigin) return;
|
|
104
157
|
transport.receive(data);
|
|
105
158
|
},
|
|
106
159
|
navigated(url) {
|
|
107
160
|
if (url.trim().toLowerCase() === "about:blank") return false;
|
|
108
|
-
if (parseOrigin(url)?.origin === pageOrigin)
|
|
161
|
+
if (parseOrigin(url)?.origin === pageOrigin) {
|
|
162
|
+
remountPending = false;
|
|
163
|
+
return false;
|
|
164
|
+
}
|
|
165
|
+
if (stranded || remountPending) return false;
|
|
166
|
+
if (remounts >= MAX_REMOUNTS) {
|
|
167
|
+
stranded = true;
|
|
168
|
+
lose(strandedError());
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
109
171
|
pageGone();
|
|
110
|
-
|
|
111
|
-
|
|
172
|
+
remounts += 1;
|
|
173
|
+
remountPending = true;
|
|
174
|
+
return true;
|
|
175
|
+
},
|
|
176
|
+
recover() {
|
|
177
|
+
if (!stranded && !(remountPending && !peer)) return false;
|
|
178
|
+
stranded = false;
|
|
179
|
+
remounts = 0;
|
|
180
|
+
remountPending = true;
|
|
181
|
+
return true;
|
|
112
182
|
},
|
|
113
183
|
pageGone,
|
|
114
184
|
dispose() {
|
|
@@ -330,6 +330,9 @@ describe("the bundler plugins", () => {
|
|
|
330
330
|
optimizeDeps: {
|
|
331
331
|
include: ["@metamask/connect-evm"],
|
|
332
332
|
noDiscovery: true,
|
|
333
|
+
// optimizeDeps() scans the root's html entries whatever noDiscovery says,
|
|
334
|
+
// and that scan fails on workspace packages whose dist is not built yet.
|
|
335
|
+
entries: [],
|
|
333
336
|
rolldownOptions: { plugins: extra },
|
|
334
337
|
},
|
|
335
338
|
plugins: [metaMaskConnectTimeouts()],
|
package/src/clients/adapter.ts
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import type { Ecosystem } from "@multiplatform.one/connectkit";
|
|
2
2
|
import type { WalletAdapter } from "../connectkit/adapters/types";
|
|
3
3
|
|
|
4
|
-
/**
|
|
4
|
+
/**
|
|
5
|
+
* The wallet adapter a non-EVM shim connector carries (see walletAdapterConnector), or null.
|
|
6
|
+
*
|
|
7
|
+
* @deprecated The wagmi shim for Solana, Sui and Bitcoin wallets, which goes in 8.0.0 when the connect modal reads the connection store (MPO-385). Use the `sol()`, `sui()` and `btc()` families and `useConnection()`.
|
|
8
|
+
*/
|
|
5
9
|
export function connectorAdapter(
|
|
6
10
|
connector: unknown,
|
|
7
11
|
ecosystem?: Exclude<Ecosystem, "evm">,
|
package/src/clients/connector.ts
CHANGED
|
@@ -16,6 +16,8 @@ export type NonEvmClient = SolanaMessageClient | SuiClient | BitcoinClient;
|
|
|
16
16
|
* The signing client for a connected non-EVM wallet, built over the adapter
|
|
17
17
|
* its shim connector carries. Sign-in uses it, so it stays free of
|
|
18
18
|
* @solana/kit. Null for an EVM connector or one that is not connected.
|
|
19
|
+
*
|
|
20
|
+
* @deprecated The wagmi shim for Solana, Sui and Bitcoin wallets, which goes in 8.0.0 when the connect modal reads the connection store (MPO-385). Use the `sol()`, `sui()` and `btc()` families and `useConnection()`.
|
|
19
21
|
*/
|
|
20
22
|
export function clientForConnector(
|
|
21
23
|
connector: unknown,
|
package/src/clients/evm.spec.ts
CHANGED
|
@@ -319,6 +319,14 @@ describe("evmClient", () => {
|
|
|
319
319
|
await expect(client.erc20.balanceOf(token)).resolves.toBe(5n * 10n ** 18n);
|
|
320
320
|
await expect(client.erc20.allowance(token, spender)).resolves.toBe(4n);
|
|
321
321
|
await expect(client.erc20.decimals(token)).resolves.toBe(18);
|
|
322
|
+
await expect(
|
|
323
|
+
client.readContract({
|
|
324
|
+
address: token,
|
|
325
|
+
abi: erc20Abi,
|
|
326
|
+
functionName: "allowance",
|
|
327
|
+
args: [account, spender],
|
|
328
|
+
}),
|
|
329
|
+
).resolves.toBe(4n);
|
|
322
330
|
});
|
|
323
331
|
|
|
324
332
|
it("skips the approval when the allowance already covers the amount", async () => {
|
package/src/clients/evm.ts
CHANGED
|
@@ -284,6 +284,8 @@ export interface EvmClient extends ChainClient<"evm"> {
|
|
|
284
284
|
readonly walletClient: EvmWalletClient;
|
|
285
285
|
/** Reads, simulation and receipts. */
|
|
286
286
|
readonly publicClient: PublicClient;
|
|
287
|
+
/** publicClient.readContract, so a read works on this client and on evmReadClient's alike. */
|
|
288
|
+
readonly readContract: PublicClient["readContract"];
|
|
287
289
|
/** personal_sign; returns the 0x signature. */
|
|
288
290
|
signMessage(message: string): Promise<Hex>;
|
|
289
291
|
sendTransaction(parameters: EvmSendTransactionParameters): Promise<Hash>;
|
|
@@ -695,6 +697,7 @@ export function evmClient(config: EvmClientConfig): EvmClient {
|
|
|
695
697
|
capabilities,
|
|
696
698
|
walletClient,
|
|
697
699
|
publicClient,
|
|
700
|
+
readContract: publicClient.readContract,
|
|
698
701
|
signMessage: (message) => walletClient.signMessage({ account, message }),
|
|
699
702
|
sendTransaction: (parameters) =>
|
|
700
703
|
walletClient.sendTransaction({
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
2
|
+
import {
|
|
3
|
+
createPublicClient,
|
|
4
|
+
custom,
|
|
5
|
+
decodeFunctionData,
|
|
6
|
+
encodeAbiParameters,
|
|
7
|
+
erc20Abi,
|
|
8
|
+
type Address,
|
|
9
|
+
type Chain,
|
|
10
|
+
type Hex,
|
|
11
|
+
type PublicClient,
|
|
12
|
+
} from "viem";
|
|
13
|
+
import { hardhat, mainnet, polygon, sepolia } from "viem/chains";
|
|
14
|
+
import { classifyTxError } from "./evm";
|
|
15
|
+
import { evmReadClient, evmReadClients } from "./evmRead";
|
|
16
|
+
import { ReadOnlyClientError, UnsupportedClientMethodError } from "./types";
|
|
17
|
+
|
|
18
|
+
const token = "0x2222222222222222222222222222222222222222" as Address;
|
|
19
|
+
const owner = "0x1111111111111111111111111111111111111111" as Address;
|
|
20
|
+
const spender = "0x3333333333333333333333333333333333333333" as Address;
|
|
21
|
+
|
|
22
|
+
/** A node that answers eth_call for balanceOf, allowance and decimals, and records every method. */
|
|
23
|
+
function node(chainId = 1) {
|
|
24
|
+
const methods: string[] = [];
|
|
25
|
+
const request = async ({ method, params }: { method: string; params?: unknown }) => {
|
|
26
|
+
methods.push(method);
|
|
27
|
+
if (method === "eth_chainId") return `0x${chainId.toString(16)}`;
|
|
28
|
+
if (method !== "eth_call") throw new Error(`unexpected ${method}`);
|
|
29
|
+
const [{ data }] = params as [{ data: Hex }];
|
|
30
|
+
const call = decodeFunctionData({ abi: erc20Abi, data });
|
|
31
|
+
if (call.functionName === "balanceOf") return encodeAbiParameters([{ type: "uint256" }], [42n]);
|
|
32
|
+
if (call.functionName === "allowance") return encodeAbiParameters([{ type: "uint256" }], [7n]);
|
|
33
|
+
if (call.functionName === "decimals") return encodeAbiParameters([{ type: "uint8" }], [6]);
|
|
34
|
+
throw new Error(`unexpected call ${call.functionName}`);
|
|
35
|
+
};
|
|
36
|
+
return { methods, request };
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** fetch stubbed as a JSON-RPC node, recording the URL of every request. */
|
|
40
|
+
function stubFetch() {
|
|
41
|
+
const urls: string[] = [];
|
|
42
|
+
vi.stubGlobal("fetch", async (input: RequestInfo | URL, init?: RequestInit) => {
|
|
43
|
+
urls.push(new URL(input instanceof Request ? input.url : String(input)).href);
|
|
44
|
+
const { id } = JSON.parse(String(init?.body)) as { id: number };
|
|
45
|
+
const result = encodeAbiParameters([{ type: "uint256" }], [5n]);
|
|
46
|
+
return new Response(JSON.stringify({ jsonrpc: "2.0", id, result }), {
|
|
47
|
+
headers: { "content-type": "application/json" },
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
return urls;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
afterEach(() => {
|
|
54
|
+
vi.unstubAllGlobals();
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
describe("evmReadClient", () => {
|
|
58
|
+
const client = (chain: Chain = mainnet) => {
|
|
59
|
+
const rpc = node(chain.id);
|
|
60
|
+
const publicClient = createPublicClient({ chain, transport: custom(rpc) }) as PublicClient;
|
|
61
|
+
return { rpc, publicClient, client: evmReadClient({ chain, publicClient }) };
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
it("is an EVM client with no address and no signing capabilities", () => {
|
|
65
|
+
const { client: reader, publicClient } = client();
|
|
66
|
+
expect(reader.family).toBe("evm");
|
|
67
|
+
expect(reader.address).toBeNull();
|
|
68
|
+
expect(reader.chainId).toBe(1);
|
|
69
|
+
expect(reader.chain).toBe(mainnet);
|
|
70
|
+
expect(reader.capabilities).toEqual([]);
|
|
71
|
+
expect(reader.publicClient).toBe(publicClient);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it("reads a contract and ERC-20 state with no provider and no account", async () => {
|
|
75
|
+
const { client: reader, rpc } = client();
|
|
76
|
+
await expect(
|
|
77
|
+
reader.readContract({
|
|
78
|
+
address: token,
|
|
79
|
+
abi: erc20Abi,
|
|
80
|
+
functionName: "balanceOf",
|
|
81
|
+
args: [owner],
|
|
82
|
+
}),
|
|
83
|
+
).resolves.toBe(42n);
|
|
84
|
+
await expect(reader.erc20.balanceOf(token, owner)).resolves.toBe(42n);
|
|
85
|
+
await expect(reader.erc20.allowance(token, spender, owner)).resolves.toBe(7n);
|
|
86
|
+
await expect(reader.erc20.decimals(token)).resolves.toBe(6);
|
|
87
|
+
expect(new Set(rpc.methods)).toEqual(new Set(["eth_call"]));
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it.each(["signMessage", "sendTransaction", "writeContract"] as const)(
|
|
91
|
+
"rejects %s with ReadOnlyClientError before any request",
|
|
92
|
+
async (method) => {
|
|
93
|
+
const { client: reader, rpc } = client();
|
|
94
|
+
const call =
|
|
95
|
+
method === "signMessage"
|
|
96
|
+
? reader.signMessage("hello")
|
|
97
|
+
: method === "sendTransaction"
|
|
98
|
+
? reader.sendTransaction({ to: owner, value: 1n })
|
|
99
|
+
: reader.writeContract({
|
|
100
|
+
address: token,
|
|
101
|
+
abi: erc20Abi,
|
|
102
|
+
functionName: "transfer",
|
|
103
|
+
args: [owner, 1n],
|
|
104
|
+
});
|
|
105
|
+
const error = await call.then(
|
|
106
|
+
() => undefined,
|
|
107
|
+
(e: unknown) => e,
|
|
108
|
+
);
|
|
109
|
+
expect(error).toBeInstanceOf(ReadOnlyClientError);
|
|
110
|
+
expect(error).toBeInstanceOf(UnsupportedClientMethodError);
|
|
111
|
+
expect(error).toMatchObject({ name: "ReadOnlyClientError", family: "evm", method });
|
|
112
|
+
expect(classifyTxError(error)).toBe("failed");
|
|
113
|
+
expect(rpc.methods).toEqual([]);
|
|
114
|
+
},
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
it("links a transaction on the chain's explorer", () => {
|
|
118
|
+
const hash = `0x${"ab".repeat(32)}` as Hex;
|
|
119
|
+
expect(client().client.explorerTxUrl(hash)).toBe(`https://etherscan.io/tx/${hash}`);
|
|
120
|
+
expect(client(hardhat).client.explorerTxUrl(hash)).toBeUndefined();
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
it("refuses a public client on another chain", () => {
|
|
124
|
+
const publicClient = createPublicClient({
|
|
125
|
+
chain: polygon,
|
|
126
|
+
transport: custom(node(polygon.id)),
|
|
127
|
+
}) as PublicClient;
|
|
128
|
+
expect(() => evmReadClient({ chain: mainnet, publicClient })).toThrow(
|
|
129
|
+
"reads chain 137, not chain 1",
|
|
130
|
+
);
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
it("reads over rpcUrl, else the chain's default RPC", async () => {
|
|
134
|
+
const urls = stubFetch();
|
|
135
|
+
await evmReadClient({ chain: mainnet, rpcUrl: "https://rpc.example.com/eth" }).erc20.balanceOf(
|
|
136
|
+
token,
|
|
137
|
+
owner,
|
|
138
|
+
);
|
|
139
|
+
await evmReadClient({ chain: mainnet }).erc20.balanceOf(token, owner);
|
|
140
|
+
expect(urls).toEqual([
|
|
141
|
+
"https://rpc.example.com/eth",
|
|
142
|
+
new URL(mainnet.rpcUrls.default.http[0]).href,
|
|
143
|
+
]);
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
describe("evmReadClients", () => {
|
|
148
|
+
it("offers the chains WalletProvider would, default first", () => {
|
|
149
|
+
const readers = evmReadClients({ chains: [mainnet, polygon, sepolia] });
|
|
150
|
+
expect(readers.chains.map((chain) => chain.id)).toEqual([mainnet.id, polygon.id]);
|
|
151
|
+
expect(readers.get().chainId).toBe(mainnet.id);
|
|
152
|
+
expect(readers.get(polygon.id).chainId).toBe(polygon.id);
|
|
153
|
+
expect(
|
|
154
|
+
evmReadClients({ chains: [mainnet, sepolia], enableTestnets: true }).chains.map((c) => c.id),
|
|
155
|
+
).toEqual([mainnet.id, sepolia.id]);
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
it("keeps one client per chain", () => {
|
|
159
|
+
const readers = evmReadClients({ chains: [mainnet, polygon] });
|
|
160
|
+
expect(readers.get(polygon.id)).toBe(readers.get(polygon.id));
|
|
161
|
+
expect(readers.get()).toBe(readers.get(mainnet.id));
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
it("refuses a chain the config does not offer, naming the ones it does", () => {
|
|
165
|
+
const readers = evmReadClients({ chains: [mainnet, sepolia] });
|
|
166
|
+
expect(() => readers.get(sepolia.id)).toThrow(/11155111.*\[1\]/);
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
it("reads the localnet chain over localnetRpcUrl, as WalletProvider does", async () => {
|
|
170
|
+
const urls = stubFetch();
|
|
171
|
+
const readers = evmReadClients({
|
|
172
|
+
chains: [mainnet],
|
|
173
|
+
localnet: true,
|
|
174
|
+
localnetRpcUrl: "http://10.0.2.2:8545",
|
|
175
|
+
});
|
|
176
|
+
expect(readers.get().chainId).toBe(hardhat.id);
|
|
177
|
+
await expect(readers.get().erc20.balanceOf(token, owner)).resolves.toBe(5n);
|
|
178
|
+
expect(urls).toEqual(["http://10.0.2.2:8545/"]);
|
|
179
|
+
});
|
|
180
|
+
});
|