@oasisprotocol/sapphire-paratime makes it easy to port your dapp to the Sapphire ParaTime
by wrapping your existing ethers.Provider
/window.ethereum
/web3.providers.*
.
Once you wrap your provider, you can use Sapphire just like you would use Ethereum.
If your dapp doesn't port in under 10 minutes, it's a bug!
If you have more than a little trouble, please file an issue.
There should be no reason not to use the Sapphire ParaTime!
After installing this library, find your Ethereum provider and wrap it using sapphire.wrap
.
Below are some examples for the most kinds of providers.
Try the @oasisprotocol/sapphire-hardhat Hardhat plugin for extra convenience.
Place this line at the top of your hardhat.config.ts
.
import '@oasisprotocol/sapphire-hardhat';
// All other Hardhat plugins must come below.
import { ethers } from 'ethers';
import * as sapphire from '@oasisprotocol/sapphire-paratime';
// In the browser via `window.ethereum`.
const signer = sapphire.wrap(
new ethers.providers.Web3Provider(window.ethereum).getSigner(),
);
// In Node via `ethers.Wallet`.
const signer = sapphire
.wrap(new ethers.Wallet('0x0a5155afec0de...'))
.connect(ethers.getDefaultProvider(sapphire.NETWORKS.testnet.defaultGateway));
// Just a provider, no signer.
const provider = sapphire.wrap(
ethers.getDefaultProvider(sapphire.NETWORKS.testnet.defaultGateway),
);
import Web3 from 'web3';
import * as sapphire from '@oasisprotocol/sapphire-paratime';
web3.setProvider(sapphire.wrap(web3.currentProvider));
import * as sapphire from '@oasisprotocol/sapphire-paratime';
const provider = sapphire.wrap(window.ethereum);
window.ethereum = sapphire.wrap(window.ethereum); // If you're feeling bold.
Error: missing provider (operation="getChainId", code=UNSUPPORTED_OPERATION, ...)
Explanation: When you first make a transaction or call using a wrapped signer or provider,
this library will automatically fetch the runtime public key from the Web3 gateway
using your connected provider. If you've wrapped just a signer (e.g., ethers.Wallet
),
then you'll see this error.
Fix: The simplest thing to do is connect a provider. Alternatively, you can pass in
a pre-initialized Cipher
object as the second argument to wrap
; and then also generate
signed queries manually using the overrides
parameter to SignedCallDataPack.make
. This
latter approach is not recommended except for the most custom of use cases, however.
Explanation: The default behavior of the Sapphire ParaTime compatibility library is to
sign calls such that msg.sender
can be authenticated during eth_call
and eth_estimateGas
.
This is useful for methods in contracts that do identity-based access control. For better UX
in the browser, you should only make signed calls when necessary.
Fix: The Sapphire ParaTime compat lib will not sign calls when the from
address is
address(0)
. For Web3.js you can pass { from:
0x${'0'.repeat(40)} }
as the final arg
to Contract.method().call
(ref). For Ethers.js please read the next section.
Contract with a Signer cannot override from (operation="overrides.from", code=UNSUPPORTED_OPERATION, ...)
Explanation: Ethers prevents overriding from
when using a Signer for safety reasons.
Fix: Create a new Contract
instance but do not connect it to a signer–just a provider.
Use that for unsigned queries instead.
Generated using TypeDoc