Skip to content

Commit

Permalink
add readonly ethers adapters
Browse files Browse the repository at this point in the history
  • Loading branch information
jnsdls committed Jan 20, 2024
1 parent 605ea88 commit e5ea67e
Show file tree
Hide file tree
Showing 4 changed files with 196 additions and 4 deletions.
18 changes: 16 additions & 2 deletions packages/thirdweb/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@
"import": "./esm/extensions/*.js",
"default": "./cjs/extensions/*.js"
},
"./adapters/*": {
"types": "./types/adapters/*.d.ts",
"import": "./esm/adapters/*.js",
"default": "./cjs/adapters/*.js"
},
"./package.json": "./package.json"
},
"typesVersions": {
Expand All @@ -51,6 +56,9 @@
],
"extensions/*": [
"./types/extensions/*.d.ts"
],
"adapters/*": [
"./types/adapters/*.d.ts"
]
}
},
Expand Down Expand Up @@ -83,14 +91,20 @@
"eslint-plugin-tsdoc": "^0.2.16",
"react": "^18.2.0",
"rimraf": "^3.0.2",
"typescript": "^5.1.6"
"typescript": "^5.1.6",
"ethers5": "npm:ethers@^5.0.0",
"ethers6": "npm:ethers@^6.0.0"
},
"peerDependencies": {
"react": ">=18"
"react": ">=18",
"ethers": "^5 || ^6"
},
"peerDependenciesMeta": {
"react": {
"optional": true
},
"ethers": {
"optional": true
}
},
"scripts": {
Expand Down
66 changes: 66 additions & 0 deletions packages/thirdweb/src/adapters/ethers5.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import type { ThirdwebContract } from "../contract/index.js";
import type * as ethers5 from "ethers5";
import type * as ethers6 from "ethers6";
import * as universalethers from "ethers";
import type { RawClient } from "../client/client.js";

type Ethers5 = typeof ethers5;

function isEthers5(
ethers_: typeof ethers5 | typeof ethers6,
): ethers_ is typeof ethers5 {
return "providers" in ethers_;
}

function assertEthers5(
ethers_: typeof ethers5 | typeof ethers6,
): asserts ethers_ is typeof ethers5 {
if (!isEthers5(ethers_)) {
throw new Error(
"You seem to be using ethers@6, please use the `ethers6Adapter()",
);
}
}

export function ethers5Adapter() {
const ethers_ = universalethers;
assertEthers5(ethers_);
return {
toProvider: (client: RawClient, chainId: number) =>
toProvider(ethers_, client, chainId),
toContract: (contract: ThirdwebContract, abi?: ethers5.ContractInterface) =>
toContract(ethers_, contract, abi),
};
}

function toProvider(
ethers: Ethers5,
client: RawClient,
chainId: number,
): ethers5.providers.Provider {
const url = `https://${chainId}.rpc.thirdweb.com/${client.clientId}`;
const headers: HeadersInit = {};
if (client.secretKey) {
headers["x-secret-key"] = client.secretKey;
}
return new ethers.providers.JsonRpcProvider({
url,
headers: headers,
});
}

async function toContract(
ethers: Ethers5,
contract: ThirdwebContract,
abi?: ethers5.ContractInterface,
): Promise<ethers5.Contract> {
// TODO handle signers as well
// resolve the ABI if it is not explicitly passed
if (!abi) {
const { resolveAbi } = await import("../abi/resolveContractAbi.js");
// this is compatible with ethers5
abi = (await resolveAbi(contract)) as ethers5.ContractInterface;
}
const provider = toProvider(ethers, contract, contract.chainId);
return new ethers.Contract(contract.address, abi, provider);
}
63 changes: 63 additions & 0 deletions packages/thirdweb/src/adapters/ethers6.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import type { ThirdwebContract } from "../contract/index.js";
import type * as ethers5 from "ethers5";
import type * as ethers6 from "ethers6";
import * as universalethers from "ethers";
import type { RawClient } from "../client/client.js";

type Ethers6 = typeof ethers6;

function isEthers5(
ethers_: typeof ethers5 | typeof ethers6,
): ethers_ is typeof ethers5 {
return "providers" in ethers_;
}

function assertEthers6(
ethers_: typeof ethers5 | typeof ethers6,
): asserts ethers_ is typeof ethers6 {
if (isEthers5(ethers_)) {
throw new Error(
"You seem to be using ethers@5, please use the `ethers5Adapter()",
);
}
}

export function ethers6Adapter() {
const ethers_ = universalethers;
assertEthers6(ethers_);
return {
toProvider: (client: RawClient, chainId: number) =>
toProvider(ethers_, client, chainId),
toContract: (contract: ThirdwebContract, abi?: ethers6.InterfaceAbi) =>
toContract(ethers_, contract, abi),
};
}

function toProvider(ethers_: Ethers6, client: RawClient, chainId: number) {
const url = `https://${chainId}.rpc.thirdweb.com/${client.clientId}`;

const fetchRequest = new ethers_.FetchRequest(url);
if (client.secretKey) {
fetchRequest.setHeader("x-secret-key", client.secretKey);
}

return new ethers_.JsonRpcProvider(fetchRequest, chainId, {
staticNetwork: true,
});
}

async function toContract(
ethers_: Ethers6,
contract: ThirdwebContract,
abi?: ethers6.InterfaceAbi,
) {
// TODO handle signers as well
// resolve the ABI if it is not explicitly passed
if (!abi) {
const { resolveAbi } = await import("../abi/resolveContractAbi.js");
// this is compatible with Ethers6
abi = (await resolveAbi(contract)) as ethers6.InterfaceAbi;
}
const provider = toProvider(ethers_, contract, contract.chainId);
return new ethers_.Contract(contract.address, abi, provider);
}
53 changes: 51 additions & 2 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit e5ea67e

Please sign in to comment.