Compare commits

..
Author SHA1 Message Date
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
f6c6a68b97 Version Packages (#690)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-03-09 10:48:42 -08:00
Joaquim VergesandGitHub 2682f5823e [SDK] Fix fetching ABI for legacy contracts (#697) 2023-03-09 18:34:02 +00:00
Joaquim VergesandGitHub d30e3f4db3 [Wallets] Upgrade paper SDK (#696) 2023-03-09 18:02:56 +00:00
Joaquim VergesandGitHub 2efe5be3ad [SDK] Optimize get contract calls (#694) 2023-03-09 05:56:36 +00:00
Joaquim VergesandGitHub 31a252a0ec [Wallets] Cleanup paper wallet integration (#692) 2023-03-09 04:42:23 +00:00
Joaquim VergesandGitHub d5f18b403a [SDK] fix passing slug only as the network (#693) 2023-03-09 04:38:05 +00:00
Nacho IacovinoandGitHub cc0c7fa093 [React] useClaimNFT using correct twfeature (#691) 2023-03-08 21:43:37 +00:00
Nacho IacovinoandGitHub baeb74274e [SDK] New AppURI defaults (#687) 2023-03-08 20:46:21 +00:00
Joaquim VergesandGitHub 5038487e1b Update README.md 2023-03-08 12:06:22 -08:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
c5959fbd52 Version Packages (#689)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-03-07 22:37:23 -08:00
Adam MajmudarandGitHub 68d52f99b3 [SDK] Poll if transaction isn't found yet (#688) 2023-03-08 06:17:23 +00:00
9efeba38f0 [Auth] Include credentials on initial login request, [react] web3button type (#684)
Co-authored-by: Manan Tank <[email protected]>
Co-authored-by: Jonas Daniels <[email protected]>
2023-03-08 06:10:39 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
50346bd9d0 Version Packages (#622)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-03-07 18:03:15 -08:00
Jonas DanielsandGitHub f9cf2bc6ba [chains] - fix windows build? (#686) 2023-03-07 20:11:52 +00:00
Jonas DanielsandGitHub 4355518afe [chains] - update chains (#685) 2023-03-07 18:57:43 +00:00
Jonas DanielsandGitHub 99521129ed quicker timeouts (#682) 2023-03-06 17:49:44 -08:00
c9067681c2 Add CLI command to deploy dynamic smart contracts (#678)
Co-authored-by: Jonas Daniels <[email protected]>
2023-03-07 00:22:30 +00:00
2335f000c9 [SDK] - NFT supply is now string instead of number (#679)
Co-authored-by: Joaquim Verges <[email protected]>
2023-03-05 04:46:00 +00:00
Adam MajmudarandGitHub a7e908b5fe [SDK] Add transaction pattern to registry (#676) 2023-03-03 22:18:35 +00:00
Adam MajmudarandGitHub 2a8cc289ac [SDK] Add transaction builder to publisher and registry (#675) 2023-03-03 21:44:45 +00:00
Adam MajmudarandGitHub d8dec9fc19 [SDK] Fix configuring SDK with custom chains (#674) 2023-03-03 08:23:55 +00:00
Adam MajmudarandGitHub 0c88304464 [SDK] Don't use functions in sdk.getContract (#673) 2023-03-03 07:25:22 +00:00
Jonas DanielsandGitHub 2676fc01f4 fix react core (#672) 2023-03-03 07:14:50 +00:00
Furqan RydhanandGitHub 61ef69649f app URI fixes (#671) 2023-03-03 07:07:32 +00:00
Furqan Rydhan 460576fea9 Merge branch 'main' of github.com:thirdweb-dev/js 2023-03-03 06:47:37 +00:00
Furqan Rydhan 87a8ebdb7a fix things 2023-03-03 06:47:01 +00:00
Furqan Rydhan e23ee0526e fix type for prebuilt contracts and app uri 2023-03-03 06:13:09 +00:00
be04ff2775 CLI improvements (#666)
Co-authored-by: Adam Majmudar <[email protected]>
Co-authored-by: adam-maj <[email protected]>
Co-authored-by: Jonas Daniels <[email protected]>
2023-03-03 06:11:48 +00:00
3740a0bf5d app uri (#662)
Co-authored-by: Nacho Iacovino <[email protected]>
Co-authored-by: Nacho Iacovino <[email protected]>
2023-03-03 05:40:00 +00:00
Jonas DanielsandGitHub 6ae39277a1 [react-core] fix signer more (#670) 2023-03-03 05:39:18 +00:00
Jonas DanielsandGitHub 8f46a2eef5 update signer correctly (#668) 2023-03-02 20:04:56 +00:00
Furqan Rydhan 8ac9b03f4a fix code tab for contract metadata 2023-03-02 06:24:17 +00:00
6ef52dc916 Fix spelling (#665)
Co-authored-by: Jonas Daniels <[email protected]>
2023-03-02 03:04:05 +00:00
Adam MajmudarandGitHub b6b0855b81 [SDK] Allow setting extra overrides (#667) 2023-03-02 02:20:45 +00:00
Jonas Daniels ac01516ce6 fix it 2023-03-01 17:36:09 -08:00
Jonas Daniels 1aef3bd270 changesets action 2023-03-01 17:29:45 -08:00
Jonas Daniels e9b5031565 more things 2023-03-01 17:23:40 -08:00
Adam MajmudarandGitHub e081075b2c [SDK] Expose get and set functions on transaction and tx.sign() (#663) 2023-03-02 00:28:40 +00:00
Jonas Daniels 3212867de2 just always do it 2023-03-01 16:18:02 -08:00
Jonas Daniels 91e7178295 hasChangesets true value not string 2023-03-01 16:08:28 -08:00
Jonas DanielsandGitHub 3985560942 changeset and workflow changes (#664) 2023-03-01 23:32:43 +00:00
87a101ad56 Fix Wrong Currency symbol in non-default chains (#660)
Co-authored-by: Jonas Daniels <[email protected]>
2023-03-01 21:37:51 +00:00
nkrishangandGitHub 842ed519a3 CLI command to create extensions for dynamic contracts (#641) 2023-03-01 19:04:30 +00:00
Adam MajmudarandGitHub 2f4cd92848 [SDK] Add prepare method to all contracts (#661) 2023-03-01 18:49:55 +00:00
iketwandGitHub 303bf63c1a [ReactCoreSDK] pass default key to the sdkprovider (#658) 2023-03-01 17:44:56 +00:00
Adam MajmudarandGitHub 8845bf960e [SDK] await getGasOverrides (#659) 2023-03-01 08:12:48 +00:00
Jake LooandGitHub b80024c6cc ERC20Permit detect (#655) 2023-03-01 03:39:12 +00:00
Jonas DanielsandGitHub 696c384a34 Jd/fix build app uri (#654) 2023-03-01 01:53:26 +00:00
Jonas DanielsandGitHub bd6be0bae7 [SDK] - add extensions getter (#653) 2023-03-01 01:09:57 +00:00
Nacho IacovinoandGitHub 8d5b418e78 [React] Fix appURI hook invariant (#650) 2023-03-01 00:51:59 +00:00
Adam MajmudarandGitHub 1bdb44d36b [React] Fix onError in Web3Button to work with errors on promise (#651) 2023-03-01 00:51:35 +00:00
Nacho IacovinoandGitHub b83ea5251b [SDK] Detect appURI (#631) 2023-03-01 00:50:03 +00:00
Adam MajmudarandGitHub 537785fed0 [SDK] Add getContract and getContractFromAbi functions (#628) 2023-03-01 00:40:13 +00:00
Adam MajmudarandGitHub fb346ffd45 [Storage] Send progress event if files have already been uploaded (#648) 2023-02-28 23:54:29 +00:00
Adam MajmudarandGitHub 63f552d736 Allow passing gatewayUrls as array and directly (#644) 2023-02-28 23:27:14 +00:00
Adam MajmudarandGitHub cc7ce8b1e8 Allow CID prediction for file type on client (#646) 2023-02-28 23:19:30 +00:00
Jonas DanielsandGitHub 85250cf711 [multi] - various fixes (#643) 2023-02-28 22:50:22 +00:00
Adam MajmudarandGitHub 29c1cf7eff Make checking for CID non-blocking on error (#645) 2023-02-28 22:16:58 +00:00
Adam MajmudarandGitHub 0666f37c13 [SDK] Cleanup signer and provider logic & add exhaustive test cases (#623) 2023-02-28 09:14:14 +00:00
Adam MajmudarandGitHub 8a8a37f6d3 [Storage] Pre-compute IPFS hashes before uploading (#637) 2023-02-28 08:08:15 +00:00
Furqan RydhanandGitHub dc08aa731f contract metadata compatibility (#642) 2023-02-28 03:59:31 +00:00
Adam MajmudarandGitHub 541dfeeaba Fix top-level transaction functions (#640) 2023-02-28 02:27:13 +00:00
1e1a39123b [SDK] Add new transaction pattern (#566)
Co-authored-by: Jonas Daniels <[email protected]>
2023-02-27 23:22:21 +00:00
Jonas DanielsandGitHub 5c7ae694c4 add test for chains (#639) 2023-02-27 22:30:36 +00:00
Jonas DanielsandGitHub e33bd2a856 add getChainByChainId function (#638) 2023-02-27 19:18:04 +00:00
Nacho IacovinoandGitHub b1ee7491c8 [React] Export appURI hooks (#636) 2023-02-27 01:01:05 +00:00
Jonas DanielsandGitHub 7832041c0f add chains (#635) 2023-02-27 00:47:10 +00:00
Joaquim VergesandGitHub 88c78f3b32 [SDK] export marketplace and appUri classes (#634) 2023-02-26 23:16:43 +00:00
Nacho IacovinoandGitHub 78536ba65f [Multi] More docs small changes (#633) 2023-02-26 07:26:22 +00:00
Nacho IacovinoandGitHub b0e8406d1e [Multi] Document marketplace v3 with examples (#632) 2023-02-26 04:00:43 +00:00
Nacho IacovinoandGitHub 9c5dbf1fe6 [Multi] AppURI now works with ContractMetadata feature (#630) 2023-02-25 23:13:09 +00:00
Nacho IacovinoandGitHub ba90c675db [Multi] More docs updates (#629) 2023-02-25 22:51:46 +00:00
Joaquim VergesandGitHub fd9ba94db2 Fix feature snippets SDK script (#627) 2023-02-25 17:10:32 +00:00
Nacho IacovinoandGitHub 91f5a2fd5c Fix documentation for react docs (#626) 2023-02-25 16:30:23 +00:00
Joaquim VergesandGitHub e50911bc06 [Wallet] Email wallet improvements (#612) 2023-02-25 04:02:59 +00:00
Nacho IacovinoandGitHub 23cd88ec3a [React] Add AppURI get/set hooks (#625) 2023-02-25 01:52:20 +00:00
Joaquim VergesandGitHub 1adaf41e41 [SDK] Extension code comments (#624) 2023-02-25 01:16:02 +00:00
YashandGitHub 478780f634 [SDK] Feature for extension router (#621) 2023-02-24 03:59:16 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
521c85c1ba Version Packages (#618)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-02-23 09:29:36 -08:00
Jonas DanielsandGitHub b7a5b45441 fix base goerli slug (#619) 2023-02-23 17:17:37 +00:00
Jonas DanielsandGitHub d7deaa48f2 [chains] - add support for base goerli (#617) 2023-02-23 16:58:25 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
98fc320a86 Version Packages (#614)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-02-22 21:48:03 -08:00
Joaquim VergesandGitHub 5712650074 [SDK] Handle custom currencies for any chain (#616) 2023-02-23 05:33:00 +00:00
Jonas DanielsandGitHub 1b0bc87efb [sdk] add code cov (#615) 2023-02-23 01:26:53 +00:00
Jonas DanielsandGitHub a3472a1331 [chains] - DX improvements & chain updates (#613) 2023-02-23 00:01:59 +00:00
310 changed files with 10478 additions and 5092 deletions
+1 -1
View File
@@ -16,6 +16,6 @@
},
"snapshot": {
"useCalculatedVersion": true,
"prereleaseTemplate": "{tag}-{commit}"
"prereleaseTemplate": "{tag}-{datetime}-{commit}"
}
}
+1 -1
View File
@@ -23,7 +23,7 @@ We use [Turborepo](https://turborepo.org/docs/getting-started) to manage the mon
You can see a quick outline of each of the projects within this repo below, each living within the [/packages](/packages) directory:
| Package | Description | Latest Version |
| ------------------------------ | -------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|--------------------------------|----------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [/sdk](./packages/sdk) | Best in class web3 SDK for Browser, Node and Mobile apps | <a href="https://www.npmjs.com/package/@thirdweb-dev/sdk"><img src="https://img.shields.io/npm/v/@thirdweb-dev/sdk?color=red&label=npm&logo=npm" alt="npm version"/></a> |
| [/react](./packages/react) | Ultimate collection of React hooks for your web3 apps | <a href="https://www.npmjs.com/package/@thirdweb-dev/react"><img src="https://img.shields.io/npm/v/@thirdweb-dev/react?color=red&label=npm&logo=npm" alt="npm version"/></a> |
| [/auth](./packages/auth) | Best in class wallet authentication for Node backends | <a href="https://www.npmjs.com/package/@thirdweb-dev/auth"><img src="https://img.shields.io/npm/v/@thirdweb-dev/auth?color=red&label=npm&logo=npm" alt="npm version"/></a> |
+11 -32
View File
@@ -13,13 +13,14 @@ concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
# To use Remote Caching, uncomment the next lines and follow the steps below.
# To use Remote Caching, uncomment the next lines and follow the steps below.
env:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
jobs:
build:
timeout-minutes: 15
name: Build
runs-on: ubuntu-latest-16
@@ -46,6 +47,7 @@ jobs:
key: ${{ github.sha }}-${{ github.run_number }}
lint:
timeout-minutes: 15
name: Lint Packages
runs-on: ubuntu-latest
needs: build
@@ -66,6 +68,7 @@ jobs:
- run: yarn lint
test:
timeout-minutes: 15
name: Unit Tests
runs-on: ubuntu-latest-16
needs: build
@@ -84,8 +87,14 @@ jobs:
key: ${{ github.sha }}-${{ github.run_number }}
- run: yarn test
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v3
with:
files: ./packages/sdk/coverage/evm/lcov.info,./packages/sdk/coverage/solana/lcov.info,
e2e:
timeout-minutes: 15
name: E2E Tests
runs-on: ubuntu-latest-16
needs: build
@@ -110,33 +119,3 @@ jobs:
run: yarn e2e
env:
NODE_OPTIONS: "--max_old_space_size=4096"
size:
name: Size Comparison
runs-on: ubuntu-latest-8
needs: build
timeout-minutes: 30
# only run on pull requests that are targeting main
if: github.event_name == 'pull_request' && github.event.pull_request.base.ref == 'main'
steps:
- name: Setup node
uses: actions/setup-node@v3
with:
node-version: 16
check-latest: true
- uses: actions/cache@v3
timeout-minutes: 5
id: restore-build
with:
path: ./*
key: ${{ github.sha }}-${{ github.run_number }}
- uses: preactjs/compressed-size-action@v2
with:
repo-token: "${{ secrets.GITHUB_TOKEN }}"
strip-hash: "\\-(\\w{8})(?:\\.esm|\\.cjs)"
minimum-change-threshold: 100
# exclude source maps, node modules and any test related files
exclude: "{**/*.map,**/node_modules/**,**/test/**}"
+2
View File
@@ -76,8 +76,10 @@ jobs:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Deploy pre-release
id: changesets
run: |
yarn changeset version --snapshot dev
node ./scripts/pre-release.mjs
yarn changeset publish --tag dev --no-git-tag
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-1
View File
@@ -10,7 +10,6 @@ dist-ssr
.cache
server/dist
public/dist
.turbo
./packages/contracts-js/abis
.idea/
.yalc/
+4 -4
View File
@@ -5,11 +5,11 @@
<br />
</p>
<h1 align="center"><a href='http://thirdweb.com/'>thirdweb</a> JavaScript/TypeScript monorepo</h1>
<h1 align="center"><a href='https://thirdweb.com/'>thirdweb</a> JavaScript/TypeScript monorepo</h1>
<p align="center">
<a href="https://github.com/thirdweb-dev/js/actions/workflows/CI.yml">
<img alt="Build Status" src="https://github.com/thirdweb-dev/js/actions/workflows/CI.yml/badge.svg"/>
<a href="https://github.com/thirdweb-dev/js/actions/workflows/build-test-lint.yml">
<img alt="Build Status" src="https://github.com/thirdweb-dev/js/actions/workflows/build-test-lint.yml/badge.svg"/>
</a>
<a href="https://discord.gg/thirdweb">
<img alt="Join our Discord!" src="https://img.shields.io/discord/834227967404146718.svg?color=7289da&label=discord&logo=discord&style=flat"/>
@@ -21,7 +21,7 @@
## Packages
| Package | Description | Latest Version |
| ------------------------------ | -------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|--------------------------------|----------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [/sdk](./packages/sdk) | Best in class web3 SDK for Browser, Node and Mobile apps | <a href="https://www.npmjs.com/package/@thirdweb-dev/sdk"><img src="https://img.shields.io/npm/v/@thirdweb-dev/sdk?color=red&label=npm&logo=npm" alt="npm version"/></a> |
| [/react](./packages/react) | Ultimate collection of React hooks for your web3 apps | <a href="https://www.npmjs.com/package/@thirdweb-dev/react"><img src="https://img.shields.io/npm/v/@thirdweb-dev/react?color=red&label=npm&logo=npm" alt="npm version"/></a> |
| [/auth](./packages/auth) | Best in class wallet authentication for Node backends | <a href="https://www.npmjs.com/package/@thirdweb-dev/auth"><img src="https://img.shields.io/npm/v/@thirdweb-dev/auth?color=red&label=npm&logo=npm" alt="npm version"/></a> |
+2 -2
View File
@@ -41,10 +41,10 @@
"mocha": "^10.2.0",
"postinstall-postinstall": "^2.1.0",
"prettier": "^2.7.1",
"turbo": "^1.4.6",
"turbo": "^1.8.3",
"yalc": "^1.0.0-pre.53"
},
"manypkg": {
"defaultBranch": "main"
}
}
}
+6
View File
@@ -1,5 +1,11 @@
# @thirdweb-dev/auth
## 3.0.7
### Patch Changes
- [#665](https://github.com/thirdweb-dev/js/pull/665) [`6ef52dc9`](https://github.com/thirdweb-dev/js/commit/6ef52dc916251d72416ba5a8b63b428770f54e75) Thanks [@shift4id](https://github.com/shift4id)! - Fix spelling throughout all packages
## 3.0.6
### Patch Changes
+2
View File
@@ -5,6 +5,8 @@
</p>
<h1 align="center">thirdweb Auth</h1>
<p align="center">
<a href="https://www.npmjs.com/package/@thirdweb-dev/auth"><img src="https://img.shields.io/npm/v/@thirdweb-dev/auth?color=red&label=npm&logo=npm" alt="npm version"/></a>
<a href="https://github.com/thirdweb-dev/js/actions/workflows/build-test-lint.yml"><img alt="Build Status" src="https://github.com/thirdweb-dev/js/actions/workflows/build-test-lint.yml/badge.svg"/></a>
<a href="https://discord.gg/thirdweb"><img alt="Join our Discord!" src="https://img.shields.io/discord/834227967404146718.svg?color=7289da&label=discord&logo=discord&style=flat"/></a>
</p>
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/auth",
"version": "3.0.6",
"version": "3.0.7",
"main": "dist/thirdweb-dev-auth.cjs.js",
"module": "dist/thirdweb-dev-auth.esm.js",
"exports": {
+5 -39
View File
@@ -468,6 +468,7 @@ const polygonMumbai: Chain = {
/**
* @public
* @deprecated - use the chainId number directly instead
*/
export enum ChainId {
Mainnet = 1,
@@ -488,6 +489,7 @@ export enum ChainId {
/**
* @public
* @deprecated - thirdweb now supports all evm chains, for a list of chain install the @thirdweb-dev/chains package
*/
export type SUPPORTED_CHAIN_ID =
| ChainId.Mainnet
@@ -507,6 +509,7 @@ export type SUPPORTED_CHAIN_ID =
/**
* @public
* @deprecated - thirdweb now supports all evm chains, for a list of chain install the @thirdweb-dev/chains package
*/
export const SUPPORTED_CHAIN_IDS: SUPPORTED_CHAIN_ID[] = [
ChainId.Mainnet,
@@ -534,45 +537,8 @@ export const NATIVE_TOKEN_ADDRESS =
export const DEFAULT_API_KEY =
"c6634ad2d97b74baf15ff556016830c251050e6c36b9da508ce3ec80095d3dc1";
function getRpcNameFromChainId(chainId: SUPPORTED_CHAIN_ID): string {
switch (chainId) {
case ChainId.Mainnet:
return "mainnet";
case ChainId.Goerli:
return "goerli";
case ChainId.Polygon:
return "polygon";
case ChainId.Mumbai:
return "mumbai";
case ChainId.Avalanche:
return "avalanche";
case ChainId.AvalancheFujiTestnet:
return "avalanche-fuji";
case ChainId.Fantom:
return "fantom";
case ChainId.FantomTestnet:
return "fantom-testnet";
case ChainId.Arbitrum:
return "arbitrum";
case ChainId.ArbitrumGoerli:
return "arbitrum-goerli";
case ChainId.Optimism:
return "optimism";
case ChainId.OptimismGoerli:
return "optimism-goerli";
case ChainId.BinanceSmartChainMainnet:
return "bsc";
case ChainId.BinanceSmartChainTestnet:
return "bsc-testnet";
default:
throw new Error("Unsupported chain id");
}
}
export function getRpcUrl(chainId: SUPPORTED_CHAIN_ID) {
return `https://${getRpcNameFromChainId(
chainId,
)}.rpc.thirdweb.com/${DEFAULT_API_KEY}`;
export function getRpcUrl(chainId: number) {
return `https://${chainId}.rpc.thirdweb.com/${DEFAULT_API_KEY}`;
}
function enhanceChain<TChain extends Chain>(chain: TChain) {
+1 -1
View File
@@ -31,5 +31,5 @@ export default async function handler(
}),
);
return res.status(200).json({ message: "Succesfully logged out" });
return res.status(200).json({ message: "Successfully logged out" });
}
+1 -1
View File
@@ -31,5 +31,5 @@ export default async function handler(
}),
);
return res.status(200).json({ message: "Succesfully logged out" });
return res.status(200).json({ message: "Successfully logged out" });
}
+28
View File
@@ -1,5 +1,33 @@
# @thirdweb-dev/chains
## 0.1.6
### Patch Changes
- [#635](https://github.com/thirdweb-dev/js/pull/635) [`7832041c`](https://github.com/thirdweb-dev/js/commit/7832041c0fb25852489c73453c2b26e844d94582) Thanks [@jnsdls](https://github.com/jnsdls)! - Add additional chains
- [#643](https://github.com/thirdweb-dev/js/pull/643) [`85250cf7`](https://github.com/thirdweb-dev/js/commit/85250cf71190092b61023d56d1e786d395a008a6) Thanks [@jnsdls](https://github.com/jnsdls)! - expose `getChainBySlug` and `ChainSlug` and `ChainId` type
- [#638](https://github.com/thirdweb-dev/js/pull/638) [`e33bd2a8`](https://github.com/thirdweb-dev/js/commit/e33bd2a856bbc2e2f6b0c90b46be5166281875ae) Thanks [@jnsdls](https://github.com/jnsdls)! - Add `getChainByChainId()` to retrieve chain by chainId
- [#685](https://github.com/thirdweb-dev/js/pull/685) [`4355518a`](https://github.com/thirdweb-dev/js/commit/4355518afea68cd8026d3ab8a0144c15d66b9e24) Thanks [@jnsdls](https://github.com/jnsdls)! - update chains
## 0.1.5
### Patch Changes
- [#617](https://github.com/thirdweb-dev/js/pull/617) [`d7deaa4`](https://github.com/thirdweb-dev/js/commit/d7deaa48f2f943deb8f2ad7459d17de930c00517) Thanks [@jnsdls](https://github.com/jnsdls)! - Add Base Goerli
- [#619](https://github.com/thirdweb-dev/js/pull/619) [`b7a5b45`](https://github.com/thirdweb-dev/js/commit/b7a5b454415596316f58a75f14472631242cc115) Thanks [@jnsdls](https://github.com/jnsdls)! - fix the slug for base-goerli
## 0.1.4
### Patch Changes
- [#613](https://github.com/thirdweb-dev/js/pull/613) [`a3472a1`](https://github.com/thirdweb-dev/js/commit/a3472a133175826d052ee986907de014e3cf3ad9) Thanks [@jnsdls](https://github.com/jnsdls)! - Update Chains
- [#616](https://github.com/thirdweb-dev/js/pull/616) [`5712650`](https://github.com/thirdweb-dev/js/commit/5712650074e2415bbea4173a0bb68d727ff2db90) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - new chains
## 0.1.3
### Patch Changes
+24 -4
View File
@@ -5,12 +5,32 @@
</p>
<h1 align="center">thirdweb chains</h1>
<p align="center">
<!-- <a href="https://www.npmjs.com/package/@thirdweb-dev/sdk"><img src="https://img.shields.io/npm/v/@thirdweb-dev/sdk?color=red&label=npm&logo=npm" alt="npm version"/></a> -->
<!-- <a href="https://github.com/thirdweb-dev/js/actions/workflows/CI.yml"><img alt="Build Status" src="https://github.com/thirdweb-dev/js/actions/workflows/CI.yml/badge.svg"/></a> -->
<!-- <a href="https://discord.gg/thirdweb"><img alt="Join our Discord!" src="https://img.shields.io/discord/834227967404146718.svg?color=7289da&label=discord&logo=discord&style=flat"/></a> -->
<a href="https://www.npmjs.com/package/@thirdweb-dev/chains"><img src="https://img.shields.io/npm/v/@thirdweb-dev/chains?color=red&label=npm&logo=npm" alt="npm version"/></a>
<a href="https://github.com/thirdweb-dev/js/actions/workflows/build-test-lint.yml"><img alt="Build Status" src="https://github.com/thirdweb-dev/js/actions/workflows/build-test-lint.yml/badge.svg"/></a>
<a href="https://discord.gg/thirdweb"><img alt="Join our Discord!" src="https://img.shields.io/discord/834227967404146718.svg?color=7289da&label=discord&logo=discord&style=flat"/></a>
</p>
<!-- <p align="center"><strong>Best in class Web3 SDK for Browser, Node and Mobile apps</strong></p> -->
<br />
### todo
## Installation
```bash
yarn add @thirdweb-dev/chains
```
## Contributing
### Adding / Overriding Chain Data
Chain data is automatically pulled in from [ethereum-lists/chains](https://github.com/ethereum-lists/chains) on every build.
#### Overriding Chain Data
Chain data can be overridden by running `yarn override-chain` and following the prompts.
#### Adding A New Chain
In cases where a chain is not listed in the [ethereum-lists/chains](https://github.com/ethereum-lists/chains) repo, you can add it manually by running `yarn add-chain` and following the prompts.
> Prefer adding chains to the ethereum-lists/chains repo instead of manually adding them here.
+41
View File
@@ -0,0 +1,41 @@
export default {
"name": "Siberium Network",
"chain": "SBR",
"rpc": [
"https://siberium-network.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc.main.siberium.net",
"https://rpc.main.siberium.net.ru"
],
"faucets": [],
"nativeCurrency": {
"name": "Siberium",
"symbol": "SBR",
"decimals": 18
},
"infoURL": "https://siberium.net",
"shortName": "sbr",
"chainId": 111111,
"networkId": 111111,
"icon": {
"url": "ipfs://QmVDeoGo2TZPDWiaNDdPCnH2tz2BCQ7viw8ugdDWnU5LFq",
"width": 1920,
"height": 1920,
"format": "svg"
},
"explorers": [
{
"name": "Siberium Mainnet Explorer - blockscout - 1",
"url": "https://explorer.main.siberium.net",
"icon": "siberium",
"standard": "EIP3091"
},
{
"name": "Siberium Mainnet Explorer - blockscout - 2",
"url": "https://explorer.main.siberium.net.ru",
"icon": "siberium",
"standard": "EIP3091"
}
],
"testnet": false,
"slug": "siberium-network"
} as const;
+30
View File
@@ -0,0 +1,30 @@
export default {
"name": "HashBit Mainnet",
"chain": "HBIT",
"rpc": [
"https://hashbit.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://mainnet-rpc.hashbit.org",
"https://rpc.hashbit.org"
],
"faucets": [
"https://free-online-app.com/faucet-for-eth-evm-chains/"
],
"nativeCurrency": {
"name": "HashBit Native Token",
"symbol": "HBIT",
"decimals": 18
},
"infoURL": "https://hashbit.org",
"shortName": "hbit",
"chainId": 11119,
"networkId": 11119,
"explorers": [
{
"name": "hashbitscan",
"url": "https://explorer.hashbit.org",
"standard": "EIP3091"
}
],
"testnet": false,
"slug": "hashbit"
} as const;
+1
View File
@@ -5,6 +5,7 @@ export default {
"rpc": [
"https://sepolia.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc.sepolia.org",
"https://rpc2.sepolia.org",
"https://rpc-sepolia.rockx.com"
],
"faucets": [
+1 -1
View File
@@ -9,7 +9,7 @@ export default {
},
"rpc": [
"https://dogcoin.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://mainnet-rpc.dogcoin.network"
"https://mainnet-rpc.dogcoin.me"
],
"faucets": [
"https://faucet.dogcoin.network"
+6
View File
@@ -15,6 +15,12 @@ export default {
"shortName": "fuse",
"chainId": 122,
"networkId": 122,
"icon": {
"url": "ipfs://QmQg8aqyeaMfHvjzFDtZkb8dUNRYhFezPp8UYVc1HnLpRW/green.png",
"format": "png",
"width": 512,
"height": 512
},
"testnet": false,
"slug": "fuse"
} as const;
+6
View File
@@ -18,5 +18,11 @@ export default {
"chainId": 123,
"networkId": 123,
"testnet": true,
"icon": {
"url": "ipfs://QmQg8aqyeaMfHvjzFDtZkb8dUNRYhFezPp8UYVc1HnLpRW/green.png",
"format": "png",
"width": 512,
"height": 512
},
"slug": "fuse-sparknet"
} as const;
+33
View File
@@ -0,0 +1,33 @@
export default {
"name": "Fibonacci Mainnet",
"chain": "FIBO",
"icon": {
"url": "ipfs://bafkreidiedaz3jugxmh2ylzlc4nympbd5iwab33adhwkcnblyop6vvj25y",
"width": 1494,
"height": 1494,
"format": "png"
},
"rpc": [
"https://fibonacci.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://node1.fibo-api.asia"
],
"faucets": [],
"nativeCurrency": {
"name": "FIBONACCI UTILITY TOKEN",
"symbol": "FIBO",
"decimals": 18
},
"infoURL": "https://fibochain.org",
"shortName": "fibo",
"chainId": 12306,
"networkId": 1230,
"explorers": [
{
"name": "fiboscan",
"url": "https://scan.fibochain.org",
"standard": "EIP3091"
}
],
"testnet": false,
"slug": "fibonacci"
} as const;
+45
View File
@@ -0,0 +1,45 @@
export default {
"name": "Horizen Yuma Testnet",
"shortName": "Yuma",
"chain": "Yuma",
"icon": {
"url": "ipfs://QmSFMBk3rMyu45Sy9KQHjgArFj4HdywANNYrSosLMUdcti",
"width": 1213,
"height": 1213,
"format": "png"
},
"rpc": [
"https://horizen-yuma-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://yuma-testnet.horizenlabs.io/ethv1"
],
"features": [
{
"name": "EIP155"
},
{
"name": "EIP1559"
}
],
"faucets": [
"https://yuma-testnet-faucet.horizen.io"
],
"nativeCurrency": {
"name": "Testnet Zen",
"symbol": "tZEN",
"decimals": 18
},
"infoURL": "https://horizen.io/",
"chainId": 1662,
"networkId": 1662,
"slip44": 121,
"explorers": [
{
"name": "Yuma Testnet Block Explorer",
"url": "https://yuma-explorer.horizen.io",
"icon": "eon",
"standard": "EIP3091"
}
],
"testnet": true,
"slug": "horizen-yuma-testnet"
} as const;
+35
View File
@@ -0,0 +1,35 @@
export default {
"name": "Palette Chain Mainnet",
"chain": "PLT",
"rpc": [
"https://palette-chain.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://palette-rpc.com:22000"
],
"faucets": [],
"nativeCurrency": {
"name": "Palette Token",
"symbol": "PLT",
"decimals": 18
},
"features": [],
"infoURL": "https://hashpalette.com/",
"shortName": "PaletteChain",
"chainId": 1718,
"networkId": 1718,
"icon": {
"url": "ipfs://QmPCEGZD1p1keTT2YfPp725azx1r9Ci41hejeUuGL2whFA",
"width": 800,
"height": 800,
"format": "png"
},
"explorers": [
{
"name": "Palettescan",
"url": "https://palettescan.com",
"icon": "PLT",
"standard": "none"
}
],
"testnet": false,
"slug": "palette-chain"
} as const;
+33
View File
@@ -0,0 +1,33 @@
export default {
"name": "Bitcichain Mainnet",
"chain": "BITCI",
"icon": {
"url": "ipfs://QmbxmfWw5sVMASz5EbR1DCgLfk8PnqpSJGQKpYuEUpoxqn",
"width": 64,
"height": 64,
"format": "svg"
},
"rpc": [
"https://bitcichain.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc.bitci.com"
],
"faucets": [],
"nativeCurrency": {
"name": "Bitci",
"symbol": "BITCI",
"decimals": 18
},
"infoURL": "https://www.bitcichain.com",
"shortName": "bitci",
"chainId": 1907,
"networkId": 1907,
"explorers": [
{
"name": "Bitci Explorer",
"url": "https://bitciexplorer.com",
"standard": "EIP3091"
}
],
"testnet": false,
"slug": "bitcichain"
} as const;
+35
View File
@@ -0,0 +1,35 @@
export default {
"name": "Bitcichain Testnet",
"chain": "TBITCI",
"icon": {
"url": "ipfs://QmbxmfWw5sVMASz5EbR1DCgLfk8PnqpSJGQKpYuEUpoxqn",
"width": 64,
"height": 64,
"format": "svg"
},
"rpc": [
"https://bitcichain-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://testnet.bitcichain.com"
],
"faucets": [
"https://faucet.bitcichain.com"
],
"nativeCurrency": {
"name": "Test Bitci",
"symbol": "TBITCI",
"decimals": 18
},
"infoURL": "https://www.bitcichain.com",
"shortName": "tbitci",
"chainId": 1908,
"networkId": 1908,
"explorers": [
{
"name": "Bitci Explorer Testnet",
"url": "https://testnet.bitciexplorer.com",
"standard": "EIP3091"
}
],
"testnet": true,
"slug": "bitcichain-testnet"
} as const;
+6
View File
@@ -22,6 +22,12 @@ export default {
"standard": "none"
}
],
"icon": {
"url": "ipfs://Qmc9AJGg9aNhoH56n3deaZeUc8Ty1jDYJsW6Lu6hgSZH4S",
"height": 512,
"width": 512,
"format": "png"
},
"testnet": false,
"slug": "gather-network"
} as const;
+31
View File
@@ -0,0 +1,31 @@
export default {
"name": "Eleanor",
"title": "Metatime Testnet Eleanor",
"chain": "MTC",
"rpc": [
"https://eleanor.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc.metatime.com/eleanor",
"wss://ws.metatime.com/eleanor"
],
"faucets": [
"https://faucet.metatime.com/eleanor"
],
"nativeCurrency": {
"name": "Eleanor Metacoin",
"symbol": "MTC",
"decimals": 18
},
"infoURL": "https://eleanor.metatime.com",
"shortName": "mtc",
"chainId": 1967,
"networkId": 1967,
"explorers": [
{
"name": "metaexplorer-eleanor",
"url": "https://explorer.metatime.com/eleanor",
"standard": "EIP3091"
}
],
"testnet": true,
"slug": "eleanor"
} as const;
+2 -1
View File
@@ -3,7 +3,8 @@ export default {
"chain": "edeXa TestNetwork",
"rpc": [
"https://edexa-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://testnet.edexa.com/rpc"
"https://testnet.edexa.com/rpc",
"https://io-dataseed1.testnet.edexa.io-market.com/rpc"
],
"faucets": [
"https://faucet.edexa.com/"
+19
View File
@@ -0,0 +1,19 @@
export default {
"name": "Arevia",
"chain": "Arevia",
"rpc": [],
"faucets": [],
"nativeCurrency": {
"name": "Arev",
"symbol": "ARÉV",
"decimals": 18
},
"infoURL": "",
"shortName": "arevia",
"chainId": 2309,
"networkId": 2309,
"explorers": [],
"status": "incubating",
"testnet": false,
"slug": "arevia"
} as const;
+15
View File
@@ -29,6 +29,21 @@ export default {
"url": "https://filfox.info/en",
"standard": "none"
},
{
"name": "Beryx",
"url": "https://beryx.zondax.ch",
"standard": "none"
},
{
"name": "Glif Explorer",
"url": "https://explorer.glif.io",
"standard": "EIP3091"
},
{
"name": "Filmine",
"url": "https://explorer.filmine.io",
"standard": "none"
},
{
"name": "Filscan",
"url": "https://filscan.io",
+1
View File
@@ -10,6 +10,7 @@ export default {
"rpc": [
"https://filecoin-hyperspace-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://api.hyperspace.node.glif.io/rpc/v1",
"https://rpc.ankr.com/filecoin_testnet",
"https://filecoin-hyperspace.chainstacklabs.com/rpc/v1"
],
"faucets": [
+9 -1
View File
@@ -5,7 +5,9 @@ export default {
"https://gather-testnet-network.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://testnet.gather.network"
],
"faucets": [],
"faucets": [
"https://testnet-faucet.gather.network/"
],
"nativeCurrency": {
"name": "Gather",
"symbol": "GTH",
@@ -23,5 +25,11 @@ export default {
}
],
"testnet": true,
"icon": {
"url": "ipfs://Qmc9AJGg9aNhoH56n3deaZeUc8Ty1jDYJsW6Lu6hgSZH4S",
"height": 512,
"width": 512,
"format": "png"
},
"slug": "gather-testnet-network"
} as const;
+35
View File
@@ -0,0 +1,35 @@
export default {
"name": "Tipboxcoin Mainnet",
"chain": "TPBX",
"icon": {
"url": "ipfs://QmbiaHnR3fVVofZ7Xq2GYZxwHkLEy3Fh5qDtqnqXD6ACAh",
"width": 192,
"height": 192,
"format": "png"
},
"rpc": [
"https://tipboxcoin.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://mainnet-rpc.tipboxcoin.net"
],
"faucets": [
"https://faucet.tipboxcoin.net"
],
"nativeCurrency": {
"name": "Tipboxcoin",
"symbol": "TPBX",
"decimals": 18
},
"infoURL": "https://tipboxcoin.net",
"shortName": "TPBXm",
"chainId": 404040,
"networkId": 404040,
"explorers": [
{
"name": "Tipboxcoin",
"url": "https://tipboxcoin.net",
"standard": "EIP3091"
}
],
"testnet": false,
"slug": "tipboxcoin"
} as const;
+33
View File
@@ -0,0 +1,33 @@
export default {
"name": "Nahmii 3 Mainnet",
"chain": "Nahmii",
"rpc": [],
"status": "incubating",
"faucets": [],
"nativeCurrency": {
"name": "Ether",
"symbol": "ETH",
"decimals": 18
},
"infoURL": "https://nahmii.io",
"shortName": "Nahmii3Mainnet",
"chainId": 4061,
"networkId": 4061,
"icon": {
"url": "ipfs://QmZhKXgoGpzvthr2eh8ZNgT75YvMtEBegdELAaMPPzf5QT",
"width": 384,
"height": 384,
"format": "png"
},
"parent": {
"type": "L2",
"chain": "eip155-1",
"bridges": [
{
"url": "https://bridge.nahmii.io"
}
]
},
"testnet": false,
"slug": "nahmii-3"
} as const;
+43
View File
@@ -0,0 +1,43 @@
export default {
"name": "Nahmii 3 Testnet",
"chain": "Nahmii",
"rpc": [
"https://nahmii-3-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://ngeth.testnet.n3.nahmii.io"
],
"faucets": [],
"nativeCurrency": {
"name": "Goerli Ether",
"symbol": "ETH",
"decimals": 18
},
"infoURL": "https://nahmii.io",
"shortName": "Nahmii3Testnet",
"chainId": 4062,
"networkId": 4062,
"icon": {
"url": "ipfs://QmZhKXgoGpzvthr2eh8ZNgT75YvMtEBegdELAaMPPzf5QT",
"width": 384,
"height": 384,
"format": "png"
},
"explorers": [
{
"name": "Nahmii 3 Testnet Explorer",
"url": "https://explorer.testnet.n3.nahmii.io",
"icon": "nahmii",
"standard": "EIP3091"
}
],
"parent": {
"type": "L2",
"chain": "eip155-3",
"bridges": [
{
"url": "https://bridge.testnet.n3.nahmii.io"
}
]
},
"testnet": true,
"slug": "nahmii-3-testnet"
} as const;
+35
View File
@@ -0,0 +1,35 @@
export default {
"name": "Tipboxcoin Testnet",
"chain": "TPBX",
"icon": {
"url": "ipfs://QmbiaHnR3fVVofZ7Xq2GYZxwHkLEy3Fh5qDtqnqXD6ACAh",
"width": 192,
"height": 192,
"format": "png"
},
"rpc": [
"https://tipboxcoin-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://testnet-rpc.tipboxcoin.net"
],
"faucets": [
"https://faucet.tipboxcoin.net"
],
"nativeCurrency": {
"name": "Tipboxcoin",
"symbol": "TPBX",
"decimals": 18
},
"infoURL": "https://tipboxcoin.net",
"shortName": "TPBXt",
"chainId": 4141,
"networkId": 4141,
"explorers": [
{
"name": "Tipboxcoin",
"url": "https://testnet.tipboxcoin.net",
"standard": "EIP3091"
}
],
"testnet": true,
"slug": "tipboxcoin-testnet"
} as const;
+30
View File
@@ -0,0 +1,30 @@
export default {
"name": "BeanEco SmartChain",
"title": "BESC Mainnet",
"chain": "BESC",
"rpc": [
"https://beaneco-smartchain.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://mainnet-rpc.bescscan.io"
],
"faucets": [
"faucet.bescscan.ion"
],
"nativeCurrency": {
"name": "BeanEco SmartChain",
"symbol": "BESC",
"decimals": 18
},
"infoURL": "besceco.finance",
"shortName": "BESC",
"chainId": 535037,
"networkId": 535037,
"explorers": [
{
"name": "bescscan",
"url": "https://Bescscan.io",
"standard": "EIP3091"
}
],
"testnet": false,
"slug": "beaneco-smartchain"
} as const;
+5 -4
View File
@@ -1,6 +1,7 @@
export default {
"name": "Hika Devnet",
"chain": "Hika Network Testnet",
"name": "Hika Network Testnet",
"title": "Hika Network Testnet",
"chain": "HIK",
"icon": {
"url": "ipfs://QmW44FPm3CMM2JDs8BQxLNvUtykkUtrGkQkQsUDJSi3Gmp",
"width": 350,
@@ -8,7 +9,7 @@ export default {
"format": "png"
},
"rpc": [
"https://hika-devnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://hika-network-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc-testnet.hika.network/"
],
"faucets": [],
@@ -29,5 +30,5 @@ export default {
}
],
"testnet": true,
"slug": "hika-devnet"
"slug": "hika-network-testnet"
} as const;
+6
View File
@@ -18,6 +18,12 @@ export default {
"shortName": "bakerloo-0",
"chainId": 65010000,
"networkId": 65010000,
"icon": {
"url": "ipfs://Qme5nxFZZoNNpiT8u9WwcBot4HyLTg2jxMxRnsbc5voQwB",
"width": 1000,
"height": 1000,
"format": "png"
},
"explorers": [
{
"name": "autonity-blockscout",
+6
View File
@@ -18,6 +18,12 @@ export default {
"shortName": "piccadilly-0",
"chainId": 65100000,
"networkId": 65100000,
"icon": {
"url": "ipfs://Qme5nxFZZoNNpiT8u9WwcBot4HyLTg2jxMxRnsbc5voQwB",
"width": 1000,
"height": 1000,
"format": "png"
},
"explorers": [
{
"name": "autonity-blockscout",
-27
View File
@@ -1,27 +0,0 @@
export default {
"name": "SiriusNet",
"chain": "SIN",
"rpc": [
"https://siriusnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://u0tnafcv6j:o2T045sxuCNXL878RDQLp5__Zj-es2cvdjtgkl4etn0@u0v7kwtvtg-u0wj114sve-rpc.us0-aws.kaleido.io/"
],
"faucets": [],
"nativeCurrency": {
"name": "MCD",
"symbol": "MCD",
"decimals": 18
},
"infoURL": "https://macaucasinolisboa.xyz",
"shortName": "mcl",
"chainId": 67390,
"networkId": 67390,
"explorers": [
{
"name": "siriusnetscan",
"url": "https://siriusnet.tryethernal.com",
"standard": "EIP3091"
}
],
"testnet": false,
"slug": "siriusnet"
} as const;
+37
View File
@@ -0,0 +1,37 @@
export default {
"name": "KLYNTAR",
"chain": "KLY",
"rpc": [
"https://klyntar.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://evm.klyntar.org/kly_evm_rpc",
"https://evm.klyntarscan.org/kly_evm_rpc"
],
"faucets": [],
"nativeCurrency": {
"name": "KLYNTAR",
"symbol": "KLY",
"decimals": 18
},
"features": [
{
"name": "EIP155"
},
{
"name": "EIP1559"
}
],
"infoURL": "https://klyntar.org",
"shortName": "kly",
"chainId": 7331,
"networkId": 7331,
"icon": {
"url": "ipfs://QmaDr9R6dKnZLsogRxojjq4dwXuXcudR8UeTZ8Nq553K4u",
"width": 400,
"height": 400,
"format": "png"
},
"explorers": [],
"status": "incubating",
"testnet": false,
"slug": "klyntar"
} as const;
+14
View File
@@ -3,6 +3,9 @@ export default {
"chain": "KLAY",
"rpc": [
"https://klaytn-cypress.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://klaytn.blockpi.network/v1/rpc/public",
"https://klaytn-mainnet-rpc.allthatnode.com:8551",
"https://public-en-cypress.klaytn.net",
"https://public-node-api.klaytnapi.com/v1/cypress"
],
"faucets": [],
@@ -17,12 +20,23 @@ export default {
"networkId": 8217,
"slip44": 8217,
"explorers": [
{
"name": "klaytnfinder",
"url": "https://www.klaytnfinder.io/",
"standard": "none"
},
{
"name": "Klaytnscope",
"url": "https://scope.klaytn.com",
"standard": "none"
}
],
"icon": {
"format": "png",
"url": "ipfs://bafkreigtgdivlmfvf7trqjqy4vkz2d26xk3iif6av265v4klu5qavsugm4",
"height": 1000,
"width": 1000
},
"testnet": false,
"slug": "klaytn-cypress"
} as const;
+24
View File
@@ -0,0 +1,24 @@
export default {
"name": "Base",
"chain": "ETH",
"rpc": [],
"faucets": [],
"nativeCurrency": {
"name": "Ether",
"symbol": "ETH",
"decimals": 18
},
"infoURL": "https://base.org",
"shortName": "base",
"chainId": 8453,
"networkId": 8453,
"status": "incubating",
"icon": {
"url": "ipfs://QmW5Vn15HeRkScMfPcW12ZdZcC2yUASpu6eCsECRdEmjjj/base-512.png",
"height": 512,
"width": 512,
"format": "png"
},
"testnet": false,
"slug": "base"
} as const;
+40
View File
@@ -0,0 +1,40 @@
export default {
"name": "Base Goerli Testnet",
"chain": "ETH",
"rpc": [
"https://base-goerli.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://goerli.base.org"
],
"faucets": [
"https://www.coinbase.com/faucets/base-ethereum-goerli-faucet"
],
"nativeCurrency": {
"name": "Goerli Ether",
"symbol": "ETH",
"decimals": 18
},
"infoURL": "https://base.org",
"shortName": "basegor",
"chainId": 84531,
"networkId": 84531,
"explorers": [
{
"name": "basescout",
"url": "https://base-goerli.blockscout.com",
"standard": "none"
},
{
"name": "basescan",
"url": "https://goerli.basescan.org",
"standard": "none"
}
],
"testnet": true,
"icon": {
"url": "ipfs://QmW5Vn15HeRkScMfPcW12ZdZcC2yUASpu6eCsECRdEmjjj/base-512.png",
"height": 512,
"width": 512,
"format": "png"
},
"slug": "base-goerli"
} as const;
+1 -1
View File
@@ -9,7 +9,7 @@ export default {
},
"rpc": [
"https://dogcoin-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://testnet-rpc.dogcoin.network"
"https://testnet-rpc.dogcoin.me"
],
"faucets": [
"https://faucet.dogcoin.network"
+27
View File
@@ -0,0 +1,27 @@
// @ts-check
/** @typedef { import("../../src/types").Chain } Chain */
/** @type {Omit<Chain, "slug">} */
export default {
name: "Localhost",
chain: "ETH",
rpc: ["http://localhost:8545"],
faucets: [],
nativeCurrency: {
name: "Ether",
symbol: "ETH",
decimals: 18,
},
// hard code eth icon for now
icon: {
url: "ipfs://QmcxZHpyJa8T4i63xqjPYrZ6tKrt55tZJpbXcjSDKuKaf9/ethereum/512.png",
height: 512,
width: 512,
format: "png",
sizes: [16, 32, 64, 128, 256, 512],
},
shortName: "local",
chainId: 1337,
networkId: 1337,
testnet: true,
};
+14
View File
@@ -0,0 +1,14 @@
// @ts-check
/** @typedef { import("../../src/types").Chain } Chain */
/** @type {Partial<Chain>} */
export default {
icon: {
url: "ipfs://QmcxZHpyJa8T4i63xqjPYrZ6tKrt55tZJpbXcjSDKuKaf9/ethereum/512.png",
height: 512,
width: 512,
format: "png",
sizes: [16, 32, 64, 128, 256, 512],
},
rpc: ["https://eth-mainnet.g.alchemy.com/v2/${ALCHEMY_API_KEY}"],
};
+17
View File
@@ -0,0 +1,17 @@
// @ts-check
/** @typedef { import("../../src/types").Chain } Chain */
/** @type {Partial<Chain>} */
export default {
icon: {
url: "ipfs://QmcxZHpyJa8T4i63xqjPYrZ6tKrt55tZJpbXcjSDKuKaf9/optimism/512.png",
height: 512,
width: 512,
format: "png",
sizes: [16, 32, 64, 128, 256, 512],
},
rpc: [
"https://optimism-mainnet.infura.io/v3/${INFURA_API_KEY}",
"https://opt-mainnet.g.alchemy.com/v2/${ALCHEMY_API_KEY}",
],
};
+13
View File
@@ -0,0 +1,13 @@
// @ts-check
/** @typedef { import("../../src/types").Chain } Chain */
/** @type {Partial<Chain>} */
export default {
chainId: 122,
icon: {
url: "ipfs://QmQg8aqyeaMfHvjzFDtZkb8dUNRYhFezPp8UYVc1HnLpRW/green.png",
format: "png",
width: 512,
height: 512,
},
};
+14
View File
@@ -0,0 +1,14 @@
// @ts-check
/** @typedef { import("../../src/types").Chain } Chain */
/** @type {Partial<Chain>} */
export default {
chainId: 123,
testnet: true,
icon: {
url: "ipfs://QmQg8aqyeaMfHvjzFDtZkb8dUNRYhFezPp8UYVc1HnLpRW/green.png",
format: "png",
width: 512,
height: 512,
},
};
+17
View File
@@ -0,0 +1,17 @@
// @ts-check
/** @typedef { import("../../src/types").Chain } Chain */
/** @type {Partial<Chain>} */
export default {
icon: {
url: "ipfs://QmcxZHpyJa8T4i63xqjPYrZ6tKrt55tZJpbXcjSDKuKaf9/polygon/512.png",
height: 512,
width: 512,
format: "png",
sizes: [16, 32, 64, 128, 256, 512],
},
rpc: [
"https://polygon-mainnet.infura.io/v3/${INFURA_API_KEY}",
"https://polygon-mainnet.g.alchemy.com/v2/${ALCHEMY_API_KEY}",
],
};
@@ -0,0 +1,13 @@
// @ts-check
/** @typedef { import("../../src/types").Chain } Chain */
/** @type {Partial<Chain>} */
export default {
chainId: 192837465,
icon: {
url: "ipfs://Qmc9AJGg9aNhoH56n3deaZeUc8Ty1jDYJsW6Lu6hgSZH4S",
height: 512,
width: 512,
format: "png",
},
};
+13
View File
@@ -0,0 +1,13 @@
// @ts-check
/** @typedef { import("../../src/types").Chain } Chain */
/** @type {Partial<Chain>} */
export default {
icon: {
url: "ipfs://QmcxZHpyJa8T4i63xqjPYrZ6tKrt55tZJpbXcjSDKuKaf9/fantom/512.png",
height: 512,
width: 512,
format: "png",
sizes: [16, 32, 64, 128, 256, 512],
},
};
@@ -0,0 +1,15 @@
// @ts-check
/** @typedef { import("../../src/types").Chain } Chain */
/** @type {Partial<Chain>} */
export default {
chainId: 356256156,
testnet: true,
icon: {
url: "ipfs://Qmc9AJGg9aNhoH56n3deaZeUc8Ty1jDYJsW6Lu6hgSZH4S",
height: 512,
width: 512,
format: "png",
},
faucets: ["https://testnet-faucet.gather.network/"],
};
+13
View File
@@ -0,0 +1,13 @@
// @ts-check
/** @typedef { import("../../src/types").Chain } Chain */
/** @type {Partial<Chain>} */
export default {
icon: {
url: "ipfs://QmcxZHpyJa8T4i63xqjPYrZ6tKrt55tZJpbXcjSDKuKaf9/fantom/512.png",
height: 512,
width: 512,
format: "png",
sizes: [16, 32, 64, 128, 256, 512],
},
};
+17
View File
@@ -0,0 +1,17 @@
// @ts-check
/** @typedef { import("../../src/types").Chain } Chain */
/** @type {Partial<Chain>} */
export default {
icon: {
url: "ipfs://QmcxZHpyJa8T4i63xqjPYrZ6tKrt55tZJpbXcjSDKuKaf9/optimism/512.png",
height: 512,
width: 512,
format: "png",
sizes: [16, 32, 64, 128, 256, 512],
},
rpc: [
"https://optimism-goerli.infura.io/v3/${INFURA_API_KEY}",
"https://opt-goerli.g.alchemy.com/v2/${ALCHEMY_API_KEY}",
],
};
+14
View File
@@ -0,0 +1,14 @@
// @ts-check
/** @typedef { import("../../src/types").Chain } Chain */
/** @type {Partial<Chain>} */
export default {
icon: {
url: "ipfs://QmcxZHpyJa8T4i63xqjPYrZ6tKrt55tZJpbXcjSDKuKaf9/arbitrum/512.png",
height: 512,
width: 512,
format: "png",
sizes: [16, 32, 64, 128, 256, 512],
},
rpc: ["https://arb-mainnet.g.alchemy.com/v2/${ALCHEMY_API_KEY}"],
};
+17
View File
@@ -0,0 +1,17 @@
// @ts-check
/** @typedef { import("../../src/types").Chain } Chain */
/** @type {Partial<Chain>} */
export default {
icon: {
url: "ipfs://QmcxZHpyJa8T4i63xqjPYrZ6tKrt55tZJpbXcjSDKuKaf9/arbitrum/512.png",
height: 512,
width: 512,
format: "png",
sizes: [16, 32, 64, 128, 256, 512],
},
rpc: [
"https://abritrum-goerli.infura.io/v3/${INFURA_API_KEY}",
"https://arb-goerli.g.alchemy.com/v2/${ALCHEMY_API_KEY}",
],
};
+14
View File
@@ -0,0 +1,14 @@
// @ts-check
/** @typedef { import("../../src/types").Chain } Chain */
/** @type {Partial<Chain>} */
export default {
icon: {
url: "ipfs://QmcxZHpyJa8T4i63xqjPYrZ6tKrt55tZJpbXcjSDKuKaf9/avalanche/512.png",
height: 512,
width: 512,
format: "png",
sizes: [16, 32, 64, 128, 256, 512],
},
rpc: ["https://avalanche-fuji.infura.io/v3/${INFURA_API_KEY}"],
};
+14
View File
@@ -0,0 +1,14 @@
// @ts-check
/** @typedef { import("../../src/types").Chain } Chain */
/** @type {Partial<Chain>} */
export default {
icon: {
url: "ipfs://QmcxZHpyJa8T4i63xqjPYrZ6tKrt55tZJpbXcjSDKuKaf9/avalanche/512.png",
height: 512,
width: 512,
format: "png",
sizes: [16, 32, 64, 128, 256, 512],
},
rpc: ["https://avalanche-mainnet.infura.io/v3/${INFURA_API_KEY}"],
};
+14
View File
@@ -0,0 +1,14 @@
// @ts-check
/** @typedef { import("../../src/types").Chain } Chain */
/** @type {Partial<Chain>} */
export default {
icon: {
url: "ipfs://QmcxZHpyJa8T4i63xqjPYrZ6tKrt55tZJpbXcjSDKuKaf9/ethereum/512.png",
height: 512,
width: 512,
format: "png",
sizes: [16, 32, 64, 128, 256, 512],
},
rpc: ["https://eth-goerli.g.alchemy.com/v2/${ALCHEMY_API_KEY}"],
};
+13
View File
@@ -0,0 +1,13 @@
// @ts-check
/** @typedef { import("../../src/types").Chain } Chain */
/** @type {Partial<Chain>} */
export default {
icon: {
url: "ipfs://QmcxZHpyJa8T4i63xqjPYrZ6tKrt55tZJpbXcjSDKuKaf9/binance-coin/512.png",
height: 512,
width: 512,
format: "png",
sizes: [16, 32, 64, 128, 256, 512],
},
};
+17
View File
@@ -0,0 +1,17 @@
// @ts-check
/** @typedef { import("../../src/types").Chain } Chain */
/** @type {Partial<Chain>} */
export default {
icon: {
url: "ipfs://QmcxZHpyJa8T4i63xqjPYrZ6tKrt55tZJpbXcjSDKuKaf9/polygon/512.png",
height: 512,
width: 512,
format: "png",
sizes: [16, 32, 64, 128, 256, 512],
},
rpc: [
"https://polygon-mumbai.infura.io/v3/${INFURA_API_KEY}",
"https://polygon-mumbai.g.alchemy.com/v2/${ALCHEMY_API_KEY}",
],
};
+25
View File
@@ -0,0 +1,25 @@
// @ts-check
/** @typedef { import("../../src/types").Chain } Chain */
/** @type {Partial<Chain>} */
export default {
chainId: 8217,
rpc: [
"https://public-en-cypress.klaytn.net",
"https://klaytn-mainnet-rpc.allthatnode.com:8551",
"https://klaytn.blockpi.network/v1/rpc/public",
],
explorers: [
{
name: "klaytnfinder",
url: "https://www.klaytnfinder.io/",
standard: "none",
},
],
icon: {
format: "png",
url: "ipfs://bafkreigtgdivlmfvf7trqjqy4vkz2d26xk3iif6av265v4klu5qavsugm4",
height: 1000,
width: 1000,
},
};
+13
View File
@@ -0,0 +1,13 @@
// @ts-check
/** @typedef { import("../../src/types").Chain } Chain */
/** @type {Partial<Chain>} */
export default {
chainId: 8453,
icon: {
url: "ipfs://QmW5Vn15HeRkScMfPcW12ZdZcC2yUASpu6eCsECRdEmjjj/base-512.png",
height: 512,
width: 512,
format: "png",
},
};
+14
View File
@@ -0,0 +1,14 @@
// @ts-check
/** @typedef { import("../../src/types").Chain } Chain */
/** @type {Partial<Chain>} */
export default {
chainId: 84531,
testnet: true,
icon: {
url: "ipfs://QmW5Vn15HeRkScMfPcW12ZdZcC2yUASpu6eCsECRdEmjjj/base-512.png",
height: 512,
width: 512,
format: "png",
},
};
+13
View File
@@ -0,0 +1,13 @@
// @ts-check
/** @typedef { import("../../src/types").Chain } Chain */
/** @type {Partial<Chain>} */
export default {
icon: {
url: "ipfs://QmcxZHpyJa8T4i63xqjPYrZ6tKrt55tZJpbXcjSDKuKaf9/binance-coin/512.png",
height: 512,
width: 512,
format: "png",
sizes: [16, 32, 64, 128, 256, 512],
},
};
-153
View File
@@ -1,153 +0,0 @@
{
"1": {
"icon": {
"url": "ipfs://QmcxZHpyJa8T4i63xqjPYrZ6tKrt55tZJpbXcjSDKuKaf9/ethereum/512.png",
"height": 512,
"width": 512,
"format": "png",
"sizes": [16, 32, 64, 128, 256, 512]
},
"rpc": ["https://eth-mainnet.g.alchemy.com/v2/${ALCHEMY_API_KEY}"]
},
"5": {
"icon": {
"url": "ipfs://QmcxZHpyJa8T4i63xqjPYrZ6tKrt55tZJpbXcjSDKuKaf9/ethereum/512.png",
"height": 512,
"width": 512,
"format": "png",
"sizes": [16, 32, 64, 128, 256, 512]
},
"rpc": ["https://eth-goerli.g.alchemy.com/v2/${ALCHEMY_API_KEY}"]
},
"137": {
"icon": {
"url": "ipfs://QmcxZHpyJa8T4i63xqjPYrZ6tKrt55tZJpbXcjSDKuKaf9/polygon/512.png",
"height": 512,
"width": 512,
"format": "png",
"sizes": [16, 32, 64, 128, 256, 512]
},
"rpc": [
"https://polygon-mainnet.infura.io/v3/${INFURA_API_KEY}",
"https://polygon-mainnet.g.alchemy.com/v2/${ALCHEMY_API_KEY}"
]
},
"80001": {
"icon": {
"url": "ipfs://QmcxZHpyJa8T4i63xqjPYrZ6tKrt55tZJpbXcjSDKuKaf9/polygon/512.png",
"height": 512,
"width": 512,
"format": "png",
"sizes": [16, 32, 64, 128, 256, 512]
},
"rpc": [
"https://polygon-mumbai.infura.io/v3/${INFURA_API_KEY}",
"https://polygon-mumbai.g.alchemy.com/v2/${ALCHEMY_API_KEY}"
]
},
"250": {
"icon": {
"url": "ipfs://QmcxZHpyJa8T4i63xqjPYrZ6tKrt55tZJpbXcjSDKuKaf9/fantom/512.png",
"height": 512,
"width": 512,
"format": "png",
"sizes": [16, 32, 64, 128, 256, 512]
}
},
"4002": {
"icon": {
"url": "ipfs://QmcxZHpyJa8T4i63xqjPYrZ6tKrt55tZJpbXcjSDKuKaf9/fantom/512.png",
"height": 512,
"width": 512,
"format": "png",
"sizes": [16, 32, 64, 128, 256, 512]
}
},
"43114": {
"icon": {
"url": "ipfs://QmcxZHpyJa8T4i63xqjPYrZ6tKrt55tZJpbXcjSDKuKaf9/avalanche/512.png",
"height": 512,
"width": 512,
"format": "png",
"sizes": [16, 32, 64, 128, 256, 512]
},
"rpc": ["https://avalanche-mainnet.infura.io/v3/${INFURA_API_KEY}"]
},
"43113": {
"icon": {
"url": "ipfs://QmcxZHpyJa8T4i63xqjPYrZ6tKrt55tZJpbXcjSDKuKaf9/avalanche/512.png",
"height": 512,
"width": 512,
"format": "png",
"sizes": [16, 32, 64, 128, 256, 512]
},
"rpc": ["https://avalanche-fuji.infura.io/v3/${INFURA_API_KEY}"]
},
"10": {
"icon": {
"url": "ipfs://QmcxZHpyJa8T4i63xqjPYrZ6tKrt55tZJpbXcjSDKuKaf9/optimism/512.png",
"height": 512,
"width": 512,
"format": "png",
"sizes": [16, 32, 64, 128, 256, 512]
},
"rpc": [
"https://optimism-mainnet.infura.io/v3/${INFURA_API_KEY}",
"https://opt-mainnet.g.alchemy.com/v2/${ALCHEMY_API_KEY}"
]
},
"420": {
"icon": {
"url": "ipfs://QmcxZHpyJa8T4i63xqjPYrZ6tKrt55tZJpbXcjSDKuKaf9/optimism/512.png",
"height": 512,
"width": 512,
"format": "png",
"sizes": [16, 32, 64, 128, 256, 512]
},
"rpc": [
"https://optimism-goerli.infura.io/v3/${INFURA_API_KEY}",
"https://opt-goerli.g.alchemy.com/v2/${ALCHEMY_API_KEY}"
]
},
"42161": {
"icon": {
"url": "ipfs://QmcxZHpyJa8T4i63xqjPYrZ6tKrt55tZJpbXcjSDKuKaf9/arbitrum/512.png",
"height": 512,
"width": 512,
"format": "png",
"sizes": [16, 32, 64, 128, 256, 512]
},
"rpc": ["https://arb-mainnet.g.alchemy.com/v2/${ALCHEMY_API_KEY}"]
},
"421613": {
"icon": {
"url": "ipfs://QmcxZHpyJa8T4i63xqjPYrZ6tKrt55tZJpbXcjSDKuKaf9/arbitrum/512.png",
"height": 512,
"width": 512,
"format": "png",
"sizes": [16, 32, 64, 128, 256, 512]
},
"rpc": [
"https://abritrum-goerli.infura.io/v3/${INFURA_API_KEY}",
"https://arb-goerli.g.alchemy.com/v2/${ALCHEMY_API_KEY}"
]
},
"56": {
"icon": {
"url": "ipfs://QmcxZHpyJa8T4i63xqjPYrZ6tKrt55tZJpbXcjSDKuKaf9/binance-coin/512.png",
"height": 512,
"width": 512,
"format": "png",
"sizes": [16, 32, 64, 128, 256, 512]
}
},
"97": {
"icon": {
"url": "ipfs://QmcxZHpyJa8T4i63xqjPYrZ6tKrt55tZJpbXcjSDKuKaf9/binance-coin/512.png",
"height": 512,
"width": 512,
"format": "png",
"sizes": [16, 32, 64, 128, 256, 512]
}
}
}
+8 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/chains",
"version": "0.1.3",
"version": "0.1.6",
"main": "dist/thirdweb-dev-chains.cjs.js",
"module": "dist/thirdweb-dev-chains.esm.js",
"exports": {
@@ -18,6 +18,8 @@
"author": "thirdweb eng <[email protected]>",
"devDependencies": {
"axios": "^0.27.2",
"jest": "^29.4.3",
"plop": "^3.1.2",
"typescript": "^4.7.4"
},
"preconstruct": {
@@ -29,6 +31,10 @@
"sideEffects": false,
"scripts": {
"build": "node ./scripts/generate-package.mjs && tsc && preconstruct build",
"push": "yalc push"
"push": "yalc push",
"plop": "plop",
"add-chain": "plop add-chain",
"override-chain": "plop override-chain",
"test": "jest"
}
}
@@ -0,0 +1,11 @@
// @ts-check
/** @typedef { import("../../src/types").Chain } Chain */
/** @type {Omit<Chain, "slug">} */
export default {
{{> namePartial}}
{{> chainPartial}}
{{> shortNamePartial}}
{{> chainIdPartial}}
{{> isTestnetPartial}}
};
@@ -0,0 +1,22 @@
// @ts-check
/** @typedef { import("../../src/types").Chain } Chain */
/** @type {Partial<Chain>} */
export default {
{{!-- if we have a name --}}
{{#if name}}
{{> namePartial}}
{{/if}}
{{!-- if we have a chain --}}
{{#if chain}}
{{> chainPartial}}
{{/if}}
{{#if shortName}}
{{> shortNamePartial}}
{{/if}}
{{!-- chainId always exists --}}
{{> chainIdPartial}}
{{#if isTestnet}}
{{> isTestnetPartial}}
{{/if}}
};
+80
View File
@@ -0,0 +1,80 @@
const chainIdPrompt = {
type: "number",
name: "chainId",
message: "Chain ID",
validate: (value) => {
if (value.length === 0) {
return "ChainId is required";
}
if (!/^\d+$/.test(value)) {
return "ChainId must be a number";
}
return true;
},
};
const stringPrompt = (id, title, isRequired) => ({
type: "input",
name: id,
message: title,
validate: (value) => {
if (isRequired && value.length === 0) {
return `${title} is required`;
}
return true;
},
});
const testnetPrompt = {
type: "confirm",
name: "isTestnet",
message: "Is this a testnet?",
};
export default function (
/** @type {import('plop').NodePlopAPI} */
plop,
) {
// add partials
plop.setPartial("chainIdPartial", "chainId: {{chainId}},\n");
plop.setPartial("namePartial", `name: "{{name}}",\n`);
plop.setPartial("chainPartial", `chain: "{{chain}}",\n`);
plop.setPartial("shortNamePartial", `shortName: "{{shortName}}",\n`);
plop.setPartial("isTestnetPartial", `testnet: {{isTestnet}},\n`);
plop.setGenerator("add-chain", {
description: "add a new chain",
prompts: [
chainIdPrompt,
stringPrompt("name", "Name", true),
stringPrompt("chain", "Chain", true),
stringPrompt("shortName", "Short Name", true),
testnetPrompt,
],
actions: [
{
type: "add",
path: "data/additional/{{chainId}}.mjs",
templateFile: "plop-templates/add-chain.hbs",
},
],
});
plop.setGenerator("override-chain", {
description: "add an override for a chain",
prompts: [
chainIdPrompt,
stringPrompt("name", "Name"),
stringPrompt("chain", "Chain"),
stringPrompt("shortName", "Short Name"),
testnetPrompt,
],
actions: [
{
type: "add",
path: "data/overrides/{{chainId}}.mjs",
templateFile: "plop-templates/chain-override.hbs",
},
],
});
}
+58 -32
View File
@@ -1,11 +1,15 @@
// @ts-check
import axios from "axios";
import merge from "deepmerge";
import fs from "fs";
import path from "path";
const combineMerge = (target, source, options) => {
/** @typedef {import("../src/types").Chain} Chain */
const combineMerge = (target, source) => {
let destination = target.slice();
source.forEach((item, index) => {
source.forEach((item) => {
if (target.indexOf(item) === -1) {
destination = [item, ...destination];
}
@@ -15,16 +19,43 @@ const combineMerge = (target, source, options) => {
const chainsDir = "./chains";
/** @typedef {{name: string, chain: string, icon: string, rpc: string[], faucets?: any[], nativeCurrency: {name: string, symbol: string, decimals: number}, infoURL?: string, shortName: string, chainId: number, networkId: number, slip44?: number, ens: {registry: string}, explorers?: {name: string, url: string, standard: string}[] }} Chain */
const chainsJsonUrl = "https://chainid.network/chains.json";
const iconRoute =
"https://raw.githubusercontent.com/ethereum-lists/chains/master/_data/icons";
const overrides = JSON.parse(fs.readFileSync("./overrides.json"));
/** @type {Record<number, Partial<Chain>>} */
let overrides = {};
// get all overides by reading the overrides directory and importing them
const overridesDir = path.join(process.cwd(), "./data/overrides");
const overridesFiles = fs.readdirSync(overridesDir);
for (const file of overridesFiles) {
// file:// is required for windows builds
const override = await import(path.join("file://", overridesDir, file));
// get file name without extension
const chainId = parseInt(file.split(".")[0]);
overrides[chainId] = override.default;
}
// chains from remote src
/** @type {Chain[]} */
let chains = (await axios.get(chainsJsonUrl)).data;
// immediately filter out localhost
chains = chains.filter((c) => c.chainId !== 1337);
// additional chains
// get all additional chains by reading the additional chains directory and importing them
const additionalChainsDir = path.join(process.cwd(), "./data/additional");
const additionalChainsFiles = fs.readdirSync(additionalChainsDir);
for (const file of additionalChainsFiles) {
// file:// is required for windows builds
const additionalChain = await import(
path.join("file://", additionalChainsDir, file)
);
chains.push(additionalChain.default);
}
chains = chains
.filter((c) => c.status !== "deprecated")
@@ -44,32 +75,6 @@ chains = chains
};
});
chains = chains.filter((c) => c.chainId !== 1337);
// inject in localhost
chains.push({
name: "Localhost",
chain: "ETH",
rpc: ["http://localhost:8545"],
faucets: [],
nativeCurrency: {
name: "Ether",
symbol: "ETH",
decimals: 18,
},
// hard code eth icon for now
icon: {
url: "ipfs://QmcxZHpyJa8T4i63xqjPYrZ6tKrt55tZJpbXcjSDKuKaf9/ethereum/512.png",
height: 512,
width: 512,
format: "png",
sizes: [16, 32, 64, 128, 256, 512],
},
shortName: "local",
chainId: 1337,
networkId: 1337,
testnet: true,
});
const imports = [];
const exports = [];
const exportNames = [];
@@ -118,6 +123,9 @@ function findSlug(chain) {
if (slug === "binance-smart-chain-testnet") {
slug = "binance-testnet";
}
if (slug === "base-goerli-testnet") {
slug = "base-goerli";
}
// end special cases
takenSlugs[slug] = true;
@@ -202,5 +210,23 @@ export * from "./types";
export * from "./utils";
export const defaultChains = [Ethereum, Goerli, Polygon, Mumbai, Arbitrum, ArbitrumGoerli, Optimism, OptimismGoerli, Binance, BinanceTestnet, Fantom, FantomTestnet, Avalanche, AvalancheFuji, Localhost];
export const allChains = [${exportNames.join(", ")}];
`,
export function getChainByChainId(chainId: number): Chain {
const chain = allChains.find(chain => chain.chainId === chainId);
if (!chain) {
throw new Error(\`Chain with chainId "\${chainId}" not found\`);
}
return chain;
}
export function getChainBySlug(slug: string): Chain {
const chain = allChains.find(chain => chain.slug === slug);
if (!chain) {
throw new Error(\`Chain with slug "\${slug}" not found\`);
}
return chain;
}
export type ChainSlug = typeof allChains[number]["slug"];
export type ChainId = typeof allChains[number]["chainId"];`,
);
File diff suppressed because one or more lines are too long
+1
View File
@@ -33,6 +33,7 @@ export type Chain = {
testnet: boolean;
slug: string;
slip44?: number;
status?: string;
};
// MinimalChain is a subset of Chain with only the fields that are required / non-optional
+17
View File
@@ -11,6 +11,14 @@ const defaultOptions = {
mode: "http",
} as const;
/**
* Construct the list of RPC URLs given a specific chain config. Format any RPC URLs
* with necessary API keys.
*
* @param chain - The chain config to assemble RPC URLs from
* @param options - Options to configure the RPC URLs
* @returns The list of RPC URLs for the chain
*/
export function getChainRPCs(
chain: Pick<Chain, "rpc" | "chainId">,
options?: ChainRPCOptions,
@@ -75,6 +83,15 @@ export function getChainRPCs(
return orderedRPCs;
}
/**
* Get the highest priority RPC URL for a specific chain
*
* @param chain - The chain config to get the RPC URL for
* @param options - Options to configure the RPC URL
* @returns The RPC URL for the chain
*
* @internal
*/
export function getChainRPC(
chain: Pick<Chain, "rpc" | "chainId">,
options?: ChainRPCOptions,
@@ -0,0 +1,5 @@
import { getChainByChainId, Goerli } from "../src";
test("expect chainId 5 to be goerli", () => {
expect(getChainByChainId(5)).toBe(Goerli);
});
+50
View File
@@ -1,5 +1,55 @@
# thirdweb
## 0.10.2
### Patch Changes
- Updated dependencies [[`2682f582`](https://github.com/thirdweb-dev/js/commit/2682f5823e5c71947f5c6a71918a0285f253fd18), [`d5f18b40`](https://github.com/thirdweb-dev/js/commit/d5f18b403a6f3ced0e1929b5c032f63325708304), [`2efe5be3`](https://github.com/thirdweb-dev/js/commit/2efe5be3ad2df4e80c0048c8fd35018ecf2d8dd9), [`baeb7427`](https://github.com/thirdweb-dev/js/commit/baeb74274e878cfbc237ef2aa676faa257606300)]:
- @thirdweb-dev/sdk@3.10.2
## 0.10.1
### Patch Changes
- Updated dependencies [[`68d52f99`](https://github.com/thirdweb-dev/js/commit/68d52f99b36c6744e45872d0bdebafbbf7d09b59)]:
- @thirdweb-dev/sdk@3.10.1
## 0.10.0
### Minor Changes
- [#678](https://github.com/thirdweb-dev/js/pull/678) [`c9067681`](https://github.com/thirdweb-dev/js/commit/c9067681c21f7506d002182415d50918d31cba77) Thanks [@nkrishang](https://github.com/nkrishang)! - Add --dynamic option to deploy command
### Patch Changes
- [#665](https://github.com/thirdweb-dev/js/pull/665) [`6ef52dc9`](https://github.com/thirdweb-dev/js/commit/6ef52dc916251d72416ba5a8b63b428770f54e75) Thanks [@shift4id](https://github.com/shift4id)! - Fix spelling throughout all packages
- [#662](https://github.com/thirdweb-dev/js/pull/662) [`3740a0bf`](https://github.com/thirdweb-dev/js/commit/3740a0bf5db1301dbd93a97ab4c9343429a4e12d) Thanks [@furqanrydhan](https://github.com/furqanrydhan)! - Change URL for thirdweb app deploy redirect
- [#664](https://github.com/thirdweb-dev/js/pull/664) [`39855609`](https://github.com/thirdweb-dev/js/commit/398556094245a4a6865ed1cb93a4ee3b1f37fb49) Thanks [@jnsdls](https://github.com/jnsdls)! - Add `@thirdweb-dev/storage` to dependencies explicitly
- [#641](https://github.com/thirdweb-dev/js/pull/641) [`842ed519`](https://github.com/thirdweb-dev/js/commit/842ed519a3fd68dc456fcb3f50d6927a9e39d681) Thanks [@nkrishang](https://github.com/nkrishang)! - Add CLI command to create dynamic contract extensions.
- [#666](https://github.com/thirdweb-dev/js/pull/666) [`be04ff27`](https://github.com/thirdweb-dev/js/commit/be04ff27759d8f63409fc46def83fe838eefb285) Thanks [@shift4id](https://github.com/shift4id)! - various cli fixes
- Updated dependencies [[`a7e908b5`](https://github.com/thirdweb-dev/js/commit/a7e908b5fe60803e64b418cf42e081ca75123a45), [`61ef6964`](https://github.com/thirdweb-dev/js/commit/61ef69649fb605f6079dd9bbef12b739b02dda30), [`2f4cd928`](https://github.com/thirdweb-dev/js/commit/2f4cd92848a6c8cec4e86654f376a6d15bdd2b52), [`8a8a37f6`](https://github.com/thirdweb-dev/js/commit/8a8a37f6d3468b2a9c9736834bc39a3eee4754f4), [`63f552d7`](https://github.com/thirdweb-dev/js/commit/63f552d736a549532eb4d6a05cfe66a771b190b9), [`fb346ffd`](https://github.com/thirdweb-dev/js/commit/fb346ffd45edf9f50cc8c68a0c318eee39a6d9c6), [`e081075b`](https://github.com/thirdweb-dev/js/commit/e081075b2cebc7edad855481366bd9864ddba102), [`d8dec9fc`](https://github.com/thirdweb-dev/js/commit/d8dec9fc19079c79729857c36e45102c90fb7e0a), [`478780f6`](https://github.com/thirdweb-dev/js/commit/478780f6349595c17a7b3cd7de7668973c201d65), [`b83ea525`](https://github.com/thirdweb-dev/js/commit/b83ea5251bcd07feaab02a7ad1be202ccc6147fd), [`541dfeea`](https://github.com/thirdweb-dev/js/commit/541dfeeabaa744880cf78b310a9d61db4dfb32b3), [`6ef52dc9`](https://github.com/thirdweb-dev/js/commit/6ef52dc916251d72416ba5a8b63b428770f54e75), [`0c883044`](https://github.com/thirdweb-dev/js/commit/0c88304464ef4461a660a374198e893c578c8de0), [`0666f37c`](https://github.com/thirdweb-dev/js/commit/0666f37c13ed4b824e238325f9d13b9af785e0b0), [`85250cf7`](https://github.com/thirdweb-dev/js/commit/85250cf71190092b61023d56d1e786d395a008a6), [`b80024c6`](https://github.com/thirdweb-dev/js/commit/b80024c6cca17541c9b5ebb51c1476e9f210d3ab), [`8845bf96`](https://github.com/thirdweb-dev/js/commit/8845bf960e18c89d0e1f2fe1c370f4e2f4e855d0), [`2335f000`](https://github.com/thirdweb-dev/js/commit/2335f000c9023dd47b1a341a4dd40ed674e9bcdb), [`696c384a`](https://github.com/thirdweb-dev/js/commit/696c384a348890202e37cbd8488b1b1eceb4e8c2), [`3740a0bf`](https://github.com/thirdweb-dev/js/commit/3740a0bf5db1301dbd93a97ab4c9343429a4e12d), [`cc7ce8b1`](https://github.com/thirdweb-dev/js/commit/cc7ce8b1e8f73288b5c00a29e0000bea9867e8c1), [`91f5a2fd`](https://github.com/thirdweb-dev/js/commit/91f5a2fd5cb2f5aed6498defdb1feeabb283db6c), [`537785fe`](https://github.com/thirdweb-dev/js/commit/537785fed0021345b0d1cec37658e43c65931f9f), [`29c1cf7e`](https://github.com/thirdweb-dev/js/commit/29c1cf7eff60221d05e87060f3c96a83343218e6), [`b6b0855b`](https://github.com/thirdweb-dev/js/commit/b6b0855b81854ec3d5dd3c763a1ad2a235837cc9), [`2a8cc289`](https://github.com/thirdweb-dev/js/commit/2a8cc289ac42273800554a247cb9259a8f0329d7), [`1e1a3912`](https://github.com/thirdweb-dev/js/commit/1e1a39123bad2b96c332ebb58b25369b31dd9de7), [`dc08aa73`](https://github.com/thirdweb-dev/js/commit/dc08aa731f92ce3c2dd232378637a3075137367d), [`bd6be0ba`](https://github.com/thirdweb-dev/js/commit/bd6be0bae78511878c2344949bb212dab30ec30c)]:
- @thirdweb-dev/sdk@3.10.0
- @thirdweb-dev/storage@1.1.0
## 0.9.25
### Patch Changes
- Updated dependencies []:
- @thirdweb-dev/sdk@3.9.5
## 0.9.24
### Patch Changes
- Updated dependencies [[`5712650`](https://github.com/thirdweb-dev/js/commit/5712650074e2415bbea4173a0bb68d727ff2db90)]:
- @thirdweb-dev/sdk@3.9.4
## 0.9.23
### Patch Changes
+1
View File
@@ -6,6 +6,7 @@
<h1 align="center">thirdweb CLI</h1>
<p align="center">
<a href="https://www.npmjs.com/package/@thirdweb-dev/cli"><img src="https://img.shields.io/npm/v/@thirdweb-dev/cli?color=red&logo=npm" alt="npm version"/></a>
<a href="https://github.com/thirdweb-dev/js/actions/workflows/build-test-lint.yml"><img alt="Build Status" src="https://github.com/thirdweb-dev/js/actions/workflows/build-test-lint.yml/badge.svg"/></a>
<a href="https://discord.gg/thirdweb"><img alt="Join our Discord!" src="https://img.shields.io/discord/834227967404146718.svg?color=7289da&label=discord&logo=discord&style=flat"/></a>
</p>
+2 -1
View File
@@ -1,7 +1,7 @@
{
"name": "thirdweb",
"main": "dist/cli/index.js",
"version": "0.9.23",
"version": "0.10.2",
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/cli",
"author": "thirdweb eng <[email protected]>",
"license": "Apache-2.0",
@@ -30,6 +30,7 @@
},
"dependencies": {
"@thirdweb-dev/sdk": "*",
"@thirdweb-dev/storage": "*",
"async-retry": "^1.3.3",
"commander": "^9.1.0",
"detect-package-manager": "^2.0.1",
+15 -20
View File
@@ -54,10 +54,7 @@ const main = async () => {
if (lastCheckCache.isCached) {
const lastVersionCheck = new Date(lastCheckCache.value);
// Don't check for updates if already checked within past 24 hours
if (
new Date().getTime() - lastVersionCheck.getTime() <
1000 * 60 * 60 * 24
) {
if (Date.now() - lastVersionCheck.getTime() < 1000 * 60 * 60 * 24) {
shouldCheckVersion = false;
}
}
@@ -115,7 +112,7 @@ const main = async () => {
`Now using CLI version ${versionInfo.latest}. Continuing execution...`,
);
await new Promise((done, failed) => {
await new Promise((resolve, reject) => {
const shell = spawn(
`npx --yes thirdweb@latest ${process.argv
.slice(2)
@@ -125,9 +122,9 @@ const main = async () => {
);
shell.on("close", (code) => {
if (code === 0) {
done("");
resolve("");
} else {
failed();
reject();
}
});
});
@@ -160,14 +157,10 @@ const main = async () => {
process.exit(1);
}
await new Promise((done, failed) => {
await new Promise((resolve, reject) => {
exec(command, (err, stdout, stderr) => {
if (err) {
failed(err);
return;
}
done({ stdout, stderr });
if (err) {return reject(err);}
resolve({ stdout, stderr });
});
});
@@ -181,7 +174,7 @@ const main = async () => {
!installation.isGlobal || installation.packageManager === "npm"
? `npx thirdweb`
: `thirdweb`;
await new Promise((done, failed) => {
await new Promise((resolve, reject) => {
const shell = spawn(
`${executionCommand} ${process.argv.slice(2).join(" ")}`,
[],
@@ -189,9 +182,9 @@ const main = async () => {
);
shell.on("close", (code) => {
if (code === 0) {
done("");
resolve("");
} else {
failed();
reject();
}
});
});
@@ -214,6 +207,7 @@ const main = async () => {
.option("--js, --javascript", "Initialize as a JavaScript project.")
.option("--forge", "Initialize as a Forge project.")
.option("--hardhat", "Initialize as a Hardhat project.")
.option("--extension", "Create a smart contract extension.")
.option("--cra", "Initialize as a Create React App project.")
.option("--next", "Initialize as a Next.js project.")
.option("--vite", "Initialize as a Vite project.")
@@ -282,10 +276,11 @@ const main = async () => {
)
.option("--app", "Deploy a web app to decentralized storage")
.option("--contract", "Deploy a smart contract to blockchains")
.option("--dynamic", "Deploy a dynamic smart contract made up of extensions to blockchains")
.action(async (options) => {
const url = await deploy(options);
if (url) {
open(url);
await open(url);
}
});
@@ -314,7 +309,7 @@ const main = async () => {
url.toString(),
)}`,
);
open(url.toString());
await open(url.toString());
});
program
@@ -341,7 +336,7 @@ const main = async () => {
url.toString(),
)}`,
);
open(url.toString());
await open(url.toString());
});
program
+1 -1
View File
@@ -21,7 +21,7 @@ export function findFiles(
}
const stat = statSync(filename);
// brownie has a "depdendencies" directory *inside* the build directory, if we detect that we should skip it
// brownie has a "dependencies" directory *inside* the build directory, if we detect that we should skip it
if (stat.isDirectory() && basename(filename) === "dependencies") {
logger.debug('skipping "dependencies" directory');
continue;
+148 -14
View File
@@ -3,14 +3,19 @@ import build from "../core/builder/build";
import detect from "../core/detection/detect";
import { execute } from "../core/helpers/exec";
import { error, info, logger, spinner } from "../core/helpers/logger";
import { createContractsPrompt } from "../core/helpers/selector";
import { createContractsPrompt, createRouterPrompt } from "../core/helpers/selector";
import { ContractPayload } from "../core/interfaces/ContractPayload";
import { ThirdwebStorage } from "@thirdweb-dev/storage";
import { detectFeatures } from "@thirdweb-dev/sdk";
import chalk from "chalk";
import { readFileSync } from "fs";
import { readFileSync, writeFileSync } from "fs";
import { ethers } from "ethers";
import ora from "ora";
import path from "path";
import { Extension, ExtensionFunction, ExtensionMetadata, ExtensionDeployArgs } from "../core/interfaces/Extension";
import { EXTENSION_REGISTRY_ADDRESS, ROUTER_CONTRACTS, PreDeployedRouter, TWRouterParams, RouterParams } from "../constants/router-contracts";
export async function processProject(
options: any,
command: "deploy" | "publish",
@@ -94,6 +99,37 @@ export async function processProject(
process.exit(1);
}
let selectedRouter: PreDeployedRouter = { name: "", metadataUri: "", bytecodeUri: ""};
if(options.dynamic) {
const choices = Object.keys(ROUTER_CONTRACTS).map((key) => { return { title: key, value: key } });
let routerType: string = "";
const res = await createRouterPrompt(
choices,
"Choose a router to deploy",
);
if (typeof res.routerType === "string") {
routerType = res.routerType.trim();
}
selectedRouter = ROUTER_CONTRACTS[routerType];
}
if(options.dynamic && !selectedRouter) {
error(
`No router selected. Please select a router contract to deploy.`,
);
process.exit(1);
}
if (options.dynamic && !selectedRouter.name) {
error(
`No router selected. Please select a router contract to deploy.`,
);
process.exit(1);
}
let selectedContracts: ContractPayload[] = [];
if (compiledResult.contracts.length === 1) {
selectedContracts = [compiledResult.contracts[0]];
@@ -149,7 +185,7 @@ export async function processProject(
});
const prompt = createContractsPrompt(
choices,
`Choose which contract(s) to ${command}`,
options.dynamic ? "Choose which extensions to add to your contract" : `Choose which contract(s) to ${command}`,
);
const selection: Record<string, ContractPayload> = await prompt.run();
selectedContracts = Object.keys(selection).map((key) => selection[key]);
@@ -168,12 +204,31 @@ export async function processProject(
process.exit(0);
}
const loader = spinner("Uploading contract data...");
const soliditySDKPackage = "@thirdweb-dev/contracts";
let usesSoliditySDK = false;
if(selectedRouter.name === "thirdweb-router") {
const deployArgs: TWRouterParams = {
extensionRegistry: EXTENSION_REGISTRY_ADDRESS,
extensionNames: selectedContracts.map((c) => c.name),
}
const outputDeployArgs = JSON.stringify(deployArgs, undefined, 2);
writeFileSync("./deployArgs.json", outputDeployArgs, "utf-8");
info("Deployment parameters written to deployArgs.json in your project directory");
} else {
const deployArgs: RouterParams = await formatToExtensions(selectedContracts);
const outputDeployArgs = JSON.stringify(deployArgs, undefined, 2);
writeFileSync("./deployArgs.json", outputDeployArgs, "utf-8");
info("Deployment parameters written to deployArgs.json in your project directory");
}
const loader = spinner("Uploading contract data...");
try {
// Upload contract sources.
for (let i = 0; i < selectedContracts.length; i++) {
const contract = selectedContracts[i];
if (contract.sources) {
@@ -201,6 +256,7 @@ export async function processProject(
const metadataURIs = await Promise.all(
selectedContracts.map(async (c) => {
logger.debug(`Uploading ${c.name}...`);
return await storage.upload(JSON.parse(JSON.stringify(c.metadata)), {
uploadWithoutDirectory: true,
});
@@ -211,23 +267,47 @@ export async function processProject(
const bytecodes = selectedContracts.map((c) => c.bytecode);
const bytecodeURIs = await storage.uploadBatch(bytecodes);
const combinedContents = selectedContracts.map((c, i) => {
// attach analytics blob to metadata
let combinedContents = [];
if(options.dynamic) {
const analytics = {
command,
contract_name: c.name,
contract_name: selectedRouter.name,
cli_version: cliVersion,
project_type: projectType,
from_ci: options.ci || false,
uses_contract_extensions: usesSoliditySDK,
};
return {
name: c.name,
metadataUri: metadataURIs[i],
bytecodeUri: bytecodeURIs[i],
combinedContents.push({
name: selectedRouter.name,
metadataUri: selectedRouter.metadataUri,
bytecodeUri: selectedRouter.bytecodeUri,
analytics,
};
});
})
} else {
combinedContents = selectedContracts.map((c, i) => {
// attach analytics blob to metadata
const analytics = {
command,
contract_name: c.name,
cli_version: cliVersion,
project_type: projectType,
from_ci: options.ci || false,
uses_contract_extensions: usesSoliditySDK,
};
return {
name: c.name,
metadataUri: metadataURIs[i],
bytecodeUri: bytecodeURIs[i],
analytics,
};
});
}
let combinedURIs: string[] = [];
if (combinedContents.length === 1) {
// use upload single if only one contract to get a clean IPFS hash
@@ -265,3 +345,57 @@ export function getUrl(hashes: string[], command: string) {
}
return url;
}
async function formatToExtensions(contracts: ContractPayload[]): Promise<{extensions: Extension[], extensionDeployArgs: ExtensionDeployArgs[]}> {
const storage = new ThirdwebStorage();
const extensions: Extension[] = [];
const extensionDeployArgs: ExtensionDeployArgs[] = [];
for(const contract of contracts) {
// Prepare extension metadata.
let metadata: ExtensionMetadata = {
name: contract.name,
metadataURI: await getMetadataURIForExtension(contract, storage),
implementation: ethers.constants.AddressZero
}
// Get extension ABI.
const abi: Parameters<typeof detectFeatures>[0] = JSON.parse(
contract.metadata,
)["output"]["abi"];
// Format ABI as `ExtensionFunction[]`.
const extensionInterface = new ethers.utils.Interface(abi);
const functions: ExtensionFunction[] = [];
const fragments = extensionInterface.functions;
for (const fnSignature of Object.keys(fragments)) {
functions.push({
functionSelector: extensionInterface.getSighash(fragments[fnSignature]),
functionSignature: fnSignature
});
}
extensions.push({
metadata,
functions
});
extensionDeployArgs.push({
name: contract.name,
amount: 0,
salt: ethers.utils.keccak256(ethers.utils.toUtf8Bytes(contract.name)),
bytecode: contract.bytecode
})
}
return { extensions, extensionDeployArgs };
}
async function getMetadataURIForExtension(contract: ContractPayload, storage: ThirdwebStorage): Promise<string> {
return await storage.upload(JSON.parse(JSON.stringify(contract.metadata)), {
uploadWithoutDirectory: true,
});
}
@@ -0,0 +1,37 @@
import { Extension, ExtensionDeployArgs } from "../core/interfaces/Extension";
export interface PreDeployedRouter {
name: string;
metadataUri: string;
bytecodeUri: string;
}
export interface RouterParams {
extensions: Extension[];
extensionDeployArgs: ExtensionDeployArgs[];
}
export interface TWRouterParams {
extensionRegistry: string;
extensionNames: string[];
}
export const EXTENSION_REGISTRY_ADDRESS: string = "0x0000000000000000000000000000000000000000";
export const ROUTER_CONTRACTS: Record<string, PreDeployedRouter> = {
"upgradeable": {
name: "RouterUpgradeableFactory",
metadataUri: "ipfs://QmdqXhoJg9RfDDURHxtHKDprh3VvyWEwZWVtQvnvXMannF",
bytecodeUri: "ipfs://QmS63fhpjFFSzGXhM9deRSVaqWvEHEN9gcDkwNjiLr5oiV/1",
},
"non-upgradeable": {
name: "RouterImmutableFactory",
metadataUri: "ipfs://QmPMmcxK7RwQfcRwS8kmFU2hLWRLWpgcsESeXeFHM8W3Wp",
bytecodeUri: "ipfs://QmS63fhpjFFSzGXhM9deRSVaqWvEHEN9gcDkwNjiLr5oiV/0",
},
"thirdweb-router": {
name: "TWRouterFactory",
metadataUri: "ipfs://QmbrV9NUBZAXqoSHpdTzxsZjtubdqumgt6WTMLV8RW3tkV",
bytecodeUri: "ipfs://QmYjMfB1uhnnsdz6qmmc3bBAv8jmnniCkjXpDU6jGN8H5s/1",
}
}
+1 -2
View File
@@ -40,8 +40,7 @@ export class BrownieBuilder extends BaseBuilder {
const contractJsonFile = readFileSync(file, "utf-8");
const contractInfo = JSON.parse(contractJsonFile);
const abi = contractInfo.abi;
const bytecode = contractInfo.bytecode;
const { abi, bytecode } = contractInfo;
for (const input of abi) {
if (this.isThirdwebContract(input)) {
+1 -1
View File
@@ -150,7 +150,7 @@ export class FoundryBuilder extends BaseBuilder {
) {
// replace the abi with the actual abi
parsedMetadata.output.abi = abi;
// need to re-add libraries if not present since forge stripts it out
// need to re-add libraries if not present since forge strips it out
if (!parsedMetadata.settings.libraries) {
parsedMetadata.settings.libraries = {};
}
+1 -2
View File
@@ -97,8 +97,7 @@ export class HardhatBuilder extends BaseBuilder {
const bytecode = info.evm.bytecode.object;
const deployedBytecode = info.evm.deployedBytecode.object;
const metadata = info.metadata;
const abi = info.abi;
const { metadata, abi } = info;
const meta = JSON.parse(metadata);
const sources = Object.keys(meta.sources)
+1 -1
View File
@@ -70,7 +70,7 @@ export class SolcBuilder extends BaseBuilder {
}
// write them out to artifacts dir
// TODO technically we *could* just return them straight here, we have them in memory anywa?
// TODO technically we *could* just return them straight here, we have them in memory anyway?
Object.keys(output.contracts)
.filter((contractName) => contractName in sources)
.forEach((contractName) => {
+6 -11
View File
@@ -36,14 +36,12 @@ export class TruffleBuilder extends BaseBuilder {
logger.debug("Processing:", file.replace(buildPath, ""));
const contractJsonFile = readFileSync(file, "utf-8");
const contractInfo = JSON.parse(contractJsonFile);
const contractName = contractInfo.contractName;
const metadata = contractInfo.metadata;
const bytecode = contractInfo.bytecode;
const deployedBytecode = contractInfo.deployedBytecode;
const parsedMetadata = JSON.parse(metadata);
const abi = parsedMetadata.output.abi;
const { contractName, metadata, bytecode, deployedBytecode } =
contractInfo;
const meta = JSON.parse(metadata);
const abi = meta.output.abi;
const target = parsedMetadata.settings.compilationTarget;
const target = meta.settings.compilationTarget;
if (
Object.keys(target).length === 0 ||
Object.keys(target)[0].includes("@")
@@ -53,7 +51,6 @@ export class TruffleBuilder extends BaseBuilder {
continue;
}
const meta = JSON.parse(metadata);
const sources = Object.keys(meta.sources)
.map((path) => {
path = path.replace("project:/", "");
@@ -73,9 +70,7 @@ export class TruffleBuilder extends BaseBuilder {
})
.filter((path) => path !== undefined) as string[];
const fileNames = Object.keys(
parsedMetadata?.settings?.compilationTarget || {},
);
const fileNames = Object.keys(meta?.settings?.compilationTarget || {});
const fileName = fileNames.length > 0 ? fileNames[0] : "";
if (this.shouldProcessContract(abi, deployedBytecode, contractName)) {
+1 -1
View File
@@ -19,7 +19,7 @@ export default async function detect(
new HardhatDetector(),
new FoundryDetector(),
new TruffleDetector(),
// new BrownieDetector(), TODO brownie does not support outputing metadata yet
// new BrownieDetector(), TODO brownie does not support outputting metadata yet
];
const possibleProjectTypes = detectors
+3 -3
View File
@@ -5,14 +5,14 @@ export async function execute(
projectPath: string,
options = { log: false, cwd: projectPath },
): Promise<{ stdout: string; stderr: string }> {
return new Promise((done, failed) => {
return new Promise((resolve, reject) => {
exec(command, { ...options }, (err, stdout, stderr) => {
if (err) {
failed(err);
reject(err);
return;
}
done({ stdout, stderr });
resolve({ stdout, stderr });
});
});
}
+13
View File
@@ -1,5 +1,6 @@
import { ContractPayload } from "../interfaces/ContractPayload";
import chalk from "chalk";
import prompts from "prompts";
const { MultiSelect } = require("enquirer");
@@ -34,3 +35,15 @@ export function createContractsPrompt(
},
});
}
export async function createRouterPrompt(
choices: { title: string; value: string }[],
message: string,
) {
return await prompts({
type: "select",
name: "routerType",
message: message,
choices: choices,
});
}
@@ -0,0 +1,24 @@
import { BytesLike } from "ethers";
export interface ExtensionMetadata {
name: string;
metadataURI: string;
implementation: string;
}
export interface ExtensionFunction {
functionSelector: BytesLike;
functionSignature: string;
}
export interface Extension {
metadata: ExtensionMetadata;
functions: ExtensionFunction[];
}
export interface ExtensionDeployArgs {
name: string;
amount: number;
salt: string;
bytecode: string;
}
+28 -18
View File
@@ -19,6 +19,7 @@ let framework: string = "";
let language: string = "";
let baseContract: string = "";
let chain: string = "";
let createExtension: boolean = false;
/* let createType: string = "app"; */
export async function twCreate(
@@ -38,13 +39,14 @@ export async function twCreate(
projectType = "app";
} else if (pType === "contract" || options.contract) {
projectType = "contract";
} else if (pType === "extension" || options.extension) {
projectType = "extension";
}
if (projectType === "app") {
if (options.typescript) {
language = "typescript";
}
if (options.javascript) {
language = "javascript";
}
@@ -52,23 +54,18 @@ export async function twCreate(
if (options.next) {
framework = "next";
}
if (options.cra) {
framework = "cra";
}
if (options.vite) {
framework = "vite";
}
if (options.node) {
framework = "node";
}
if (options.express) {
framework = "express";
}
if (options.reactNative) {
framework = "react-native";
}
@@ -76,7 +73,6 @@ export async function twCreate(
if (options.solana) {
chain = "solana";
}
if (options.evm) {
chain = "evm";
}
@@ -86,7 +82,6 @@ export async function twCreate(
if (options.forge) {
framework = "forge";
}
if (options.hardhat) {
framework = "hardhat";
}
@@ -104,6 +99,7 @@ export async function twCreate(
choices: [
{ title: "App", value: "app" },
{ title: "Contract", value: "contract" },
{ title: "Dynamic Contract Extension", value: "extension" },
],
});
@@ -116,9 +112,20 @@ export async function twCreate(
projectType = "app";
}
if (projectType === "extension") {
createExtension = true;
if (options.forge) {
framework = "forge";
}
if (options.hardhat) {
framework = "hardhat";
}
}
// Whether to only create a new contract without the project
let onlyContract = false;
if (projectType === "contract") {
if (projectType === "contract" || projectType === "extension") {
const resolvedProjectPath = path.resolve(projectPath);
const contractProjectType = await detect(resolvedProjectPath, {});
@@ -154,7 +161,9 @@ export async function twCreate(
if (!onlyContract) {
if (!projectPath) {
const defaultName =
projectType === "contract" ? "thirdweb-contracts" : "thirdweb-app";
projectType === "contract" || projectType === "extension"
? "thirdweb-contracts"
: "thirdweb-app";
const res = await prompts({
type: "text",
name: "path",
@@ -165,10 +174,10 @@ export async function twCreate(
const validation = validateNpmName(
path.basename(path.resolve(name.toLowerCase())),
);
if (validation.valid) {
return true;
}
return "Invalid project name: " + validation.problems?.[0];
return (
validation.valid ||
"Invalid project name: " + validation.problems?.[0]
);
},
});
@@ -258,7 +267,7 @@ export async function twCreate(
}
if (
projectType === "contract" &&
(projectType === "contract" || projectType === "extension") &&
framework !== "forge" &&
framework !== "hardhat"
) {
@@ -289,7 +298,7 @@ export async function twCreate(
}
}
if (projectType === "contract") {
if (projectType === "contract" || projectType === "extension") {
// Select contract name
if (!contractName) {
const defaultName = "MyContract";
@@ -329,7 +338,7 @@ export async function twCreate(
}
// Select base contract
if (projectType === "contract" && !baseContract) {
if (projectType === "contract" && !baseContract && !createExtension) {
let standard = "none";
const standardPrompt = await prompts({
type: "select",
@@ -424,7 +433,7 @@ export async function twCreate(
: getPkgManager();
const template =
typeof options.template === "string" && options.template.trim();
typeof options.template === "string" ? options.template.trim() : undefined;
try {
if (projectType === "app") {
await createApp({
@@ -443,6 +452,7 @@ export async function twCreate(
contractName,
baseContract,
onlyContract,
createExtension,
});
}
} catch (reason) {
@@ -1,5 +1,6 @@
import { hasBaseContract, readBaseContract } from "./base-contracts";
import { DownloadError } from "./create-app";
import { readExtensionBoilerPlate } from "./extension-contract-boilerplate";
import { PackageManager } from "./get-pkg-manager";
import { tryGitInit } from "./git";
import { hasForge } from "./has-forge";
@@ -23,6 +24,15 @@ interface ICreateContractProject {
framework?: string;
baseContract?: string;
onlyContract: boolean;
createExtension: boolean;
}
function isErrorLike(err: unknown): err is { message: string } {
return (
typeof err === "object" &&
err !== null &&
typeof (err as { message?: unknown }).message === "string"
);
}
export async function createContractProject({
@@ -32,6 +42,7 @@ export async function createContractProject({
contractName,
baseContract,
onlyContract,
createExtension,
}: ICreateContractProject) {
// Check that the selected base contract is valid
if (baseContract) {
@@ -70,7 +81,8 @@ export async function createContractProject({
}
// Clean the contract name
contractName = contractName.replace(/\.sol$/, "") + ".sol";
const contractObjectName = contractName.replace(/\.sol$/, "");
contractName = contractObjectName + ".sol";
const useYarn = packageManager === "yarn";
@@ -99,6 +111,23 @@ export async function createContractProject({
`${chalk.green("Success!")} Created ${contractName} at ${contractPath}`,
);
}
if (!baseContract && createExtension) {
const extensionBoilerplate = readExtensionBoilerPlate(contractObjectName);
// Set the contents of the Contract.sol file to the extension contract storage library boilerplate
let contractFile = "";
contractFile = path.join(root, contractName);
// Write the extension storage library to the MyContract.sol file
await writeFile(contractFile, extensionBoilerplate);
console.log(
`${chalk.green(
"Success!",
)} Created your ${contractName} extension at ${contractPath}`,
);
}
} else {
// Otherwise, create a new contracts project
const projectName = path.basename(root);
@@ -118,14 +147,6 @@ export async function createContractProject({
process.chdir(root);
function isErrorLike(err: unknown): err is { message: string } {
return (
typeof err === "object" &&
err !== null &&
typeof (err as { message?: unknown }).message === "string"
);
}
try {
console.log(`Downloading files. This might take a moment.`);
@@ -164,6 +185,26 @@ export async function createContractProject({
// Write the base contract to the new file
await writeFile(contractFile, baseContractText);
}
if (!baseContract && createExtension) {
const extensionBoilerplate =
readExtensionBoilerPlate(contractObjectName);
// Set the contents of the Contract.sol file to the extension contract storage library boilerplate
let contractFile = "";
contractFile = path.join(root, contractName);
if (framework === "hardhat") {
fs.unlinkSync(path.join(root, "contracts", "Contract.sol"));
contractFile = path.join(root, "contracts", contractName);
}
if (framework === "forge") {
fs.unlinkSync(path.join(root, "src", "Contract.sol"));
contractFile = path.join(root, "src", contractName);
}
// Write the extension storage library to the MyContract.sol file
await writeFile(contractFile, extensionBoilerplate);
}
} catch (reason) {
throw new DownloadError(
isErrorLike(reason) ? reason.message : String(reason),
@@ -0,0 +1,58 @@
// Import the extension-contract storage boilerplate
export function readExtensionBoilerPlate(name: string): string {
const snakeCaseName = camelToSnakeCase(name).toUpperCase();
const dotCaseName = camelToDotCase(name);
const boilerplate = `// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;
library ${name}Storage {
bytes32 public constant ${snakeCaseName}_STORAGE_POSITION = keccak256("${dotCaseName}.storage");
// Define your contract's state inside the Data struct.
struct Data {
// Example: a uint called "number"
uint256 number;
}
/**
* Access your state variables using the following pattern (example):
* ${name}Storage.Data storage data = ${name}Storage.getStorage();
**/
function getStorage() internal pure returns (Data storage data) {
bytes32 position = ${snakeCaseName}_STORAGE_POSITION;
assembly {
data.slot := position
}
}
}
contract ${name} {
function readContractState() external view returns (uint256) {
${name}Storage.Data storage data = ${name}Storage.getStorage();
return data.number;
}
function writeContractState(uint256 x) external {
${name}Storage.Data storage data = ${name}Storage.getStorage();
data.number = x;
}
}`;
return boilerplate;
}
function camelToSymbolCase(text: string, symbol: string): string {
return text
.replace(/(.)([A-Z][a-z]+)/, `$1${symbol}$2`)
.replace(/([a-z0-9])([A-Z])/, `$1${symbol}$2`)
.toLowerCase();
}
function camelToSnakeCase(text: string): string {
return camelToSymbolCase(text, "_");
}
function camelToDotCase(text: string): string {
return camelToSymbolCase(text, ".");
}
+3 -8
View File
@@ -1,14 +1,9 @@
import { exec } from "child_process";
export async function hasForge() {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
return await new Promise((resolve, reject) => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
exec("forge --version", (error, stdout, stderr) => {
if (error) {
resolve(false);
}
resolve(true);
return await new Promise((resolve) => {
exec("forge --version", (error) => {
resolve(!error);
});
});
}
+2 -4
View File
@@ -3,7 +3,6 @@ import ViteDetector from "../core/detection/vite";
import YarnDetector from "../core/detection/yarn";
import { runCommand } from "../create/helpers/run-command";
import { upload } from "../storage/command";
import { DEFAULT_IPFS_GATEWAY } from "@thirdweb-dev/sdk";
import { ThirdwebStorage } from "@thirdweb-dev/storage";
export async function deployApp(distPath = "dist", projectPath = ".") {
@@ -33,9 +32,8 @@ export async function deployApp(distPath = "dist", projectPath = ".") {
}
try {
let url = await upload(storage, distPath);
url = url.replace("ipfs://", DEFAULT_IPFS_GATEWAY);
return `${url}/index.html`;
const uri = await upload(storage, distPath);
return `https://thirdweb.com/app/deploy/${uri.replace("ipfs://", "")}`;
} catch (err) {
console.error("Can't upload project");
return Promise.reject("Can't upload project");

Some files were not shown because too many files have changed in this diff Show More