Compare commits

...
Author SHA1 Message Date
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
e4d41856f2 Version Packages (#699)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-03-09 12:07:00 -08:00
Joaquim VergesandGitHub 713d3187be [SDK] Allow null values for NFT schema (#698) 2023-03-09 19:38:54 +00:00
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
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
7c3f050883 Version Packages (#609)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-02-22 13:59:28 -08:00
8b68f20678 refactor: Release to Publish (#567)
Co-authored-by: Jonas Daniels <[email protected]>
2023-02-22 21:36:03 +00:00
Jonas DanielsandGitHub 3d644fb8cb [react] - add mediarenderer prop (#608) 2023-02-21 10:30:21 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
690ff925c3 Version Packages (#603)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-02-20 20:13:14 -08:00
Jonas DanielsandGitHub 4fe6797427 clean up remaining workflows (#605) 2023-02-19 02:12:39 +00:00
Jonas DanielsandGitHub f3408d05d8 [sdk] - fix possible crash in StaticJsonRpcBatchProvider (#604) 2023-02-19 01:47:29 +00:00
Jonas Daniels 845e818c66 CI all in one? 2023-02-18 14:55:51 -08:00
Jonas Daniels 5178256e84 try out new ci action 2023-02-18 14:40:23 -08:00
Jonas DanielsandGitHub 66cf1fb5c2 [various] - upgrade dependencies (#601) 2023-02-18 22:10:45 +00:00
Jonas Daniels df792f0b81 make merge queue work 2023-02-18 14:10:16 -08:00
Jonas Daniels ae0f967356 make platform own everything by default 2023-02-18 13:55:33 -08:00
Jonas Daniels 076718112f devrel should not own changeset markdown files 2023-02-18 13:54:00 -08:00
Jonas Daniels 7c9f86cc44 improve codeowners 2023-02-18 13:51:56 -08:00
Jonas DanielsandGitHub 9c90371426 Jd/add codeowners (#602) 2023-02-18 13:49:09 -08:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
4516487a9a Version Packages (#600)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-02-17 17:38:12 -08:00
Adam MajmudarandGitHub 300fe4a933 [Storage] Pass through pinata metadata (#597) 2023-02-18 01:32:09 +00:00
Joaquim VergesandGitHub f580b8ac06 [React] fix react provider readonly chain mismatch (#599) 2023-02-18 01:24:16 +00:00
Adam MajmudarandGitHub f0de81d4b1 [Auth] Expose verifyLogin function (#588) 2023-02-17 17:15:08 -08:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
f3a863a3b1 Bump undici from 5.14.0 to 5.19.1 (#594)
Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-02-16 18:11:22 -08:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
128bca9e07 Version Packages (#595)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-02-16 17:37:38 -08:00
iketwGitHubiketwciaranightingaleJonas Danielsgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>github-actions[bot] <github-actions[bot]@users.noreply.github.com>Nacho Iacovino
18ba6b381e [React Native SDK] init package (#522)
Co-authored-by: iketw <[email protected]>
Co-authored-by: ciaranightingale <[email protected]>
Co-authored-by: Jonas Daniels <[email protected]>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Nacho Iacovino <[email protected]>
2023-02-16 20:04:07 -05:00
Jonas Daniels 18c16101dd release-pr may use cache 2023-02-16 08:49:50 -08:00
Jonas DanielsandGitHub b6b94ca348 smaller workers (#593) 2023-02-16 08:45:38 -08:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
81d2d2185d Version Packages (#560)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-02-15 21:45:09 -08:00
Joaquim VergesandGitHub 37f58b4e68 [React] fix alignment on web3button (#592) 2023-02-15 21:41:02 -08:00
61d41db769 [React] Fix passing activeChainId prop down (#591)
Co-authored-by: Jonas Daniels <[email protected]>
2023-02-15 21:26:49 -08:00
Jonas DanielsandGitHub 44cce2f2b1 [SDK] - allow passing Chain object to initialize SDK (#590) 2023-02-16 05:16:14 +00:00
Jonas DanielsandGitHub 017b0d56b6 [chains] - update chains & add utils (#589) 2023-02-16 01:06:34 +00:00
Adam MajmudarandGitHub 4d77c185d9 [SDK] Update tiered drop with total price (#585) 2023-02-15 17:26:00 +00:00
44d56e4a91 [SDK] Check how many NFTs a specific wallet has claimed (#577)
Co-authored-by: Adam Majmudar <[email protected]>
Co-authored-by: Jonas Daniels <[email protected]>
2023-02-15 01:41:25 +00:00
Nacho IacovinoandGitHub 03e755f1df [React] Don't have min-width requirement for html types (#583) 2023-02-15 01:10:52 +00:00
Adam MajmudarandGitHub 8694d5a3a1 Add changeset for react (#582) 2023-02-14 20:06:02 +00:00
Adam MajmudarandGitHub 4d9e5c6193 Update next-auth wallet config (#581) 2023-02-14 19:39:46 +00:00
Jonas DanielsandGitHub 27d8db200e [SDK] - mark fromPrivateKey as public (#579) 2023-02-14 08:11:52 +00:00
Adam MajmudarandGitHub 813c4a4a09 [Unity Bridge] Add support for Auth to unity-js-bridge (#575) 2023-02-14 07:16:10 +00:00
Adam MajmudarandGitHub f6ea971854 [Auth] Add support for next-auth (#576) 2023-02-14 01:04:08 -05:00
Jonas DanielsandGitHub f3b96e7120 [react, react-core] - allow number and string types for activeChain prop (#578) 2023-02-14 03:09:32 +00:00
iketwandGitHub cfd2a7c9ec [ReactSDK] remove duplicate and set Dapp url as mandatory (#571) 2023-02-13 21:50:34 +00:00
FirekeeperandGitHub 9670c7aee5 Firekeeper/unity js listeners dyncall (#573) 2023-02-13 13:38:20 -08:00
Joaquim VergesandGitHub 94b120ffd1 [Wallets] Device Wallet (#548) 2023-02-12 21:32:14 -08:00
Jonas DanielsandGitHub d0bcd2c587 [chains] - fix localhost (#570) 2023-02-12 05:04:47 +00:00
Jonas DanielsandGitHub 818048d52f [react, react-core] chain integration (#569) 2023-02-11 16:48:44 -08:00
Jonas DanielsandGitHub 500a0e671b [chains, react] - upgraded rpcs, etc (#568) 2023-02-11 15:05:12 -08:00
Jonas DanielsandGitHub 6a50719486 [chains] - add getChainRPCs (#565) 2023-02-10 05:48:14 +00:00
Joaquim VergesandGitHub 1f89410867 Update README.md 2023-02-09 21:36:42 -08:00
Joaquim VergesandGitHub 363c6799a6 Update README.md 2023-02-09 21:35:50 -08:00
Joaquim VergesandGitHub bddabe0b42 [Wallet] Email wallet integration (#559) 2023-02-09 21:35:07 -08:00
Joaquim VergesandGitHub 2b3e94f90a [React] Fix creating SDKs with signer only (#564) 2023-02-09 17:08:25 -08:00
5d25ee1ab7 [SDK] fix getMultiChainContractList (#562)
Co-authored-by: Joaquim Verges <[email protected]>
2023-02-09 23:20:23 +00:00
Joaquim VergesandGitHub d6abe00c4e Fix marketplace v3 tests (#563) 2023-02-09 13:58:10 -08:00
af8cf40e4e [SDK, react-core, react] Support any EVM chain (#486)
Co-authored-by: Jonas Daniels <[email protected]>
Co-authored-by: iketw <[email protected]>
Co-authored-by: Jarrod Watts <[email protected]>
2023-02-09 01:08:20 +00:00
iketwandGitHub e85ec3e8f0 [ReactSDK] fix comment (#558) 2023-02-08 23:31:48 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
9919026f38 Version Packages (#554)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-02-08 13:04:43 -08:00
YashandGitHub c349f44d58 [SDK] Fix tests marketplace-v3 (#557) 2023-02-08 11:21:56 -08:00
Joaquim VergesandGitHub fc7c6b6211 [SDK] Extract util test functions (#556) 2023-02-08 10:13:10 -08:00
Joaquim VergesandGitHub 55b00eff26 [SDK] Add gas estimators to marketplace plugins (#555) 2023-02-07 16:22:55 -08:00
Jonas DanielsandGitHub 76d219e6be [contracts-js, storage] - force release (#553) 2023-02-07 20:00:00 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
f13408a33d Version Packages (#552)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-02-07 11:30:03 -08:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
74b19012c2 Version Packages (#543)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-02-06 21:02:00 -08:00
Joaquim VergesandGitHub 8f85868324 Fix contracts-js turbo caching issue (#551) 2023-02-07 01:14:11 +00:00
Adam MajmudarandGitHub 448b357ed4 [SDK] Add solidity stack traces to error messages (#550) 2023-02-06 19:21:17 -05:00
YashandGitHub 912738bd0a [CLI] Add staking bases (#549) 2023-02-06 12:01:22 -08:00
f1aecc3049 [SDK] Contracts version update - Marketplace V3 (#544)
Co-authored-by: Joaquim Verges <[email protected]>
2023-02-06 05:40:23 +00:00
Adam MajmudarandGitHub 0b38dac852 [SDK] Add proper error catching for when user has no funds (#547) 2023-02-05 21:28:44 -08:00
Nacho IacovinoandGitHub 440a4ade95 [React] Add more marketplace v3 hooks (#546) 2023-02-04 04:01:35 +00:00
Adam MajmudarandGitHub 29d0c62610 [SDK] Add error info fields to TransactionError (#545) 2023-02-04 03:09:34 +00:00
Adam MajmudarandGitHub f295ec67b4 [SDK] Upgraded error messages on failed transactions (#539) 2023-02-04 00:35:10 +00:00
1686fb4b2c [SDK] marketplace v3 integration (#474)
Co-authored-by: Joaquim Verges <[email protected]>
Co-authored-by: Nacho Iacovino <[email protected]>
Co-authored-by: Nacho Iacovino <[email protected]>
Co-authored-by: Jonas Daniels <[email protected]>
2023-02-03 13:19:09 -08:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
85dd18e8f0 Version Packages (#541)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-02-03 10:53:16 -08:00
Joaquim VergesandGitHub ec1f2324c7 [SDK] Solana - Expose getTransaction pagination options + transactions for given wallet (#542) 2023-02-03 10:39:40 -08:00
b59a31c365 Add support for rendering 3D NFTs (#470)
Co-authored-by: Jonas Daniels <[email protected]>
Co-authored-by: Jarrod Watts <[email protected]>
Co-authored-by: Nacho Iacovino <[email protected]>
Co-authored-by: Nacho Iacovino <[email protected]>
2023-02-03 16:38:59 +01:00
Joaquim VergesandGitHub d29f7e78f0 [SDK] expose getMintTransaction() for fine grain control on mint calls (#540) 2023-02-02 19:32:29 -08:00
github-actions[bot]andGitHub 3e2b392b6b Version Packages (#538) 2023-02-02 09:21:36 -08:00
Adam MajmudarandGitHub cf96333fa2 Fix cache error on mkdir (#537) 2023-02-02 17:12:57 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
4213cfee77 Bump http-cache-semantics from 4.1.0 to 4.1.1 (#536)
Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-02-02 00:26:26 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
25ef4be50f Version Packages (#534)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-02-01 16:16:07 -08:00
ab1f8bb6f6 [CLI] Modify auto-update process with flag and caching (#528)
Co-authored-by: Jonas Daniels <[email protected]>
2023-02-02 00:04:50 +00:00
Jonas DanielsandGitHub 5f8ec45af7 [SDK] - add burnBatch and getTransactions in solana (#535) 2023-02-01 15:35:22 -08:00
Adam MajmudarandGitHub b45d761f8f [SDK] add creator and royalty settings update for drop (#410) 2023-02-01 15:47:49 -05:00
Adam MajmudarandGitHub 04de5b2783 [SDK] expose getSnapshotEntryForAddress (#471) 2023-02-01 17:34:20 +00:00
Adam MajmudarandGitHub dee4596549 [Auth] Update peerDependencies (#533) 2023-02-01 12:21:16 -05:00
Nacho IacovinoandGitHub 3547901ddd Add all available hooks to React readme (#530) 2023-02-01 02:21:47 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
fe7ab1c5d3 Version Packages (#526)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-01-31 15:06:05 -08:00
Jonas DanielsandGitHub bdd9ed2298 [react] - fix zag-js/react issues (#527) 2023-01-31 14:57:55 -08:00
ciaranightingaleandGitHub 0977454d45 update readme (#529) 2023-01-31 14:49:24 -08:00
Joaquim VergesandGitHub 19b8e18b6b [SDK] Fix getClaimTransaction().estimateGasCostInEther() for claims costing native currency (#525) 2023-01-31 09:21:00 -08:00
Adam MajmudarandGitHub 7c0060b7fd Fix useMagic and useGnosis documentation (#523) 2023-01-30 22:34:25 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
0a07d7a248 Version Packages (#521)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-01-28 21:52:12 -08:00
Adam MajmudarandGitHub 8c81ca5c30 Update react-core dependencies (#520) 2023-01-29 05:25:55 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
c911d183e6 Version Packages (#513)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-01-27 14:34:52 -08:00
f15733f34c Update changesets (#519)
Co-authored-by: Joaquim Verges <[email protected]>
2023-01-27 14:30:03 -08:00
Adam MajmudarandGitHub a6c074c3f3 [Auth] complete auth update & restructure (#460) 2023-01-27 17:06:58 -05:00
Jonas DanielsandGitHub fdb9baedee check for exitcode in detect e2e test (#518) 2023-01-27 12:18:47 -08:00
Avneesh AgarwalandGitHub 9e591b32b7 feat: add express, node.js, and react native templates (#517) 2023-01-27 10:23:06 -08:00
Jonas DanielsandGitHub 12ec3be4a3 update changeset file (#516) 2023-01-26 14:50:57 -08:00
Jonas DanielsandGitHub 48893c730e [react, react-core] - rely on react-core in react (#514) 2023-01-26 12:59:58 -08:00
f37e86b7d2 [React] Move Solana to peer dependencies (#493)
Co-authored-by: iketw <[email protected]>
Co-authored-by: Jonas Daniels <[email protected]>
2023-01-26 09:52:21 -08:00
62b7388bb2 [react-core] init (#511)
Co-authored-by: Jonas Daniels <[email protected]>
2023-01-26 06:10:48 +00:00
iketwandGitHub 065c4db41b [ReactSDK] Changes useClaimedNFTs to only fetch claimed NFTs (#512) 2023-01-25 22:02:50 -08:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
431ab23ee2 Bump cookiejar from 2.1.3 to 2.1.4 (#508)
Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-23 14:30:14 -08:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
836484ba98 Version Packages (#504)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-01-23 13:59:28 -08:00
Nacho IacovinoandGitHub 5047686f2a Fix ConnectWallet network selector (#507) 2023-01-23 20:53:44 +00:00
7cab8d1679 [SDK] Plugin pattern: get composite ABI (#475)
Co-authored-by: Joaquim Verges <[email protected]>
2023-01-20 17:52:30 -08:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
0f0125acf2 Version Packages (#477)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-01-18 21:03:46 -08:00
Joaquim VergesandGitHub 894cbefc63 [SDK] Add intermediate event for contract deploy transactions before confirmation (#502) 2023-01-18 20:54:21 -08:00
retocroomanandGitHub 73dc026ff9 [SDK] Fix getting domain separator error (#500) 2023-01-18 15:18:42 -08:00
Joaquim VergesandGitHub af32007b9f [SDK] remove debug logs (#501) 2023-01-18 22:57:07 +00:00
Joaquim VergesandGitHub 5fba324ac1 [SDK] Fix claim conditions detection on legacy contracts (#498) 2023-01-15 20:34:39 -08:00
Joaquim VergesandGitHub bff433e121 [SDK] Fix deploy transaction listener for all deploy types sdk.deployer.addDeployListener() (#494) 2023-01-13 19:32:50 -08:00
Joaquim VergesandGitHub 68c8e3c4d7 [SDK] resolve contracts via multichain registry (#491) 2023-01-11 17:41:08 -08:00
Jonas DanielsandGitHub 4e8ff58208 [CLI] attempt to fix usage of rm on windows (#483) 2023-01-10 15:57:33 +01:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
d0d5a3c23d Bump json5 from 1.0.1 to 1.0.2 (#476)
Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-09 12:56:52 +01:00
9eaa21d09a [SDK] Multichain registry (#311)
Co-authored-by: Yash <[email protected]>
2023-01-05 19:43:28 -08:00
557429b5cf [SDK] Support for PackVRF (#463)
Co-authored-by: Jonas Daniels <[email protected]>
2023-01-05 15:38:59 -08:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
96d2dfd25d Version Packages (#467)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-01-03 14:54:29 +13:00
YashandGitHub 5862c558fb [SDK] Update forwarder address (#469) 2022-12-20 12:42:02 -08:00
e913e0daa9 [SDK] Add SDK options to factory (#465)
Co-authored-by: Joaquim Verges <[email protected]>
2022-12-17 13:05:52 +13:00
Joaquim VergesandGitHub f7a74a3b7c [SDK] Expose sdk.wallet.signTypedData() (#468) 2022-12-16 23:50:36 +00:00
Joaquim VergesandGitHub 73883f56d0 [SDK] workaround for signing typed data with magic.link signers (#466) 2022-12-17 10:44:03 +13:00
Jonas DanielsandGitHub e47085af92 [config] add timeouts for all relevant github actions (#464) 2022-12-16 10:06:58 +01:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
f525e2cc23 Version Packages (#455)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-12-16 15:28:02 +13:00
Nacho IacovinoandGitHub af85389dc0 [CLI] Fix deprecated links (#461) 2022-12-13 16:20:34 -08:00
ccb4ce8d00 [Wallets] - magic wallet connector (#457)
Co-authored-by: Joaquim Verges <[email protected]>
2022-12-13 13:58:49 +13:00
Joaquim VergesandGitHub 4cdd0bd634 [SDK] Fixes for latest wallet package integration (#458) 2022-12-08 22:13:16 +00:00
ea95c5f609 [SDK] add two new utilities toEther and toWei (#421)
Co-authored-by: Nacho Iacovino <[email protected]>
Co-authored-by: Jonas Daniels <[email protected]>
2022-12-08 12:46:41 -08:00
Joaquim VergesandGitHub 699a2b16fb [SOL] Fix claiming drops with custom currencies (#456) 2022-12-08 09:32:47 +00:00
Joaquim VergesandGitHub a8267f912d [SOL] Drop fixes for batch upload (#453) 2022-12-08 21:59:47 +13:00
Jonas DanielsandGitHub c673e39f23 upgrade dependencies across the codebase (#454) 2022-12-08 08:19:16 +00:00
08d04fe4dc [React] add props for button title to change the text (#422)
Co-authored-by: Jonas Daniels <[email protected]>
2022-12-08 08:09:23 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
cbf5508bd5 Version Packages (#449)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-12-07 14:21:51 +13:00
Joaquim VergesandGitHub 3731459d33 [SDK] Less strict prebuilt checks to support OSRF variants (#451) 2022-12-07 13:08:12 +13:00
Adam MajmudarandGitHub 64f24f1bb1 CLI auto-updates on every run (#441) 2022-12-06 02:40:31 +00:00
Joaquim VergesandGitHub cac6c30bca [SDK] Fix setting allowance or approvals gaslessly (#450) 2022-12-06 11:49:04 +13:00
Adam MajmudarandGitHub e7740a59db Detect if forge isn't installed and display error (#447) 2022-12-05 16:54:13 -05:00
Jonas DanielsandGitHub 7a37e564fd [SDK, React] - useContract fail fast (#448) 2022-12-05 21:41:58 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
e173636f4b Version Packages (#446)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-12-04 11:34:00 +13:00
Joaquim VergesandGitHub 8c6cdaa288 [SDK] Fix creating listings with a magic.link wallet (#443) 2022-12-03 21:58:44 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
ad9b3febff Version Packages (#445)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-12-04 07:49:38 +13:00
Adam MajmudarandGitHub 94f49b1294 Move framework check back to template (#444) 2022-12-03 18:40:46 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
517e2a75e3 Version Packages (#442)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-12-02 16:26:33 -08:00
Jonas DanielsandGitHub 72692689e9 initialize pay package (#433) 2022-12-02 22:52:04 +00:00
Jonas DanielsandGitHub efc56fa580 [SDK] - improved batch provider (#440) 2022-12-02 22:39:11 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
564b17e760 Version Packages (#419)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-12-03 11:25:35 +13:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
b4507db963 Bump decode-uri-component from 0.2.0 to 0.2.2 (#439)
Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-02 14:10:31 -08:00
Joaquim VergesandGitHub f451da6395 [SDK] Fix SigMint detection for OSRF NFT Collection contracts (#438) 2022-12-03 11:00:21 +13:00
Jonas DanielsandGitHub ee47840767 fix #429 (#436) 2022-12-02 10:47:46 -08:00
Adam MajmudarandGitHub bef97f72f4 [CLI] Make solc default backup compilation (#435) 2022-12-02 17:11:20 +00:00
Adam MajmudarandGitHub 3e87dd3ccb [CLI] display file names when there are duplicate contract names (#432) 2022-12-02 03:21:40 +00:00
Joaquim VergesandGitHub def42511ff [SOL] Remove workaround for getLargestAccount (#434) 2022-12-02 02:42:26 +00:00
Adam MajmudarandGitHub c42545a647 [CLI] fix CLI on paths with spaces for windows (#431) 2022-12-01 19:03:54 -05:00
Adam MajmudarandGitHub 6e20d1f21a [CLI] allow adding contracts to existing projects (#428) 2022-12-01 20:31:06 +00:00
Joaquim VergesandGitHub e684d7e1ca [CLI] Fix metadata upload with special characters (#430) 2022-12-01 20:14:27 +00:00
Adam MajmudarandGitHub f545a67e9f [Auth] include credentials when requesting user (#425) 2022-12-01 18:17:31 +00:00
Jake LooandGitHub 034a257442 [SDK] Support more types of Minimal Proxy (#429) 2022-12-01 20:30:09 +13:00
1bfb91dbf3 [SDK] Improve error parsing for other wallets (#424)
Co-authored-by: Jonas Daniels <[email protected]>
2022-11-30 18:02:21 -08:00
Jonas DanielsandGitHub 5d95cbcdb2 fix turbo (#427) 2022-12-01 00:52:06 +00:00
Jonas DanielsandGitHub 639e535ed5 init unity-js-bridge package (#420) 2022-11-30 22:36:16 +00:00
af3acc6b10 [SDK] Add support for AWS KMS (#416)
Co-authored-by: Jonas Daniels <[email protected]>
2022-11-28 20:34:24 -08:00
Joaquim VergesandGitHub eca47763cd [SDK] increase gas limit for opening packs (#418) 2022-11-29 03:30:15 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
37b5bec897 Version Packages (#417)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-28 18:23:23 -08:00
Nacho IacovinoandGitHub 48d91e4431 [CLI] Fix mappings for prebuilts (#415) 2022-11-28 18:13:00 -08:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
a20be881e3 Version Packages (#406)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-29 12:09:38 +13:00
Joaquim VergesandGitHub 47f8945325 [SDK] improve error parsing (#414) 2022-11-29 11:45:33 +13:00
Furqan RydhanandGitHub 1b0bf99da7 Improvements to the App Deploy Flow (#413) 2022-11-28 14:23:44 -08:00
f03be398e0 [SDK] Update signTypedData domain to match contract (#412)
Co-authored-by: Joaquim Verges <[email protected]>
2022-11-28 03:00:50 +00:00
27996cb4bc [CLI] - feat: add solana support to cli (#403)
Co-authored-by: Jarrod Watts <[email protected]>
Co-authored-by: Jonas Daniels <[email protected]>
2022-11-24 01:01:00 +00:00
2eaa67acbe [CLI+SDK] app-uri (#283)
Co-authored-by: Furqan Rydhan <[email protected]>
Co-authored-by: Jonas Daniels <[email protected]>
2022-11-23 09:17:29 +00:00
Jonas Daniels aafd7968df bring the registry-url back apparently it was important 2022-11-23 01:05:43 -08:00
Jonas DanielsandGitHub 48797c7cf0 [SDK] - add gasless feature detection (#408) 2022-11-23 00:53:59 -08:00
Jonas DanielsandGitHub 4edcb37100 update prettier & format (#407) 2022-11-23 06:41:39 +00:00
83dcaf7058 Expose sdk.fromWallet and wallet classes (#402)
Co-authored-by: Jonas Daniels <[email protected]>
2022-11-22 18:15:28 -05:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
b4e005be7f Version Packages (#401)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-22 14:31:57 -08:00
Nacho IacovinoandGitHub ccb7db4873 [Solana + React] Update hooks for creators/royalties (#405) 2022-11-22 19:22:51 +00:00
Jonas DanielsandGitHub 9151aa7dc8 [SDK] - expose getDefaultTrustedForwarders helper fn (#404) 2022-11-22 03:35:01 +00:00
5a01c537e3 [DO NOT MERGE] Update to Metaplex v0.17 (#305)
Co-authored-by: Jonas Daniels <[email protected]>
2022-11-21 16:14:39 -08:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
f09c153ff7 Version Packages (#391)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-21 15:22:56 -08:00
Nacho IacovinoandGitHub 15431621fd [React] Remove console.log (#400) 2022-11-21 20:03:32 +00:00
Jonas DanielsandGitHub 887af24450 [SDK] - fix error handling for nullish error values (#399) 2022-11-21 18:52:02 +00:00
Jonas DanielsandGitHub 15514f190a [SDK] - add default value option to constructorParams schema (#398) 2022-11-21 18:28:18 +00:00
Adam MajmudarandGitHub 72589ec234 Call user callback in getUser (#397) 2022-11-21 17:46:18 +00:00
Jonas DanielsandGitHub f8bceec10c fix solana claim condition native token (#395) 2022-11-19 05:36:42 +00:00
Adam MajmudarandGitHub 7c0744a006 Add support for total supply and pagination on get all (#388) 2022-11-18 02:21:32 +00:00
Nacho IacovinoandGitHub 846022e2cf [React] Fix unlimited price (#392) 2022-11-17 22:25:25 +00:00
Joaquim VergesandGitHub 96bd92e724 [SDK] Expose getAllDetectedFeatures(ABI) helper function (#390) 2022-11-17 14:07:37 -08:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
c2b6d977ed Version Packages (#383)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-16 14:02:50 -08:00
7cb8e59be4 [SDK] Add new Drop contract implementation addresses (#364)
Co-authored-by: Jonas Daniels <[email protected]>
Co-authored-by: Adam Majmudar <[email protected]>
2022-11-16 21:52:01 +00:00
Adam MajmudarandGitHub 04a47e8971 Add retroactive creator and royalty update option (#385) 2022-11-16 21:37:45 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
8a6a97a3e9 Bump loader-utils from 2.0.3 to 2.0.4 (#384)
Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-16 19:51:40 +00:00
Jonas DanielsandGitHub 612bcdd16f [REACT] - update gnosis connector (#386) 2022-11-16 19:34:27 +00:00
Jonas DanielsandGitHub 0ed77d2c9e [SDK] - add constructorParams to schema for better release -> deploy (#382) 2022-11-15 20:47:54 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
7129aef6e1 Version Packages (#370)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-11 08:51:19 -08:00
Joaquim VergesandGitHub f50b74819d [SDK] make isConnected sync, remove useless fn (#381) 2022-11-11 06:14:24 +00:00
Joaquim VergesandGitHub 3eba69afd7 [SDK] expose signer's chain id via sdk.wallet (#380) 2022-11-11 00:42:05 +00:00
Jarrod WattsandGitHub 98c2253e8f [SDK] Docs - Add await before sdk.getContract snippets (#379) 2022-11-10 16:08:31 -08:00
32d91ef709 [REACT] Fix Border Radius for Safari (#378)
Co-authored-by: Jarrod Watts <[email protected]>
2022-11-10 09:53:17 -08:00
Adam MajmudarandGitHub b79dc18f7a Add event filtering on topics (#377) 2022-11-09 11:51:13 -05:00
Adam MajmudarandGitHub 4af785c37c Add TokensClaimed event to tiered-drop (#376) 2022-11-08 20:34:45 +00:00
Adam MajmudarandGitHub 6f818f393e Updated tiered-drop contract (#373) 2022-11-03 17:03:00 -07:00
Adam MajmudarandGitHub 97ed4779a9 Update nft drop claimTo documentation (#372) 2022-11-03 22:42:42 +00:00
Nacho IacovinoandGitHub 2d3fca5237 [React] Add useClaimerProofs hook (#369) 2022-11-03 01:17:15 +01:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
7016019f2a Version Packages (#366)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-02 15:16:25 -07:00
Joaquim VergesandGitHub 4e7b293c54 [SDK] Fix handling of old allowlist proof format (#368) 2022-11-02 14:11:13 -07:00
Jonas DanielsandGitHub c9c0e4ff39 [SDK] - make EVM side react native compatible (#365) 2022-11-02 05:38:56 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
06c24c153a Version Packages (#361)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-01 16:13:47 -07:00
aa6d9ed75d [SDK] Support new Drop claim conditions mechanics (#333)
Co-authored-by: adam-maj <[email protected]>
Co-authored-by: Adam Majmudar <[email protected]>
2022-11-01 23:07:10 +00:00
Joaquim VergesandGitHub 42a606588d [SDK] Fix fetching NFTs with numbers as ids (#362) 2022-11-01 22:01:01 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
2820761003 Version Packages (#360)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-01 13:49:34 -07:00
Adam MajmudarandGitHub 5200d5d7e7 Add support for TieredDrop in extensions (#329) 2022-11-01 13:48:48 -07:00
Joaquim VergesandGitHub e731c1a7c3 [SDK] Allow fetching claimerProofs from any claim condition (#359) 2022-10-31 23:26:27 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
2e8d3fd6e7 Version Packages (#358)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-10-28 18:14:35 -07:00
Nacho IacovinoandGitHub cc4613b5fd [React] Add Pack and Multiwrap as NFTContract types (#356) 2022-10-29 01:28:40 +02:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
78566babaa Version Packages (#354)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-10-28 10:29:57 -07:00
Joaquim VergesandGitHub 65fc7ba6ff [SDK] Expose claimCondtions.getClaimerProofs(address) (#357) 2022-10-28 10:25:36 -07:00
Nacho IacovinoandGitHub 1c24c3c3c4 [Multi] Add useUpdateCreator hook, fix CreatorInput schema (#353) 2022-10-26 18:19:32 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
408c5a81fa Version Packages (#347)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-10-26 08:38:25 -07:00
Joaquim VergesandGitHub 352291791e [SDK, React] expose marketplace.auction.executeSale (#352) 2022-10-26 00:19:01 +00:00
Jonas DanielsandGitHub aabbb149e8 [React] - fix wallet connection during hot reload (#351) 2022-10-25 22:48:39 +00:00
Jonas DanielsandGitHub d59450f814 do not release e2e tests (#350) 2022-10-25 20:29:22 +00:00
7d9a4c6abc Update name of useRoyalty, and update (#348)
Co-authored-by: Jonas Daniels <[email protected]>
2022-10-25 19:56:09 +00:00
Jonas DanielsandGitHub 99806e595d [VARIOUS] - exclude sizes of test files etc (#349) 2022-10-25 18:39:30 +00:00
Nacho IacovinoandGitHub 21c21c1adf resolveReleasesFromAddress -> resolveContractUriFromAddress (#344) 2022-10-24 23:43:43 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
4b10719047 Version Packages (#345)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-10-24 16:18:44 -07:00
Joaquim VergesandGitHub 989cf7347c [React, SDK] Small fixes for useOffers and makeOffers (#346) 2022-10-24 23:09:32 +00:00
Joaquim VergesandGitHub 72227b2e16 [SDK, React] Expose new useOffers and useMakeOffer hooks (#343) 2022-10-24 15:28:34 -07:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
ed6c54f20d Version Packages (#336)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-10-21 13:26:24 -07:00
Joaquim VergesandGitHub 26116a6f63 [SDK] Update to new univeral RPC endpoint (#342) 2022-10-21 13:21:11 -07:00
Jonas DanielsandGitHub f11a2719ff [workflow] github hosted runners (#340) 2022-10-20 22:02:58 -07:00
Jonas DanielsandGitHub ef27aad0aa [Various, React] - add initial e2e testing setup (#327) 2022-10-21 04:19:04 +00:00
Nacho IacovinoandGitHub b03a902145 [React] Docs update (#339) 2022-10-20 20:17:01 -07:00
Adam MajmudarandGitHub 340605b507 Clean native token address in changeset (#337) 2022-10-20 23:57:55 +00:00
Adam MajmudarandGitHub 15f8006e1f Export smart contract (#335) 2022-10-20 23:46:02 +00:00
Adam MajmudarandGitHub 811c5a1166 Update code snippets for signature minting (#334) 2022-10-20 23:29:07 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
c41a80d86d Version Packages (#331)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-10-20 15:35:12 -07:00
Joaquim VergesandGitHub ad851f7b4d [SDK] Fix for finding addresses in legacy merkle tree format (#332) 2022-10-20 21:35:52 +00:00
Joaquim VergesandGitHub 6218c88584 [SDK] Fix for deploy byte parameters (#330) 2022-10-20 04:47:55 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
c9b564feaf Version Packages (#323)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-10-19 21:19:06 -07:00
Adam MajmudarandGitHub 87fd6ab14e Update storage download on fail (#324) 2022-10-19 12:44:36 -07:00
Joaquim VergesandGitHub df74340fa5 [SDK] Import cbor-x fully for es builds (#328) 2022-10-19 17:46:54 +00:00
Joaquim VergesandGitHub a57b4f01f3 [SDK] Implement sharded merkle trees for lightweight allowlist checks (#321) 2022-10-19 16:54:09 +00:00
Jonas DanielsandGitHub 126752d7d0 [Various] - clean up extraneous dependencies (#326) 2022-10-18 23:56:04 -07:00
89ff921a7d Fix vite (#315)
Co-authored-by: Jonas Daniels <[email protected]>
Co-authored-by: Joaquim Verges <[email protected]>
2022-10-18 15:23:57 -07:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
9124b3180c Version Packages (#308)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-10-18 15:02:14 -07:00
Adam MajmudarandGitHub f41a443c57 Add update creators and update royalty (#320) 2022-10-18 21:50:47 +00:00
Joaquim VergesandGitHub b7cd744cd0 [SDK] Sign multiple solana claims at once (#322) 2022-10-18 21:35:03 +00:00
bb1b4e6ac3 [React] Add useMinimumNextBid hook (#318)
Co-authored-by: Jonas Daniels <[email protected]>
2022-10-18 11:57:26 -07:00
2f8ec89c4c [SDK, React] Expose total claimed/unclaimed supply for erc721 contracts (#319)
Co-authored-by: Nacho Iacovino <[email protected]>
2022-10-17 18:17:54 -07:00
Joaquim VergesandGitHub 6ae52664e5 [React] Fix passing wrong RPC url to UserWallet when using an external signer (#316) 2022-10-17 22:26:15 +00:00
Adam MajmudarandGitHub 4f867e15ed Fix supply in nft.get() (#317) 2022-10-17 19:17:43 +00:00
cc8f983615 fix typo (#314)
Co-authored-by: Joaquim Verges <[email protected]>
2022-10-16 22:27:40 +00:00
Joaquim VergesandGitHub f45ef62128 [SDK] return fallback metadata when tokenId is not found on nft contract (#313) 2022-10-16 15:15:26 -07:00
9727502eb3 Add useMintNFTSupply hook (#310)
Co-authored-by: Jonas Daniels <[email protected]>
2022-10-14 13:32:43 -07:00
Adam MajmudarandGitHub b6eec6146c [Solana] Add quantity to mint additional supply (#312) 2022-10-14 19:23:07 +00:00
88daa3c5cb [SDK] Check for undefined ABI (#309)
Co-authored-by: Joaquim Verges <[email protected]>
2022-10-14 03:37:40 +00:00
Adam MajmudarandGitHub 53c6507669 Add deploy event listener (#306) 2022-10-13 21:28:24 +00:00
YashandGitHub 782b58d3f6 [SDK] Fix multicall txns in a gasless setup (#307) 2022-10-13 11:57:02 -07:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
e17e41f4d1 Version Packages (#304)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-10-12 15:22:33 -07:00
Joaquim VergesandGitHub 712b11a43e [SDK] Fix not getting real owner of Solana NFTs (#303) 2022-10-12 22:12:53 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
306debb029 Version Packages (#302)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-10-12 10:57:32 -07:00
Joaquim VergesandGitHub 86f0ceff46 [React] Remove useAddress hook for now (#301) 2022-10-12 17:54:14 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
7f0d1ec947 Version Packages (#300)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-10-12 10:23:15 -07:00
Joaquim VergesandGitHub b1218cbd7d [React] Recreate SDK on wallet changes to propagate to useAddress and other hooks (#299) 2022-10-12 10:12:21 -07:00
Joaquim Verges 97ef35ce0f [SDK] docstrings for claim conditions 2022-10-12 08:48:58 -07:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
1f46f270cd Version Packages (#267)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-10-12 00:36:55 -07:00
Jonas DanielsandGitHub e8c25ed0f2 [React] - fix getBalance (#298) 2022-10-12 05:28:15 +00:00
Jonas DanielsandGitHub 78d6d3c159 [SDK] - fix solana getAddress (#297) 2022-10-12 04:49:39 +00:00
Joaquim Verges c72d92956a update generate snippets scripts 2022-10-11 21:28:39 -07:00
Jonas DanielsandGitHub cf88795376 [SDK, React] - useBalance hook (#296) 2022-10-12 04:15:06 +00:00
Jonas DanielsandGitHub 47287fb189 [Various] - fix lint (#295) 2022-10-11 21:02:38 -07:00
Joaquim Verges 3763326c25 [React] Fix docstrings 2022-10-11 20:32:10 -07:00
Joaquim Verges 894eb27dfa [SDK] Fix docstrings 2022-10-11 20:21:11 -07:00
Joaquim VergesandGitHub 8b3b97c8f7 [SDK] Fix getAllClaimed for Solana NFT drops (#293) 2022-10-12 00:31:19 +00:00
Jonas DanielsandGitHub 89d87a5eb3 [SDK] - fix batch upload for lazy mint (#294) 2022-10-12 00:18:15 +00:00
Jonas DanielsandGitHub 492a818079 [SOL] - expose useAddress() (#292) 2022-10-11 21:10:43 +00:00
Jonas DanielsandGitHub 86f608390a [React] - expose .program on useProgram() (#291) 2022-10-11 21:00:56 +00:00
Jonas DanielsandGitHub 8096c78b46 [SDK, React] - claim changes (#290) 2022-10-11 20:48:51 +00:00
Nacho IacovinoandGitHub 521a49c6ec [Solana] Standarize use claim (#289) 2022-10-11 10:50:35 -07:00
Joaquim VergesandGitHub 25a4773bba [SDK] Add pagination to getAll() for solana nft collections (#286) 2022-10-11 05:16:20 +00:00
18381fac73 Fix errorneous ERC20 Allowance check (#280)
Co-authored-by: Joaquim Verges <[email protected]>
2022-10-10 21:56:16 +00:00
Joaquim VergesandGitHub 89b5c6fe07 [SDK] Make solana drop creation and register transactions sequential (#285) 2022-10-10 14:43:09 -07:00
Joaquim VergesandGitHub 4dccccc6fa [SDK] Solana docs update (#284) 2022-10-10 12:44:55 -07:00
Jarrod WattsandGitHub de15e4212f [REACT] - Update Broken Links to Portal in README (#281) 2022-10-10 00:54:37 +00:00
Jarrod WattsandGitHub 1f41adbd2c [REACT] - Fix useActiveClaimCondition invariant failing for token ID 0 (#282) 2022-10-10 11:13:00 +11:00
Furqan RydhanandGitHub 1918495f2e Command Updates (detect -> build) + helper text (#279) 2022-10-09 16:21:07 -07:00
24514a6e9f Fr/command updates (#276)
Co-authored-by: Joaquim Verges <[email protected]>
2022-10-08 03:29:20 +00:00
Adam MajmudarandGitHub ad06c5b289 Add auth support to react and auth packages (#274) 2022-10-07 21:20:36 +00:00
Adam MajmudarandGitHub 9de3f8c8e9 Add support for recursive folder upload (#277) 2022-10-07 19:09:40 +00:00
Joaquim VergesandGitHub b1fa17158d [SDK] Expose maxClaimable and disallow claiming drops by default (#273) 2022-10-07 02:16:52 +00:00
Nacho IacovinoandGitHub 2bdf1984cb [Solana] Add claim conditions hooks (#272) 2022-10-07 02:36:20 +02:00
Adam MajmudarandGitHub df048af605 Add support for auth to Solana (#271) 2022-10-06 17:05:18 -07:00
Joaquim VergesandGitHub 41507d32a7 [SDK] Solana Program Registry Integration (#270) 2022-10-06 16:21:17 -07:00
Jonas DanielsandGitHub b2cadf164c [SDK, React] - remove deprecated chains (#269) 2022-10-06 00:20:53 -07:00
Adam MajmudarandGitHub 57b9c671aa [CLI] Update storage upload CLI (#268) 2022-10-05 15:29:16 -07:00
Adam MajmudarandGitHub 3b7d10ed93 [React] Add hook to create a storage upload component (#266) 2022-10-05 15:08:43 -07:00
Jonas DanielsandGitHub d6bb61b7fa [SDK] - align getProgram & make chainId getter available on EVM contracts (#263) 2022-10-05 20:06:34 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
8e591383fc Version Packages (#265)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-10-05 12:53:02 -07:00
Adam MajmudarandGitHub 6f95a520e6 [CLI] Add npx thirdweb upload command (#259) 2022-10-05 18:42:03 +00:00
Nacho IacovinoandGitHub f669d3ef4a [React] Use same data structure for useLazyMint (#264) 2022-10-05 11:25:42 -07:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
83575058db Version Packages (#235)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-10-04 21:02:13 -07:00
Jonas DanielsandGitHub 028cb78125 [SDK] - fix HexColor schema (#262) 2022-10-05 01:31:10 +00:00
Jonas DanielsandGitHub c8261b74b5 [SDK, React] - align getContract and useContract across sdk and react (#261) 2022-10-04 18:09:36 -07:00
Jonas DanielsandGitHub a36c788415 Create size.yml 2022-10-04 12:47:09 -07:00
Nacho IacovinoandGitHub ac232b5aff Accept TokenContract instead of erc20 instance (#258) 2022-10-04 18:39:13 +00:00
Jonas DanielsandGitHub ba6f45027a [SDK] - fix permissions enumerable export (#257) 2022-10-04 17:51:10 +00:00
Jonas DanielsandGitHub d677e9d634 [React] - enable permissions enumerable feature (#256) 2022-10-04 17:21:22 +00:00
Jonas DanielsandGitHub 9b92697fb7 [React] - useContract can accept an abi now (#255) 2022-10-04 04:40:16 +00:00
Joaquim VergesandGitHub c19e471f65 [React] Update react docs (#254) 2022-10-03 21:13:07 -07:00
Jonas DanielsandGitHub b6fc298d0c [React] - allow passing in contractType in useContract() (#253) 2022-10-03 20:18:07 -07:00
Jonas DanielsandGitHub ea41231b3e [React] - fix usage of Buffer (#251) 2022-10-04 01:26:37 +00:00
Joaquim VergesandGitHub 2ea3f00c41 [SDK] Expose additional claim condition information (#252) 2022-10-04 00:26:46 +00:00
20745f8cd6 [SDK] Add check if abi exists (#250)
Co-authored-by: Jonas Daniels <[email protected]>
2022-10-03 22:36:32 +02:00
Furqan RydhanandGitHub caf979537b AppURI detection enabled [SDK] (#247) 2022-10-03 19:12:09 +00:00
Joaquim VergesandGitHub e4b10bc5bd [SDK] Polish + Fixes for Solana NFT Drops (#249) 2022-10-03 12:03:16 -07:00
ef0bac7f44 Renamed initial commit message during thirdweb cli createApp (#246)
Co-authored-by: simon.lim <[email protected]>
Co-authored-by: Jonas Daniels <[email protected]>
2022-10-02 16:43:30 +00:00
Jonas DanielsandGitHub 23de9eac4f Update README.md 2022-10-02 09:38:13 -07:00
Jonas DanielsandGitHub 1972f3ec0d [SDK, React] - useBurnNFT for solana (#245) 2022-10-01 01:46:07 +00:00
Adam MajmudarandGitHub ffd0fc42ae [React] Add code snippets for Solana (#244) 2022-09-30 15:28:21 -07:00
Jonas Daniels 93531a5d47 fix build outputs 2022-09-30 15:16:16 -07:00
Joaquim Verges b16aaebc4c update solana docs 2022-09-30 10:30:32 -07:00
Jonas DanielsandGitHub 1136d959ba fix persister logic (#243) 2022-09-30 04:38:40 +00:00
Jonas DanielsandGitHub db23f0588d [Storage] - send different header in tests (#242) 2022-09-29 20:14:53 -07:00
Jonas DanielsandGitHub e662408e19 [SDK] - unify program metadata return type again (#240) 2022-09-30 01:41:08 +00:00
Adam MajmudarandGitHub afe4ba6471 Update solana docs (#239) 2022-09-30 00:27:45 +00:00
Joaquim VergesandGitHub 6647f707bd [SDK, React] Unify NFT types for EVM and Solana (#238) 2022-09-30 00:12:37 +00:00
Jonas DanielsandGitHub cac373b010 [React, SDK] - solana improvements (#236) 2022-09-29 06:51:16 +00:00
Joaquim VergesandGitHub 9412d41683 [SDK] add burn function, better RPC, rename inputs (#234) 2022-09-28 22:16:09 -07:00
github-actions[bot]andGitHub 2506eeb25d Version Packages (#227) 2022-09-28 19:37:48 -07:00
ba7dcbbad8 [SDK] - Add getMinimumNextBid function to marketplace (#182)
Co-authored-by: Jonas Daniels <[email protected]>
Co-authored-by: Jarrod Watts <[email protected]>
2022-09-28 19:20:17 -07:00
Adam MajmudarandGitHub cd1abe6ba7 [Solana] Add code example snippets (#233) 2022-09-29 02:05:35 +00:00
e1bcc67ceb [CLI] - Set package.json name to the name the user entered for the project (#103)
Co-authored-by: Jarrod Watts <[email protected]>
Co-authored-by: Nacho Iacovino <[email protected]>
Co-authored-by: Jonas Daniels <[email protected]>
2022-09-29 01:14:46 +00:00
d26b76872a [SDK] Dynamically import anchor library (#232)
Co-authored-by: Jonas Daniels <[email protected]>
2022-09-28 18:01:57 -07:00
9711b51067 [SOL] Add README.md (#231)
Co-authored-by: Jonas Daniels <[email protected]>
2022-09-28 22:54:57 +00:00
Jonas Daniels e2037310a6 stale is not a workflow... 2022-09-28 14:32:30 -07:00
Jonas Daniels 683d542334 handle stale issues 2022-09-28 14:32:03 -07:00
9c8a3fb6d4 [SDK, React] Add Solana claimTo, pass quantity to claim, and expose useClaim hook (#229)
Co-authored-by: Jonas Daniels <[email protected]>
2022-09-28 14:10:18 -07:00
Jonas Daniels 41accc2e21 never cache contracts-js build 2022-09-28 13:51:36 -07:00
Jonas DanielsandGitHub f2a62110c4 try out buildjet (#226) 2022-09-28 13:31:55 -07:00
Adam MajmudarandGitHub db9f811bf8 [SDK] Fix docs setup for multiple entrypoints (#230) 2022-09-28 19:44:52 +00:00
Joaquim VergesandGitHub fc5efe9521 [SDK] export TransactionTask for docs (#228) 2022-09-28 11:25:41 -07:00
82397636f4 [SDK] Get all offers for a listing (#191)
Co-authored-by: Jarrod Watts <[email protected]>
Co-authored-by: Joaquim Verges <[email protected]>
2022-09-28 18:15:18 +00:00
27a30e3ffb [SDK] - Add ability to view and update owner of a contract (#194)
Co-authored-by: Jarrod Watts <[email protected]>
Co-authored-by: Joaquim Verges <[email protected]>
2022-09-28 17:25:06 +00:00
github-actions[bot]andGitHub 2f1155239d Version Packages (#223) 2022-09-27 22:20:38 -07:00
Jonas DanielsandGitHub c295a47144 [SDK, React] - fix esm exports (#221) 2022-09-28 04:41:53 +00:00
Joaquim VergesandGitHub 0dade96d0d [SDK] Check that proxy/factory deploy flag properly is set (#224) 2022-09-28 04:17:41 +00:00
Joaquim VergesandGitHub 666ff5f694 [SOL] expose ThirdwebSDK.fromPrivateKey convenience static method (#222) 2022-09-28 02:50:38 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
8bc41cdc60 Version Packages (#214)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-09-27 18:08:47 -07:00
Joaquim VergesandGitHub 37a707f98c [React] lock zag version (#220) 2022-09-27 17:58:44 -07:00
Joaquim VergesandGitHub 3c8f6205e9 [SDK] expose proxy deploy for released contracts (#217) 2022-09-27 17:10:48 -07:00
Jonas DanielsandGitHub 1eaedc262f [React] - allow null and undefined for RequiredParam (#218) 2022-09-27 22:10:05 +00:00
e187d21e12 [SDK] Merge solana package into main SDK (#213)
Co-authored-by: Jonas Daniels <[email protected]>
2022-09-27 13:36:29 -07:00
YashandGitHub b030a86608 [SDK] Update addresses (#216) 2022-09-27 11:10:11 -07:00
acbabc8999 [SDK] - Relayer gas override (#206)
Co-authored-by: Jarrod Watts <[email protected]>
2022-09-27 19:05:29 +05:30
Jonas DanielsandGitHub 196195e2f9 [React] - fix small discrepancies (#215) 2022-09-27 10:27:32 +00:00
Jonas DanielsandGitHub 7c86babb86 [React] - subdivide react sdk (#208) 2022-09-27 09:35:45 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
36f2b70d57 Version Packages (#207)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-09-27 02:13:05 -07:00
Jarrod WattsandGitHub 849146bf5c [SDK] Docs: Update getContract snippet to use await (#212) 2022-09-27 03:41:12 +00:00
Jarrod WattsandGitHub 4cac79c45d [REACT] Docs: Remove broken link from migration guide (#210) 2022-09-27 02:17:13 +00:00
Jonas DanielsandGitHub 1bda83b114 Jd/fix react effect warning (#209) 2022-09-26 22:40:48 +00:00
Joaquim VergesandGitHub ce05bfd861 [SDK] Remove usages of Buffer to decode bytecodes (#205) 2022-09-26 13:29:24 -07:00
Jarrod WattsandGitHub d982a98b0c Jw/fix signature mint snipptes (#203) 2022-09-26 06:51:50 +00:00
Jarrod WattsandGitHub b983087101 Jw/fix signature mint snipptes (#202) 2022-09-26 05:23:08 +00:00
Jarrod WattsandGitHub b25789fa46 Jw/migration guide (#200) 2022-09-26 14:42:26 +10:00
github-actions[bot]andGitHub e39b66f309 Version Packages (#198) 2022-09-23 19:34:55 -07:00
5f5ab015e1 [SDK, SOL] Fixes for getOwned and solana balance (#199)
Co-authored-by: Jonas Daniels <[email protected]>
2022-09-24 02:11:58 +00:00
Jonas DanielsandGitHub f4f05bd9a4 [React] - make web3 button network switch obvious (#197) 2022-09-24 00:16:56 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
2f5b66bef9 Version Packages (#193)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-09-23 15:27:49 -07:00
63258bc9c3 [React] Expose simple provider and useSDK hook for solana (#179)
Co-authored-by: Jonas Daniels <[email protected]>
2022-09-23 19:12:24 +00:00
Jonas DanielsandGitHub a80fc97b6a [SDK] - update prebuilt contract roles to match contracts (#195) 2022-09-23 18:49:41 +00:00
Adam MajmudarandGitHub 24f66e38c2 Switch to using XHR with timeout (#192) 2022-09-23 05:32:45 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
b5bfaefa85 Version Packages (#157)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-09-22 17:11:41 -07:00
Adam MajmudarandGitHub 493ebf032e Add upload with gateway url for URIs (#190) 2022-09-22 17:06:59 -07:00
Adam MajmudarandGitHub d608cea197 Add progress tracking to file upload (#189) 2022-09-22 15:15:00 -07:00
Adam MajmudarandGitHub a9ec190ff9 Remove JSON types (#188) 2022-09-22 21:27:43 +00:00
3edec391be [CLI] thirdweb deploy redirects to contract deploy page if no contracts detected (#177)
Co-authored-by: Jonas Daniels <[email protected]>
Co-authored-by: Joaquim Verges <[email protected]>
2022-09-22 14:07:32 -07:00
bdec5a59af [CLI] Fix "Invalid Project name" when a project with a capital letter is entered (#184)
Co-authored-by: Jonas Daniels <[email protected]>
2022-09-22 20:20:15 +00:00
Jonas DanielsandGitHub 9d03619aab fix some lint issues (#187) 2022-09-22 19:02:22 +00:00
Jonas DanielsandGitHub 0ccbca78dc [Storage] - handle special chars (#185) 2022-09-22 11:29:42 -07:00
Adam MajmudarandGitHub 75c752cc14 Fix tests (#186) 2022-09-22 11:06:55 -07:00
Jonas DanielsandGitHub 3580182fa9 [Storage] - allow uploading the same file multiple times in uploadBatch if it is *the same file* (#183) 2022-09-22 09:33:24 +00:00
b54f95dc90 Update expected input types for storage (#163)
Co-authored-by: Jonas Daniels <[email protected]>
2022-09-22 08:12:52 +00:00
Adam MajmudarandGitHub f4074ddadc Replace schemes after replacing files (#180) 2022-09-22 06:43:22 +00:00
Jonas DanielsandGitHub 208b0389a5 [React] - use internal Signer (#168) 2022-09-22 06:04:27 +00:00
3b877ba221 [SDK] Ozdefender EOA forwarder option (#174)
Co-authored-by: Joaquim Verges <[email protected]>
2022-09-22 04:47:00 +00:00
Adam MajmudarandGitHub 45a400fd92 Change API for instantiating storage (#178) 2022-09-21 21:09:11 -07:00
Adam MajmudarandGitHub 3332fa5697 Split create contract flow into steps (#175) 2022-09-21 22:51:47 +00:00
Joaquim VergesandGitHub fdda564b1e [SOL] Fix browser build (#173) 2022-09-21 14:35:19 -07:00
Adam MajmudarandGitHub 89db3db7ff Add changeset for CLI (#172) 2022-09-21 20:15:09 +00:00
Adam MajmudarandGitHub bd9c705571 Add thirdweb deploy to end of thirdweb detect (#171) 2022-09-21 19:55:54 +00:00
Adam MajmudarandGitHub 0ad0f21bcd Display yarn build command at the end of thirdweb create --contract (#169) 2022-09-21 19:18:42 +00:00
Joaquim VergesandGitHub 4169b9428f [SDK] Syntax fixes for react native support (#167) 2022-09-21 09:35:22 -07:00
Jarrod WattsandGitHub 2f9e8aaab4 Jw/lazymintabletwfeature (#165) 2022-09-21 04:17:11 +00:00
Adam MajmudarandGitHub 421461ece0 Add README for Solana and Storage (#164) 2022-09-21 02:39:12 +00:00
Jarrod WattsandGitHub 485ebc8400 [REACT] - Feature snippet generation logic (#155) 2022-09-21 10:40:41 +10:00
Joaquim VergesandGitHub 772f8431e3 [SDK] Catch gas estimate errors in gasless tx (#162) 2022-09-20 23:00:12 +00:00
Joaquim VergesandGitHub 5345479922 [SDK] Allow forcing direct deploys to deploy implementations from release flow (#161) 2022-09-20 15:19:18 -07:00
Adam MajmudarandGitHub cfe8bbafa4 Add resolveScheme method to storage (#156) 2022-09-20 18:31:56 +00:00
Adam MajmudarandGitHub 18dc8d33ed Fix nft collection docs (#159) 2022-09-20 18:07:30 +00:00
Jonas DanielsandGitHub f8ab4779bb init paper checkout in v3 (#154) 2022-09-20 05:41:20 +00:00
Adam MajmudarandGitHub 6fe16c5bf2 Add documentation for Solana (#152) 2022-09-19 22:13:25 -07:00
Adam MajmudarandGitHub ba0e169654 Add support for string with name (#151) 2022-09-19 18:08:55 -07:00
Jarrod WattsandGitHub 27b869ed93 Update README.md (#150) 2022-09-20 00:25:11 +00:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
091ce2eb45 Version Packages (#149)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-09-19 16:08:23 -07:00
Joaquim Verges e24a371508 fix changeset 2022-09-19 16:03:14 -07:00
Adam MajmudarandGitHub b86afb4b09 Add documentation for storage (#147) 2022-09-19 22:26:44 +00:00
Joaquim VergesandGitHub 964add6f20 [CLI, Storage] Fix deploy/release uploads via CLI (#148) 2022-09-19 14:56:42 -07:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
ec414bbc42 Version Packages (#136)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-09-19 11:11:34 -07:00
Joaquim VergesandGitHub 51dde28224 [SDK, React] Fix using external signers with ThirdwebSDKProvider (#143) 2022-09-19 18:03:39 +00:00
Adam MajmudarandGitHub 57432d21c4 Update Storage SDK (#139) 2022-09-19 16:58:12 +00:00
Jarrod WattsandGitHub 19d87c2885 Jw/react readme (#144) 2022-09-19 07:20:08 +00:00
Joaquim VergesandGitHub 68812e9d27 Update README.md 2022-09-17 11:29:03 -07:00
Joaquim VergesandGitHub 90c53475f0 Update README.md 2022-09-17 11:23:54 -07:00
Joaquim VergesandGitHub 5a52585a7a [SOL] More solana integration (#140) 2022-09-16 19:15:35 -07:00
Joaquim VergesandGitHub 6b48b9288b [SOL] solana dashboard integration (#138) 2022-09-16 13:19:17 -07:00
Joaquim VergesandGitHub 9d74a43aac [SDK] Make contract events generic for better DX (#133) 2022-09-16 05:51:23 +00:00
Jonas DanielsandGitHub 9c7e5518ff [SOL] - enforce owner when deploying (#137) 2022-09-15 22:24:05 -07:00
Jonas DanielsandGitHub b234c58d44 [SDK] - less rpc calls = good (#135) 2022-09-16 03:43:24 +00:00
Adam MajmudarandGitHub b1ae844e8b Reorder CLI commands (#134) 2022-09-15 20:20:43 -07:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
78bae497ba Version Packages (#126)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-09-15 14:00:20 -07:00
Joaquim VergesandGitHub 3e425bf8e6 [SOL] get account type for a given address (#132) 2022-09-15 20:54:45 +00:00
Jarrod WattsandGitHub 4dca5b21a6 Change feature detection URLs (#128) 2022-09-15 13:45:04 -07:00
Joaquim VergesandGitHub 42c79e93dc [SDK] fix editing releases from the dashboard (#131) 2022-09-15 19:17:02 +00:00
Joaquim VergesandGitHub 2951b5533c [SOL] New return type for registry.getAccountsForWallet (#130) 2022-09-15 18:09:52 +00:00
Joaquim VergesandGitHub fe8751eeae [SDK] add ownable feature detection (#124) 2022-09-15 17:41:32 +00:00
Jonas DanielsandGitHub a0cd47ec35 [SOL] - explicitly export the missing schemata (#129) 2022-09-15 17:13:20 +00:00
Jarrod WattsandGitHub 3902e7aba4 Update read and write hook names for snippet generation (#127) 2022-09-15 17:36:23 +10:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
8717cb2c05 Version Packages (#118)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-09-14 19:38:16 -07:00
Jarrod WattsandGitHub d57ab03f5d Add useContract hook snippet back in (#125) 2022-09-15 12:34:57 +10:00
Joaquim VergesandGitHub 5aa3c433d7 [Solana] Add sdk.wallet.getBalance() (#123) 2022-09-14 19:27:52 +00:00
Joaquim VergesandGitHub 98dd64a375 [SDK] handle legacy claim method signature in extensions (#122) 2022-09-14 19:15:47 +00:00
Joaquim VergesandGitHub e25dd1ac8e [Solana] Handle WalletAdapter connections, internal cleanup (#120) 2022-09-14 05:04:08 +00:00
Jonas DanielsandGitHub e68f9685b3 fix snippets (#119) 2022-09-14 03:16:58 +00:00
Joaquim VergesandGitHub 84beda1cbb [Solana] Create account registry (#117) 2022-09-13 16:22:00 -07:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
32e7fb0c96 Version Packages (#92)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-09-13 15:24:45 -07:00
Joaquim VergesandGitHub 8202cc60d8 v3 release notes (#116) 2022-09-13 15:16:00 -07:00
Jonas DanielsandGitHub a37bc00991 [SDK] - add sales to token pre-built (#115) 2022-09-13 20:49:11 +00:00
b442c97080 [SDK] Fix get owned for Signature Drop (#111)
Co-authored-by: Jonas Daniels <[email protected]>
2022-09-13 11:49:42 -07:00
Jonas DanielsandGitHub 1df2dea18f [CLI, REACT] - small improvements (#114) 2022-09-13 17:51:01 +00:00
0fa6f3fcfb [REACT, SDK] universal use-contract & async pre-built contracts (#106)
Co-authored-by: Joaquim Verges <[email protected]>
2022-09-13 09:12:14 -07:00
Jonas DanielsandGitHub b900b8503f Create codeql-analysis.yml (#113) 2022-09-13 07:44:16 +00:00
5a5bc36150 addPackContents function (#108)
Co-authored-by: Joaquim Verges <[email protected]>
2022-09-12 22:21:16 -07:00
Nacho IacovinoandGitHub 8158a55e66 Remove incorrect await (#110) 2022-09-12 21:39:16 +00:00
Adam MajmudarandGitHub f7ccc30f9d Add enabled check to useUser (#109) 2022-09-12 21:11:08 +00:00
78b40a94df [Solana] Add support for NFT Drop (#78)
Co-authored-by: Joaquim Verges <[email protected]>
2022-09-12 18:10:36 +00:00
YashandGitHub 95d850515c Pass empty trustedForwarders for Pack (#107) 2022-09-11 20:20:21 -07:00
Joaquim VergesandGitHub 1244c38162 [Solana] Custom Program support (#94) 2022-09-10 22:34:33 -07:00
Joaquim Verges 7b923be499 add twfeature for non-ERC extensions 2022-09-10 21:23:00 -07:00
Adam MajmudarandGitHub 0912dc5f9c [Solana] Remove error catch from supplyOf (#105) 2022-09-10 22:57:21 +00:00
052aa23888 Add test case and supplyOf (#102)
Co-authored-by: Jarrod Watts <[email protected]>
Co-authored-by: Joaquim Verges <[email protected]>
2022-09-10 22:45:16 +00:00
Joaquim Verges 6c10ed93cb Fix standard function snippets 2022-09-09 21:04:53 -07:00
Joaquim VergesandGitHub 2327a9d611 generate feature snippets for all ERC standards (#101) 2022-09-10 12:29:20 +10:00
Nacho IacovinoandGitHub 27ffbc252b [Multi] Fix typo (#100) 2022-09-10 01:27:40 +00:00
Jonas DanielsandGitHub a70b590be1 [SDK] - do not prompt to deploy again if user rejected the first call (#99) 2022-09-09 17:15:54 -07:00
45818944e5 Add mint additional supply and balance (#97)
Co-authored-by: Joaquim Verges <[email protected]>
2022-09-09 23:21:06 +00:00
Adam MajmudarandGitHub fe047d551e [Solana] Add nft helper common interface (#79) 2022-09-09 20:56:03 +00:00
82627ea031 [SDK, REACT] Switch to simpler detection API for ERC20/721/1155 extensions (#19)
Co-authored-by: Nacho Iacovino <[email protected]>
Co-authored-by: Jonas Daniels <[email protected]>
Co-authored-by: Nacho Iacovino <[email protected]>
2022-09-09 13:45:51 -07:00
Adam MajmudarandGitHub 1de14730bc Update auth docs domain to example.com (#96) 2022-09-09 19:02:27 +00:00
2adb8ff667 [SDK, React] Support arbitrum and optimism goerli testnets (#91)
Co-authored-by: Joaquim Verges <[email protected]>
2022-09-09 07:07:08 +00:00
Joaquim VergesandGitHub 820a5191b5 [SDK] Expose ERC721Claimable/ERC1155Claimable features (#90) 2022-09-08 21:44:20 -07:00
Jarrod WattsandGitHub c94ef909d0 Update README.md (#89) 2022-09-08 08:28:27 +00:00
Joaquim VergesandGitHub 8aef97d6f1 apply prettier on everything (#80) 2022-09-08 04:38:16 +00:00
Jarrod WattsandGitHub 8a5501fb80 Add contributing.md and update readme (#77) 2022-09-07 19:58:39 -07:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
8696199849 Version Packages (#67)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-09-06 21:03:48 -07:00
Joaquim VergesandGitHub 05353fd8da Add support for chain agnostic gasless tx (#71) 2022-09-06 20:52:39 -07:00
baa87a1fbd Update Opezeppelin forwarder address for Goerli (#74)
Co-authored-by: Krishang Nadgauda <[email protected]>
Co-authored-by: Joaquim Verges <[email protected]>
2022-09-07 03:17:18 +00:00
Jonas DanielsandGitHub 407932680f [SDK] - fix FactoryDeploymentSchema initialize function by adding a default (#75) 2022-09-06 22:40:18 +00:00
Jarrod WattsandGitHub 6bec17c07a [SDK] more snippets (#73) 2022-09-06 02:21:39 +00:00
Jarrod WattsandGitHub c379d19dfb [SDK] - Document contract from ABI (#72) 2022-09-06 02:00:07 +00:00
Joaquim VergesandGitHub 3e2bec8a47 Fix links in README 2022-09-05 15:29:23 -07:00
Jarrod WattsandGitHub 8b028c29d5 Update erc-1155-claimable.ts (#69) 2022-09-05 15:43:21 +10:00
Jarrod WattsandGitHub cc286841e2 Update erc-1155-mintable.ts (#68) 2022-09-05 15:01:56 +10:00
576d968a89 [SDK] Doc - Remove "reveal" from "create reveal batch" snippet (#66)
Co-authored-by: Joaquim Verges <[email protected]>
2022-09-05 02:36:43 +00:00
f2bdf47b4f [Solana] deploy and manage tokens (#63)
Co-authored-by: Jonas Daniels <[email protected]>
2022-09-04 19:15:58 -07:00
Jonas Daniels b92d3f7006 release dev 2022-09-02 18:49:15 -07:00
Jonas Daniels c9457bc2e7 also allow contributors 2022-09-02 18:38:06 -07:00
Jonas Daniels 3308bddd70 fix release pr action? 2022-09-02 18:37:39 -07:00
github-actions[bot]GitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
8954b8c5b6 Version Packages (#62)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-09-02 17:31:37 -07:00
Jonas DanielsandGitHub 3287c2b0f2 Jd/add pre release (#61) 2022-09-02 17:26:47 -07:00
Jonas DanielsandGitHub a5cdd85c77 [SDK] - rapid testing (#64) 2022-09-02 16:17:18 -07:00
e9e71cfcd8 Add CLI tests (#56)
Co-authored-by: Jonas Daniels <[email protected]>
2022-09-02 13:44:43 -07:00
2008 changed files with 110064 additions and 168601 deletions
+7 -4
View File
@@ -2,17 +2,20 @@
"$schema": "https://unpkg.com/@changesets/[email protected]/schema.json",
"changelog": ["@changesets/changelog-github", { "repo": "thirdweb-dev/js" }],
"commit": false,
"fixed": [],
"fixed": [
["@thirdweb-dev/sdk", "@thirdweb-dev/react-core", "@thirdweb-dev/react"]
],
"linked": [],
"access": "public",
"baseBranch": "main",
"updateInternalDependencies": "patch",
"ignore": [],
"ignore": ["e2e-cra-5", "e2e-next-12", "e2e-vite-3"],
"___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH": {
"updateInternalDependents": "always"
"updateInternalDependents": "always",
"onlyUpdatePeerDependentsWhenOutOfRange": true
},
"snapshot": {
"useCalculatedVersion": true,
"prereleaseTemplate": "{tag}-{commit}"
"prereleaseTemplate": "{tag}-{datetime}-{commit}"
}
}
+29
View File
@@ -0,0 +1,29 @@
# Order is important; the last matching pattern takes the most precedence.
# Platform team owns everything by default
* @thirdweb-dev/platform
# Devrel owns all markdown files (README etc.)
*.md @thirdweb-dev/devrel
.changeset/
# Shared ownership of the react and react-core packages
packages/react/ @thirdweb-dev/product @thirdweb-dev/platform
packages/react-core/ @thirdweb-dev/product @thirdweb-dev/platform
# Shared ownership of the CLI
packages/cli/ @thirdweb-dev/product @thirdweb-dev/platform
# Chains is owned specifically by jonas for now
packages/chains/ @jnsdls
# .github folder + .changeset + turbo config is owned by joaquim and jonas for now
.github/ @jnsdls @joaquim-verges
.changeset/config.json @jnsdls @joaquim-verges
turbo.json @joaquim-verges @jnsdls
+1 -1
View File
@@ -13,6 +13,6 @@ runs:
- name: Install dependencies
shell: bash
run: yarn install --frozen-lockfile
run: yarn
env:
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: "1"
+136
View File
@@ -0,0 +1,136 @@
# Contributing to thirdweb
You can find a full video tutorial on how to contribute to thirdweb below:
https://www.youtube.com/watch?v=TXsQ3qok3B0
## Getting Started
To get started, read the [How this repo works](#how-this-repo-works) section below to learn about the structure of this repo.
From there, you can take a look at our [Good First Issues](https://github.com/thirdweb-dev/js/labels/good%20first%20issue) board and find an issue that interests you!
If you have any questions about the issue, feel free to ask on our [Discord server](https://discord.gg/thirdweb) in the `#contributors` channel; where you'll be able to get help from our team and other contributors.
<br/>
## How this repo works
[@thirdweb-dev/js](https://github.com/thirdweb-dev/js) is a monorepo, meaning it contains many projects within it.
We use [Turborepo](https://turborepo.org/docs/getting-started) to manage the monorepo, and help speed up the [CI/CD](https://www.atlassian.com/continuous-delivery/principles/continuous-integration-vs-delivery-vs-deployment) pipeline to ship to production faster 🚢.
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> |
| [/storage](./packages/storage) | Best in class decentralized storage SDK for Browser and Node | <a href="https://www.npmjs.com/package/@thirdweb-dev/storage"><img src="https://img.shields.io/npm/v/@thirdweb-dev/storage?color=red&label=npm&logo=npm" alt="npm version"/></a> |
| [/cli](./packages/cli) | Publish and deploy smart contracts without dealing with private keys | <a href="https://www.npmjs.com/package/thirdweb"><img src="https://img.shields.io/npm/v/thirdweb?color=red&label=npm&logo=npm" alt="npm version"/></a> |
| [/solana](./packages/solana) | Solana SDK for Browser, Node and React Native | <a href="https://www.npmjs.com/package/@thirdweb-dev/solana"><img src="https://img.shields.io/npm/v/@thirdweb-dev/solana?color=red&label=npm&logo=npm" alt="npm version"/></a> |
## How to contribute
Let's explore how you can set up the repo on your local machine and start contributing!
This section requires some existing knowledge of [Git](https://git-scm.com/), [Node.js](https://nodejs.org/en/) and [Yarn](https://yarnpkg.com/).
<br/>
### Getting the repo
For OSS contributions, we use a [Forking Workflow](https://www.atlassian.com/git/tutorials/comparing-workflows/forking-workflow), meaning each developer will fork the repo and work on their own fork; and then submit a PR to the main repo when they're ready to merge their changes.
To begin:
1. [Create a fork](https://github.com/thirdweb-dev/js/fork) of this repository to your own GitHub account.
2. [Clone your fork](https://help.github.com/articles/cloning-a-repository/) to your local device.
3. Create a new branch on your fork to start working on your changes:
```
git checkout -b MY_BRANCH_NAME
```
4. Install the dependencies:
```
yarn
```
Now you have got the repo on your local machine, and you're ready to start making your changes!
### Test Your Changes
We use [yalc](https://github.com/wclr/yalc) to test changes locally.
Install the yalc CLI globally:
```bash
yarn global add yalc
```
First, create a test project where you can experiment with your changes:
You can create a basic starter project with the `sdk` and `react` packages installed using the CLI:
```bash
npx thirdweb create --app
```
Use `yalc` to link your local changes in the monorepo to the test project, by running the following command from your test repo:
```bash
yalc add @thirdweb-dev/react # Link the react package
yalc add @thirdweb-dev/sdk # Link the sdk package
# etc...
```
From the monorepo, run the following command to publish your local changes to the test project:
```bash
yarn push
```
Now, each time you make a change to the monorepo, you can run `yarn push` to publish your changes to the test project.
In your test project, you need to:
1. Delete the dependencies cache. If you're using Next.js, that is the `.next` directory, and if you're using CRA, that is the `node_modules/.cache` directory.
2. Restart the development server.
<br/>
### Publish Your Changes
Once you're satisfied with your changes, you are ready to submit them for review!
1. Use [changeset](https://github.com/changesets/changesets) to generate a changeset file:
```
yarn changeset
```
We follow [semantic versioning](https://semver.org/) for generating versioned releases of our packages (i.e. version = `MAJOR.MINOR.PATCH`)
- Update `major` for breaking changes
- Update `minor` for new features,
- Update `patch` for non-breaking bug fixes, etc)
2. Commit the changeset along with your changes:
```
git commit -am "My commit message"
```
3. Push your changes to the SDK:
```
git push origin MY_BRANCH_NAME
```
4. Create a [pull request](https://www.atlassian.com/git/tutorials/making-a-pull-request) to the `main` branch of the official (not your fork) SDK repo.
It's helpful to tag PRs with `[SDK]`, `[REACT]`, `[AUTH]`, (the name of the package you're modifying) to indicate the package that you are engaging with.
+17
View File
@@ -0,0 +1,17 @@
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 60
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 7
# Issues with these labels will never be considered stale
exemptLabels:
- pinned
- security
# Label to use when marking an issue as stale
staleLabel: wontfix
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: false
-36
View File
@@ -1,36 +0,0 @@
name: CI
on:
push:
branches: ["main"]
pull_request:
types: [opened, synchronize]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build:
name: Build and Test
# timeout-minutes: 15
runs-on: ubuntu-latest
# To use Remote Caching, uncomment the next lines and follow the steps below.
env:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
steps:
- name: Check out code
uses: actions/checkout@v3
with:
fetch-depth: 2
- name: Install
uses: ./.github/composite-actions/install
- name: Build
run: yarn build
- name: Test
run: yarn test
+121
View File
@@ -0,0 +1,121 @@
name: Build, Lint & Test
on:
push:
branches: ["main"]
pull_request:
types: [opened, synchronize]
# trigger on merge group as well (merge queue)
merge_group:
types: [checks_requested]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
# 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
steps:
- name: Check out code
uses: actions/checkout@v3
with:
fetch-depth: 25
- name: Install
uses: ./.github/composite-actions/install
- run: yarn build
# We use week in the turbo cache key to keep the cache from infinitely growing
- id: get-week
run: echo "WEEK=$(date +%U)" >> $GITHUB_OUTPUT
- uses: actions/cache@v3
timeout-minutes: 5
id: cache-build
with:
path: ./*
key: ${{ github.sha }}-${{ github.run_number }}
lint:
timeout-minutes: 15
name: Lint Packages
runs-on: ubuntu-latest
needs: build
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 }}
- run: yarn lint
test:
timeout-minutes: 15
name: Unit Tests
runs-on: ubuntu-latest-16
needs: build
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 }}
- 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
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 }}
- name: Install Playwright
run: npx playwright install --with-deps
- name: Run e2e tests
run: yarn e2e
env:
NODE_OPTIONS: "--max_old_space_size=4096"
+72
View File
@@ -0,0 +1,72 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
on:
push:
branches: [ "main" ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ "main" ]
schedule:
- cron: '37 9 * * 3'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'javascript' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
steps:
- name: Checkout repository
uses: actions/checkout@v3
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v2
# ℹ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
# If the Autobuild fails above, remove it and uncomment the following three lines.
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
# - run: |
# echo "Run, Build Application using script"
# ./location_of_script_within_repo/buildscript.sh
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
-35
View File
@@ -1,35 +0,0 @@
name: Integration tests
on:
push:
branches: ["main"]
pull_request:
types: [opened, synchronize]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
integration-tests:
timeout-minutes: 60
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install
uses: ./.github/composite-actions/install
- name: Install Playwright
run: npx playwright install --with-deps
- name: Run e2e tests
run: yarn e2e
env:
NODE_OPTIONS: "--max_old_space_size=4096"
- uses: actions/upload-artifact@v2
if: always()
with:
name: playwright-report
path: packages/react/playwright-report/
retention-days: 30
+10 -5
View File
@@ -8,6 +8,7 @@ on:
jobs:
deploy-check:
# this just checks if ur allowed to do the action so does not need to run on a fast machine
runs-on: ubuntu-latest
steps:
- name: acknowledge deployment request to commenter
@@ -22,7 +23,7 @@ jobs:
id: validate_user
if: ${{ steps.check.outputs.triggered == 'true' }}
run: |
if [[ "${AUTHOR_ASSOCIATION}" != 'MEMBER' && "${AUTHOR_ASSOCIATION}" != 'OWNER' ]]
if [[ "${AUTHOR_ASSOCIATION}" != 'MEMBER' && "${AUTHOR_ASSOCIATION}" != 'OWNER' && "${AUTHOR_ASSOCIATION}" != 'CONTRIBUTOR' ]]
then
echo "User authorization failed"
exit 1
@@ -39,7 +40,8 @@ jobs:
comment_body: ${{ github.event.comment.body }}
deploy:
runs-on: ubuntu-latest
runs-on: ubuntu-latest-16
timeout-minutes: 30
needs: deploy-check
if: needs.deploy-check.outputs.triggered == 'true'
steps:
@@ -59,12 +61,13 @@ jobs:
with:
persist-credentials: true
repository: ${{ fromJson(steps.get_pull_request_ref.outputs.data).head.repo.full_name }}
ref: ${{ fromJson(steps.get_pull_request_ref.outputs.data).head.ref }}
- name: Install
uses: ./.github/composite-actions/install
- name: Build
run: yarn build:release
run: yarn build
- name: Configure npm
run: |
@@ -73,8 +76,10 @@ jobs:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Deploy pre-release
id: changesets
run: |
yarn changeset version --snapshot pr${{ github.event.issue.number }}
yarn changeset publish --tag pr${{ github.event.issue.number }} --no-git-tag
yarn changeset version --snapshot dev
node ./scripts/pre-release.mjs
yarn changeset publish --tag dev --no-git-tag
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+2 -1
View File
@@ -14,7 +14,8 @@ concurrency:
jobs:
release:
name: Release
runs-on: ubuntu-latest
timeout-minutes: 30
runs-on: ubuntu-latest-16
steps:
- name: Checkout branch
uses: actions/checkout@v3
+6 -2
View File
@@ -10,6 +10,10 @@ dist-ssr
.cache
server/dist
public/dist
.turbo
./packages/contracts-js/abis
.idea/
.idea/
.yalc/
yalc.lock
build/
playwright-report/
.vscode/
+4 -2
View File
@@ -1,2 +1,4 @@
lib
node_modules
node_modules
dist
contracts-js
*.d.ts
+15 -15
View File
@@ -10,19 +10,19 @@ We pledge to act and interact in ways that contribute to an open, welcoming, div
Examples of behavior that contributes to a positive environment for our community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
* Focusing on what is best not just for us as individuals, but for the overall community
- Demonstrating empathy and kindness toward other people
- Being respectful of differing opinions, viewpoints, and experiences
- Giving and gracefully accepting constructive feedback
- Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
- Focusing on what is best not just for us as individuals, but for the overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a professional setting
- The use of sexualized language or imagery, and sexual attention or advances of any kind
- Trolling, insulting or derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or email address, without their explicit permission
- Other conduct which could reasonably be considered inappropriate in a professional setting
## Enforcement Responsibilities
@@ -64,7 +64,7 @@ Community leaders will follow these Community Impact Guidelines in determining t
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.
**Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within the community.
@@ -72,12 +72,12 @@ Community leaders will follow these Community Impact Guidelines in determining t
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0, available at [https://www.contributor-covenant.org/version/2/0/code_of_conduct.html][v2.0].
Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder][Mozilla CoC].
Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder][mozilla coc].
For answers to common questions about this code of conduct, see the FAQ at [https://www.contributor-covenant.org/faq][FAQ]. Translations are available at [https://www.contributor-covenant.org/translations][translations].
For answers to common questions about this code of conduct, see the FAQ at [https://www.contributor-covenant.org/faq][faq]. Translations are available at [https://www.contributor-covenant.org/translations][translations].
[homepage]: https://www.contributor-covenant.org
[v2.0]: https://www.contributor-covenant.org/version/2/0/code_of_conduct.html
[Mozilla CoC]: https://github.com/mozilla/diversity
[FAQ]: https://www.contributor-covenant.org/faq
[mozilla coc]: https://github.com/mozilla/diversity
[faq]: https://www.contributor-covenant.org/faq
[translations]: https://www.contributor-covenant.org/translations
+35 -28
View File
@@ -1,44 +1,51 @@
<p align="center">
<br />
<a href="https://thirdweb.com"><img src="https://github.com/thirdweb-dev/js/blob/main/packages/sdk/logo.svg?raw=true" width="200" alt=""/></a>
<br />
<br />
<a href="https://thirdweb.com">
<img src="https://github.com/thirdweb-dev/js/blob/main/packages/sdk/logo.svg?raw=true" width="200" alt=""/></a>
<br />
</p>
<h1 align="center">thirdweb 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>
<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://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 SDKs for Browser, Node and Mobile apps</strong></p>
<br />
## Packages
| Package | Description | Latest Version |
| ---------------------------------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [/sdk](./packages/sdk/README.md) | 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/README.md) | 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/README.md) | 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> |
| [/storage](./packages/storage/README.md) | Best in class decentralized storage SDK for Browser and Node | <a href="https://www.npmjs.com/package/@thirdweb-dev/storage"><img src="https://img.shields.io/npm/v/@thirdweb-dev/storage?color=red&label=npm&logo=npm" alt="npm version"/></a> |
| [/cli](./packages/cli/README.md) | Publish and deploy smart contracts without dealing with private keys | <a href="https://www.npmjs.com/package/thirdweb"><img src="https://img.shields.io/npm/v/thirdweb?color=red&label=npm&logo=npm" alt="npm version"/></a> |
| [/solana](./packages/solana/README.md) | Solana SDK for Browser, Node and React Native | <a href="https://www.npmjs.com/package/@thirdweb-dev/solana"><img src="https://img.shields.io/npm/v/@thirdweb-dev/solana?color=red&label=npm&logo=npm" alt="npm version"/></a> |
| 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> |
| [/storage](./packages/storage) | Best in class decentralized storage SDK for Browser and Node | <a href="https://www.npmjs.com/package/@thirdweb-dev/storage"><img src="https://img.shields.io/npm/v/@thirdweb-dev/storage?color=red&label=npm&logo=npm" alt="npm version"/></a> |
| [/cli](./packages/cli) | Publish and deploy smart contracts without dealing with private keys | <a href="https://www.npmjs.com/package/thirdweb"><img src="https://img.shields.io/npm/v/thirdweb?color=red&label=npm&logo=npm" alt="npm version"/></a> |
## How this monorepo functions
## Documentation
### Contributing
Visit [https://portal.thirdweb.com/](https://portal.thirdweb.com/) to view the full documentation.
1. Create PRs to the monorepo
2. Tag PRs with `[SDK]`, `[REACT]`, `[AUTH]`, etc to indicate the package that you are engaging with (TBD a better process for this / if it is necessary)
3. Create a `changeset` (with `yarn changeset`) for every **user impacting** change and describe what changed (try to focus on the end-user impact as much as possible -- use `major` for breaking changes, `minor` for new features, `patch` for non-breaking bug fixes, etc)
4. when the PR builds and tests pass merge to main
<br />
### Releases
## Contributing
#### Nightly
We welcome contributions from all developers, regardless of experience level. If you are interested in contributing, please read our [Contributing Guide](.github/contributing.md) where you'll learn how the repo works, how to test your changes, and how to submit a pull request.
- every push to main automatically gets published to the `@nightly` tag as a snapshot version (based on the commit hash)
- nightly versions are published to npm under the `@nightly` tag
<br />
#### Stable
## Community
- every push to main that contains a changeset automatically gets added to the [Version Packages](https://github.com/thirdweb-dev/js/tree/changeset-release/main) PR
- to release a stable version of the code that is on main (with the change sets as the release notes / changelog) merge the `Version Packages` PR to main, this will automatically create new `@latest` packages for all of the packages in the monorepo that have changesets
The best place to discuss your ideas, ask questions, and troubleshoot issues is our [Discord server](https://discord.gg/thirdweb).
<br/>
## Security
If you believe you have found a security vulnerability in any of our packages, we kindly ask you not to open a public issue; and to disclose this to us by emailing `[email protected]`.
+28 -22
View File
@@ -2,43 +2,49 @@
"name": "@thirdweb-dev/js",
"version": "1.0.0",
"main": "index.js",
"repository": "git@github.com:thirdweb-dev/js.git",
"repository": "https://github.com/thirdweb-dev/js",
"author": "thirdweb eng <[email protected]>",
"license": "MIT",
"private": true,
"workspaces": {
"packages": [
"packages/*"
"packages/*",
"test/**/*"
]
},
"devDependencies": {
"@changesets/changelog-github": "^0.4.6",
"@changesets/cli": "^2.24.3",
"@trivago/prettier-plugin-sort-imports": "^3.3.0",
"eslint": "^8.23.0",
"postinstall-postinstall": "^2.1.0",
"prettier": "^2.7.1",
"turbo": "latest"
},
"scripts": {
"test": "turbo run test",
"test": "turbo run test test:evm test:solana --filter=./packages/*",
"e2e": "turbo run e2e",
"build": "turbo run build",
"build:release": "turbo run build --force",
"build": "turbo run build --filter=./packages/*",
"build:release": "turbo run build --force --filter=./packages/*",
"dev": "turbo run dev --no-cache --parallel --continue",
"fix:repo": "manypkg fix",
"lint": "turbo run lint",
"fix": "turbo run fix",
"clean": "turbo run clean && rm -rf node_modules",
"format": "prettier --write \"**/*.{ts,tsx,md}\"",
"changeset": "changeset",
"version-packages": "changeset version",
"release": "changeset publish",
"release": "node ./scripts/pre-release.mjs && changeset publish",
"version-packages:nightly": "changeset version --snapshot nightly",
"release:nightly": "changeset publish --tag nightly"
"release:nightly": "node ./scripts/pre-release.mjs && changeset publish --tag nightly",
"push": "turbo run push --filter=./packages/*"
},
"preconstruct": {
"packages": [
"packages/*"
]
"packageManager": "[email protected]",
"dependencies": {
"@changesets/changelog-github": "^0.4.6",
"@changesets/cli": "^2.24.3",
"@manypkg/cli": "^0.19.1",
"@manypkg/get-packages": "^1.1.3",
"@trivago/prettier-plugin-sort-imports": "^4.0.0",
"eslint": "^8.21.0",
"mocha": "^10.2.0",
"postinstall-postinstall": "^2.1.0",
"prettier": "^2.7.1",
"turbo": "^1.8.3",
"yalc": "^1.0.0-pre.53"
},
"packageManager": "[email protected]"
}
"manypkg": {
"defaultBranch": "main"
}
}
+232
View File
@@ -1,5 +1,237 @@
# @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
- [#601](https://github.com/thirdweb-dev/js/pull/601) [`66cf1fb`](https://github.com/thirdweb-dev/js/commit/66cf1fb5c2e8deb486543ee028d786bb8eef6c19) Thanks [@jnsdls](https://github.com/jnsdls)! - upgrade dependencies
## 3.0.5
### Patch Changes
- [#588](https://github.com/thirdweb-dev/js/pull/588) [`f0de81d`](https://github.com/thirdweb-dev/js/commit/f0de81d4b1ba33b2ac73ed16cfdea8fd4eb5da9e) Thanks [@adam-maj](https://github.com/adam-maj)! - Add verify login to auth
## 3.0.4
### Patch Changes
- [#581](https://github.com/thirdweb-dev/js/pull/581) [`4d9e5c6`](https://github.com/thirdweb-dev/js/commit/4d9e5c6193b839fc7f67e7e73e0589dc8c4db90d) Thanks [@adam-maj](https://github.com/adam-maj)! - Remove wallet from next-auth config
- [#576](https://github.com/thirdweb-dev/js/pull/576) [`f6ea971`](https://github.com/thirdweb-dev/js/commit/f6ea97185470f91fc73a117827df51cf8e1c99d1) Thanks [@adam-maj](https://github.com/adam-maj)! - Add support for next-auth to auth and react
## 3.0.3
### Patch Changes
- [#533](https://github.com/thirdweb-dev/js/pull/533) [`dee4596`](https://github.com/thirdweb-dev/js/commit/dee45965496d5d0298944031dd13a4345f9e1683) Thanks [@adam-maj](https://github.com/adam-maj)! - Remove next major version pin on auth
## 3.0.2
## 3.0.1
### Patch Changes
- [#520](https://github.com/thirdweb-dev/js/pull/520) [`8c81ca5`](https://github.com/thirdweb-dev/js/commit/8c81ca5c3033b04b1f64e3a1134a72e7e3ec03b1) Thanks [@adam-maj](https://github.com/adam-maj)! - Update auth and react-core dependencies
## 3.0.0
### Major Changes
- [#460](https://github.com/thirdweb-dev/js/pull/460) [`a6c074c`](https://github.com/thirdweb-dev/js/commit/a6c074c3f33148cd17f5a66a58df9272a4381bab) Thanks [@adam-maj](https://github.com/adam-maj)! - Complete Auth redesign and update to add a number of major and quality of life improvements, including the following:
- Ability to use Auth APIs with both cookies and JWTs, allowing non browser clients to interact with Auth (mobile, gaming, scripts, etc.)
- Ability to store session data and other data on the Auth user
- Callbacks to run side-effects on login, logout, and requesting user data
- Ability to configure cookies for custom domains and backend setups
- Support for validation of the entire EIP4361/CAIP122 specification
- No more need for redirects or payload encoding on Auth requests
- and more...
See the new documentation to view the new changes and usage: [Auth Documentation](https://portal.thirdweb.com/auth).
## How to upgrade
The `ThirdwebAuth` constructor now takes the `domain` in the constructor, and takes a more generic `wallet` interface as input. The `wallet` can be imported from the `@thirdweb-dev/wallets` package, or for more simpler use cases, from the `@thirdweb-dev/auth/evm` and `@thirdweb-dev/auth/solana` entrypoints.
```js
import { PrivateKeyWallet } from "@thirdweb-dev/auth/evm";
// Pass in domain and wallet to the constructor
const wallet = new PrivateKeyWallet("0x...");
const auth = new ThirdwebAuth(wallet, "example.com");
// Auth functions no longer require domain to be passed in
const payload = await auth.login();
```
## 2.0.41
## 2.0.40
## 2.0.39
## 2.0.38
## 2.0.37
## 2.0.36
## 2.0.35
## 2.0.34
### Patch Changes
- [#425](https://github.com/thirdweb-dev/js/pull/425) [`f545a67`](https://github.com/thirdweb-dev/js/commit/f545a67e9fb597d27bb39ca515d24d306fbb121a) Thanks [@adam-maj](https://github.com/adam-maj)! - Add sameSite none and include credentials
## 2.0.33
## 2.0.32
## 2.0.31
### Patch Changes
- [#397](https://github.com/thirdweb-dev/js/pull/397) [`72589ec`](https://github.com/thirdweb-dev/js/commit/72589ec234d86939b67b0ca8b3b789f2e9c54cc2) Thanks [@adam-maj](https://github.com/adam-maj)! - Call user callback in getUser
## 2.0.30
## 2.0.29
## 2.0.28
## 2.0.27
## 2.0.26
## 2.0.25
## 2.0.24
## 2.0.23
## 2.0.22
## 2.0.21
### Patch Changes
- [#327](https://github.com/thirdweb-dev/js/pull/327) [`ef27aad`](https://github.com/thirdweb-dev/js/commit/ef27aad0aafc4577e85f44dc77dfbe880bd239b5) Thanks [@jnsdls](https://github.com/jnsdls)! - enable e2e testing
## 2.0.20
## 2.0.19
## 2.0.18
## 2.0.17
## 2.0.16
## 2.0.15
## 2.0.14
### Patch Changes
- [#274](https://github.com/thirdweb-dev/js/pull/274) [`ad06c5b`](https://github.com/thirdweb-dev/js/commit/ad06c5b28902422f9b416d65255c64c937a5e046) Thanks [@adam-maj](https://github.com/adam-maj)! - Add solana auth support and plugins for react and auth package
## 2.0.13
## 2.0.12
## 2.0.11
## 2.0.10
## 2.0.9
## 2.0.8
### Patch Changes
- Updated dependencies [[`ce05bfd`](https://github.com/thirdweb-dev/js/commit/ce05bfd8615a9c79664856bce53de8b43bed5c87)]:
- @thirdweb-dev/[email protected]
## 2.0.7
### Patch Changes
- Updated dependencies [[`5f5ab01`](https://github.com/thirdweb-dev/js/commit/5f5ab015e1dd3c471d6affe995ef36ec88932b3c)]:
- @thirdweb-dev/[email protected]
## 2.0.6
### Patch Changes
- Updated dependencies [[`a80fc97`](https://github.com/thirdweb-dev/js/commit/a80fc97b6a1e72ed46a400b4b602e180947fb870)]:
- @thirdweb-dev/[email protected]
## 2.0.5
### Patch Changes
- Updated dependencies [[`4169b94`](https://github.com/thirdweb-dev/js/commit/4169b9428f9001b7cad259a4e56fe610316cd191), [`3b877ba`](https://github.com/thirdweb-dev/js/commit/3b877ba221acfd85f80b99e1bc382055217f0a39), [`b54f95d`](https://github.com/thirdweb-dev/js/commit/b54f95dc906928ff2f9251748f254a16fe1f2cee), [`f8ab477`](https://github.com/thirdweb-dev/js/commit/f8ab4779bb2d6d66200e1e8fd558e0ac069a2f54), [`772f843`](https://github.com/thirdweb-dev/js/commit/772f8431e3a62d0ded62dae90a43e9a7edd5b1a2), [`a9ec190`](https://github.com/thirdweb-dev/js/commit/a9ec190ff99d2714cef2500d20ea0f3f73f07be3), [`208b038`](https://github.com/thirdweb-dev/js/commit/208b0389a50ea48bbb9600fec60fec2f1671d4b9), [`5345479`](https://github.com/thirdweb-dev/js/commit/534547992243bdd3a77e34ec2b2487b5adab366a)]:
- @thirdweb-dev/[email protected]
## 2.0.4
### Patch Changes
- Updated dependencies []:
- @thirdweb-dev/[email protected]
## 2.0.3
### Patch Changes
- Updated dependencies [[`51dde28`](https://github.com/thirdweb-dev/js/commit/51dde28224209f1b8b26f436c204a5e702281564), [`9d74a43`](https://github.com/thirdweb-dev/js/commit/9d74a43aac21448beba63ba4e2637945965a3634), [`b234c58`](https://github.com/thirdweb-dev/js/commit/b234c58d44d8322e44b2d2ba87ad4ec7d699e961)]:
- @thirdweb-dev/[email protected]
## 2.0.2
### Patch Changes
- Updated dependencies [[`42c79e9`](https://github.com/thirdweb-dev/js/commit/42c79e93dc958ca46a55d705aeea44ffdbbcc5f6), [`fe8751e`](https://github.com/thirdweb-dev/js/commit/fe8751eeae7ad013b890a8092ddbd091ecbd6708)]:
- @thirdweb-dev/[email protected]
## 2.0.1
### Patch Changes
- Updated dependencies [[`98dd64a`](https://github.com/thirdweb-dev/js/commit/98dd64a375c302a879aab3c628ecfb84b4dd19da)]:
- @thirdweb-dev/[email protected]
## 2.0.0
### Patch Changes
- Updated dependencies [[`a70b590`](https://github.com/thirdweb-dev/js/commit/a70b590be1efa7c0ad93a724afb24870439558ed), [`a37bc00`](https://github.com/thirdweb-dev/js/commit/a37bc00991bf1a359f5f8aa8e24e2c388dcd99d8), [`b442c97`](https://github.com/thirdweb-dev/js/commit/b442c970808f6cb7457d29542bd826dba711579c), [`0fa6f3f`](https://github.com/thirdweb-dev/js/commit/0fa6f3fcfbd571579baf9d2a0dbeee556ddbd5fe), [`2adb8ff`](https://github.com/thirdweb-dev/js/commit/2adb8ff6673768a91fa411c2d069245190ad9397), [`5a5bc36`](https://github.com/thirdweb-dev/js/commit/5a5bc361507bd8707dc12e9000bb9a218221cf61), [`820a519`](https://github.com/thirdweb-dev/js/commit/820a5191b5e7af5aba5e4d1cc90cd895c0dade11), [`0fa6f3f`](https://github.com/thirdweb-dev/js/commit/0fa6f3fcfbd571579baf9d2a0dbeee556ddbd5fe), [`82627ea`](https://github.com/thirdweb-dev/js/commit/82627ea0311f612119d0596ed0f568267a7af16b)]:
- @thirdweb-dev/[email protected]
## 1.0.8
### Patch Changes
- Updated dependencies [[`baa87a1`](https://github.com/thirdweb-dev/js/commit/baa87a1fbd7eee24ce9a95e16028de8435f85e69), [`4079326`](https://github.com/thirdweb-dev/js/commit/407932680fb024f17f12f578aa22c7f8c0c13339), [`05353fd`](https://github.com/thirdweb-dev/js/commit/05353fd8da82f77fb642bb38a533fb99801aed30)]:
- @thirdweb-dev/[email protected]
## 1.0.7
### Patch Changes
- [#61](https://github.com/thirdweb-dev/js/pull/61) [`3287c2b`](https://github.com/thirdweb-dev/js/commit/3287c2b0f233332fe4a095f973deed8efab91db6) Thanks [@jnsdls](https://github.com/jnsdls)! - fix versions in dependencies before releasing stable
- Updated dependencies [[`3287c2b`](https://github.com/thirdweb-dev/js/commit/3287c2b0f233332fe4a095f973deed8efab91db6)]:
- @thirdweb-dev/[email protected]
## 1.0.6
### Patch Changes
+9 -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>
@@ -16,8 +18,13 @@
Install the latest version of the SDK with either `npm` or `yarn`:
```shell
npm install @thirdweb-dev/auth @thirdweb-dev/sdk ethers
npm install @thirdweb-dev/auth
```
```shell
yarn add @thirdweb-dev/auth @thirdweb-dev/sdk ethers
yarn add @thirdweb-dev/auth
```
## Documentation
- [Auth Docs](https://portal.thirdweb.com/auth)
+4
View File
@@ -0,0 +1,4 @@
{
"main": "dist/thirdweb-dev-auth-evm.cjs.js",
"module": "dist/thirdweb-dev-auth-evm.esm.js"
}
+79 -32
View File
@@ -1,79 +1,125 @@
{
"name": "@thirdweb-dev/auth",
"version": "1.0.6",
"version": "3.0.7",
"main": "dist/thirdweb-dev-auth.cjs.js",
"module": "dist/thirdweb-dev-auth.esm.js",
"exports": {
"./package.json": "./package.json",
".": {
"module": "./dist/thirdweb-dev-auth.esm.js",
"default": "./dist/thirdweb-dev-auth.cjs.js"
},
"./evm": {
"module": "./evm/dist/thirdweb-dev-auth-evm.esm.js",
"default": "./evm/dist/thirdweb-dev-auth-evm.cjs.js"
},
"./next": {
"module": "./next/dist/thirdweb-dev-auth-next.esm.js",
"default": "./next/dist/thirdweb-dev-auth-next.cjs.js"
},
"./solana": {
"module": "./solana/dist/thirdweb-dev-auth-solana.esm.js",
"default": "./solana/dist/thirdweb-dev-auth-solana.cjs.js"
},
"./express": {
"module": "./express/dist/thirdweb-dev-auth-express.esm.js",
"default": "./express/dist/thirdweb-dev-auth-express.cjs.js"
},
"./next": {
"module": "./next/dist/thirdweb-dev-auth-next.esm.js",
"default": "./next/dist/thirdweb-dev-auth-express.cjs.js"
},
"./next-auth": {
"module": "./next-auth/dist/thirdweb-dev-auth-next-auth.esm.js",
"default": "./next-auth/dist/thirdweb-dev-auth-next-auth.cjs.js"
}
},
"repository": {
"directory": "packages/auth",
"type": "git",
"url": "https://github.com/thirdweb-dev/js.git"
},
"./package.json": "./package.json"
},
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/auth",
"author": "thirdweb eng <[email protected]>",
"license": "Apache-2.0",
"files": [
"dist/**/*",
"next/**/*",
"express/**/*",
"next-auth/**/*"
],
"scripts": {
"build": "preconstruct build",
"lint": "eslint"
"format": "prettier --write 'src/**/*'",
"lint": "eslint src/",
"fix": "eslint src/ --fix",
"clean": "rm -rf dist/ && rm -rf node_modules/",
"test": "mocha --config './test/.mocharc.json' --timeout 30000 --parallel './test/**/*.test.ts'"
},
"preconstruct": {
"entrypoints": [
"next/index.ts",
"index.ts",
"express/index.ts",
"next-auth/index.ts"
]
"next/index.ts",
"next-auth/index.ts",
"evm/index.ts",
"solana/index.ts"
],
"exports": true
},
"devDependencies": {
"@babel/core": "^7.19.3",
"@babel/preset-env": "^7.18.10",
"@babel/preset-typescript": "^7.18.6",
"@microsoft/api-documenter": "^7.19.4",
"@microsoft/api-extractor": "^7.29.2",
"@microsoft/tsdoc": "^0.14.1",
"@preconstruct/cli": "^2.2.1",
"@thirdweb-dev/sdk": "*",
"@solana/web3.js": "^1.73.0",
"@swc-node/register": "^1.5.4",
"@swc/core": "^1.3.23",
"@thirdweb-dev/wallets": "*",
"@types/bs58": "^4.0.1",
"@types/chai": "^4.3.4",
"@types/cookie": "^0.5.1",
"@types/cookie-parser": "^1.4.3",
"@types/express": "^4.17.13",
"@types/mocha": "^10.0.1",
"@typescript-eslint/eslint-plugin": "^5.33.0",
"@typescript-eslint/parser": "^5.33.0",
"@wagmi/core": "^0.8.18",
"chai": "^4.3.7",
"eslint": "^8.21.0",
"eslint-config-prettier": "^8.5.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-inclusive-language": "^2.2.0",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-tsdoc": "^0.2.16",
"ethers": ">=5.5.1",
"ethers": "^5.7.2",
"express": "^4.18.1",
"next": "12.2.0",
"mocha": "^10.2.0",
"next": "^12.2.0",
"next-auth": "^4.10.3",
"prettier": "^2.7.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"typescript": "^4.7.4"
},
"peerDependencies": {
"@thirdweb-dev/sdk": "*",
"ethers": ">=5.5.1",
"express": "^4.18.1",
"next": "12.2.0",
"next-auth": "^4.10.3"
"@noble/ed25519": "^1.7.1",
"@solana/web3.js": "^1.73.0",
"bs58": "^5.0.0",
"cookie-parser": "^1.4.6",
"ethers": "^5",
"express": "^4",
"next": "^12 || ^13",
"next-auth": "^4",
"tweetnacl": "^1.0.3"
},
"peerDependenciesMeta": {
"@noble/ed25519": {
"optional": true
},
"@solana/web3.js": {
"optional": true
},
"bs58": {
"optional": true
},
"cookie-parser": {
"optional": true
},
"tweetnacl": {
"optional": true
},
"ethers": {
"optional": true
},
"express": {
"optional": true
},
@@ -86,6 +132,7 @@
},
"dependencies": {
"cookie": "^0.5.0",
"cookie-parser": "^1.4.6"
"uuid": "^9.0.0",
"zod": "^3.20.2"
}
}
+4
View File
@@ -0,0 +1,4 @@
{
"main": "dist/thirdweb-dev-auth-solana.cjs.js",
"module": "dist/thirdweb-dev-auth-solana.esm.js"
}
+412
View File
@@ -0,0 +1,412 @@
import {
LoginOptions,
LoginPayload,
GenerateOptions,
LoginPayloadData,
LoginPayloadDataSchema,
AuthenticationPayloadDataSchema,
AuthenticationPayloadData,
LoginOptionsSchema,
VerifyOptionsSchema,
VerifyOptions,
GenerateOptionsSchema,
AuthenticateOptionsSchema,
AuthenticateOptions,
User,
Json,
} from "./schema";
import { isBrowser } from "./utils";
import type { GenericAuthWallet } from "@thirdweb-dev/wallets";
export class ThirdwebAuth {
private domain: string;
private wallet: GenericAuthWallet;
constructor(wallet: GenericAuthWallet, domain: string) {
this.wallet = wallet;
this.domain = domain;
}
public updateWallet(wallet: GenericAuthWallet) {
this.wallet = wallet;
}
public async login(options?: LoginOptions): Promise<LoginPayload> {
const parsedOptions = LoginOptionsSchema.parse(options);
let chainId: string | undefined = parsedOptions?.chainId;
if (!chainId && this.wallet.getChainId) {
try {
chainId = (await this.wallet.getChainId()).toString();
} catch {
// ignore error
}
}
const payloadData = LoginPayloadDataSchema.parse({
type: this.wallet.type,
domain: parsedOptions?.domain || this.domain,
address: await this.wallet.getAddress(),
statement: parsedOptions?.statement,
version: parsedOptions?.version,
uri:
parsedOptions?.uri ||
(isBrowser() ? window.location.origin : undefined),
chain_id: chainId,
nonce: parsedOptions?.nonce,
expiration_time:
parsedOptions?.expirationTime || new Date(Date.now() + 1000 * 60 * 5),
invalid_before: parsedOptions?.invalidBefore,
resources: parsedOptions?.resources,
});
const message = this.generateMessage(payloadData);
const signature = await this.wallet.signMessage(message);
return {
payload: payloadData,
signature,
};
}
public async verify(
payload: LoginPayload,
options?: VerifyOptions,
): Promise<string> {
const parsedOptions = VerifyOptionsSchema.parse(options);
if (payload.payload.type !== this.wallet.type) {
throw new Error(
`Expected chain type '${this.wallet.type}' does not match chain type on payload '${payload.payload.type}'`,
);
}
// Check that the intended domain matches the domain of the payload
const domain = parsedOptions?.domain || this.domain;
if (payload.payload.domain !== domain) {
throw new Error(
`Expected domain '${domain}' does not match domain on payload '${payload.payload.domain}'`,
);
}
// Check that the payload statement matches the expected statement
if (parsedOptions?.statement) {
if (payload.payload.statement !== parsedOptions.statement) {
throw new Error(
`Expected statement '${parsedOptions.statement}' does not match statement on payload '${payload.payload.statement}'`,
);
}
}
// Check that the intended URI matches the URI of the payload
if (parsedOptions?.uri) {
if (payload.payload.uri !== parsedOptions.uri) {
throw new Error(
`Expected URI '${parsedOptions.uri}' does not match URI on payload '${payload.payload.uri}'`,
);
}
}
// Check that the intended version matches the version of the payload
if (parsedOptions?.version) {
if (payload.payload.version !== parsedOptions.version) {
throw new Error(
`Expected version '${parsedOptions.version}' does not match version on payload '${payload.payload.version}'`,
);
}
}
// Check that the intended chain ID matches the chain ID of the payload
if (parsedOptions?.chainId) {
if (payload.payload.chain_id !== parsedOptions.chainId) {
throw new Error(
`Expected chain ID '${parsedOptions.chainId}' does not match chain ID on payload '${payload.payload.chain_id}'`,
);
}
}
// Check that the payload nonce is valid
if (parsedOptions?.validateNonce !== undefined) {
try {
await parsedOptions.validateNonce(payload.payload.nonce);
} catch (err) {
throw new Error(`Login request nonce is invalid`);
}
}
// Check that it isn't before the invalid before time
const currentTime = new Date();
if (currentTime < new Date(payload.payload.invalid_before)) {
throw new Error(`Login request is not yet valid`);
}
// Check that the payload hasn't expired
if (currentTime > new Date(payload.payload.expiration_time)) {
throw new Error(`Login request has expired`);
}
// Check that the specified resources are present on the payload
if (parsedOptions?.resources) {
const missingResources = parsedOptions.resources.filter(
(resource) => !payload.payload.resources?.includes(resource),
);
if (missingResources.length > 0) {
throw new Error(
`Login request is missing required resources: ${missingResources.join(
", ",
)}`,
);
}
}
// Check that the signing address is the claimed wallet address
const message = this.generateMessage(payload.payload);
const chainId =
this.wallet.type === "evm" && payload.payload.chain_id
? parseInt(payload.payload.chain_id)
: undefined;
const verified = await this.verifySignature(
message,
payload.signature,
payload.payload.address,
chainId,
);
if (!verified) {
throw new Error(
`Signer address does not match payload address '${payload.payload.address.toLowerCase()}'`,
);
}
return payload.payload.address;
}
public async generate(
payload: LoginPayload,
options?: GenerateOptions,
): Promise<string> {
if (isBrowser()) {
throw new Error(
"Authentication tokens should not be generated in the browser, as they must be signed by a server-side admin wallet.",
);
}
const parsedOptions = GenerateOptionsSchema.parse(options);
const domain = parsedOptions?.domain || this.domain;
const userAddress = await this.verify(payload, {
domain,
...parsedOptions?.verifyOptions,
});
let session: Json | undefined = undefined;
if (typeof parsedOptions?.session === "function") {
const sessionTrigger = (await parsedOptions.session(userAddress)) as Json;
if (sessionTrigger) {
session = sessionTrigger;
}
} else {
session = parsedOptions?.session;
}
const adminAddress = await this.wallet.getAddress();
const payloadData = AuthenticationPayloadDataSchema.parse({
iss: adminAddress,
sub: userAddress,
aud: domain,
nbf: parsedOptions?.invalidBefore || new Date(),
exp:
parsedOptions?.expirationTime ||
new Date(Date.now() + 1000 * 60 * 60 * 5),
iat: new Date(),
jti: parsedOptions?.tokenId,
ctx: session,
});
const message = JSON.stringify(payloadData);
const signature = await this.wallet.signMessage(message);
// Header used for JWT token specifying hash algorithm
const header = {
// Specify ECDSA with SHA-256 for hashing algorithm
alg: "ES256",
typ: "JWT",
};
const encodedHeader = Buffer.from(JSON.stringify(header)).toString(
"base64",
);
const encodedData = Buffer.from(JSON.stringify(payloadData))
.toString("base64")
.replace(/=/g, "");
const encodedSignature = Buffer.from(signature).toString("base64");
// Generate a JWT token with base64 encoded header, payload, and signature
const token = `${encodedHeader}.${encodedData}.${encodedSignature}`;
return token;
}
/**
* Authenticate With Token
* @remarks Server-side function that authenticates the provided JWT token. This function verifies that
* the provided authentication token is valid and returns the address of the authenticated wallet.
*
* @param domain - The domain of the server-side application doing authentication
* @param token - The authentication token being used
* @returns The address of the authenticated wallet
*
* @example
* ```javascript
* const domain = "example.com";
* const loginPayload = await sdk.auth.login(domain);
* const token = await sdk.auth.generateAuthToken(domain, loginPayload);
*
* // Authenticate the token and get the address of authenticating users wallet
* const address = sdk.auth.authenticate(domain, token);
* ```
*/
public async authenticate<TSession extends Json = Json>(
token: string,
options?: AuthenticateOptions,
): Promise<User<TSession>> {
if (isBrowser()) {
throw new Error(
"Should not authenticate tokens in the browser, as they must be verified by the server-side admin wallet.",
);
}
const parsedOptions = AuthenticateOptionsSchema.parse(options);
const domain = parsedOptions?.domain || this.domain;
const encodedPayload = token.split(".")[1];
const encodedSignature = token.split(".")[2];
const payload: AuthenticationPayloadData = JSON.parse(
Buffer.from(encodedPayload, "base64").toString(),
);
const signature = Buffer.from(encodedSignature, "base64").toString();
// Check that the payload unique ID is valid
if (parsedOptions?.validateTokenId !== undefined) {
try {
await parsedOptions.validateTokenId(payload.jti);
} catch (err) {
throw new Error(`Token ID is invalid`);
}
}
// Check that the token audience matches the domain
if (payload.aud !== domain) {
throw new Error(
`Expected token to be for the domain '${domain}', but found token with domain '${payload.aud}'`,
);
}
// Check that the token is past the invalid before time
const currentTime = Math.floor(new Date().getTime() / 1000);
if (currentTime < payload.nbf) {
throw new Error(
`This token is invalid before epoch time '${payload.nbf}', current epoch time is '${currentTime}'`,
);
}
// Check that the token hasn't expired
if (currentTime > payload.exp) {
throw new Error(
`This token expired at epoch time '${payload.exp}', current epoch time is '${currentTime}'`,
);
}
// Check that the connected wallet matches the token issuer
const connectedAddress = await this.wallet.getAddress();
if (connectedAddress.toLowerCase() !== payload.iss.toLowerCase()) {
throw new Error(
`Expected the connected wallet address '${connectedAddress}' to match the token issuer address '${payload.iss}'`,
);
}
let chainId: number | undefined = undefined;
if (this.wallet.getChainId) {
try {
chainId = await this.wallet.getChainId();
} catch {
// ignore error
}
}
const verified = await this.verifySignature(
JSON.stringify(payload),
signature,
connectedAddress,
chainId,
);
if (!verified) {
throw new Error(
`The connected wallet address '${connectedAddress}' did not sign the token`,
);
}
return {
address: payload.sub,
session: payload.ctx as TSession | undefined,
};
}
private async verifySignature(
message: string,
signature: string,
address: string,
chainId?: number,
) {
return this.wallet.verifySignature(message, signature, address, chainId);
}
/**
* Generates a EIP-4361 & CAIP-122 compliant message to sign based on the login payload
*/
private generateMessage(payload: LoginPayloadData): string {
const typeField = payload.type === "evm" ? "Ethereum" : "Solana";
const header = `${payload.domain} wants you to sign in with your ${typeField} account:`;
let prefix = [header, payload.address].join("\n");
prefix = [prefix, payload.statement].join("\n\n");
if (payload.statement) {
prefix += "\n";
}
const suffixArray = [];
if (payload.uri) {
const uriField = `URI: ${payload.uri}`;
suffixArray.push(uriField);
}
const versionField = `Version: ${payload.version}`;
suffixArray.push(versionField);
if (payload.chain_id) {
const chainField = `Chain ID: ` + payload.chain_id || "1";
suffixArray.push(chainField);
}
const nonceField = `Nonce: ${payload.nonce}`;
suffixArray.push(nonceField);
const issuedAtField = `Issued At: ${payload.issued_at}`;
suffixArray.push(issuedAtField);
const expiryField = `Expiration Time: ${payload.expiration_time}`;
suffixArray.push(expiryField);
if (payload.invalid_before) {
const invalidBeforeField = `Not Before: ${payload.invalid_before}`;
suffixArray.push(invalidBeforeField);
}
if (payload.resources) {
suffixArray.push(
[`Resources:`, ...payload.resources.map((x) => `- ${x}`)].join("\n"),
);
}
const suffix = suffixArray.join("\n");
return [prefix, suffix].join("\n");
}
}
+2
View File
@@ -0,0 +1,2 @@
export { ThirdwebAuth } from "./auth";
export * from "./schema";
+208
View File
@@ -0,0 +1,208 @@
import { utils, BigNumber } from "ethers";
import { v4 as uuidv4 } from "uuid";
import { z } from "zod";
export const AddressSchema = z.string().refine(
(arg) => utils.isAddress(arg),
(out) => {
return {
message: `${out} is not a valid address`,
};
},
);
export const RawDateSchema = z.date().transform((i) => {
return BigNumber.from(Math.floor(i.getTime() / 1000));
});
export const AccountTypeSchema = z.union([
z.literal("evm"),
z.literal("solana"),
]);
const literalSchema = z.union([z.string(), z.number(), z.boolean(), z.null()]);
type Literal = z.infer<typeof literalSchema>;
export type Json = Literal | { [key: string]: Json } | Json[];
const JsonSchema: z.ZodType<Json> = z.lazy(
() => z.union([literalSchema, z.array(JsonSchema), z.record(JsonSchema)]),
{ invalid_type_error: "Provided value was not valid JSON" },
);
/**
* @internal
*/
export const LoginOptionsSchema = z
.object({
domain: z.string().optional(),
statement: z.string().optional(),
uri: z.string().optional(),
version: z.string().optional(),
chainId: z.string().optional(),
nonce: z.string().optional(),
expirationTime: z.date().optional(),
invalidBefore: z.date().optional(),
resources: z.array(z.string()).optional(),
})
.optional();
/**
* @internal
*/
export const LoginPayloadDataSchema = z.object({
type: AccountTypeSchema,
domain: z.string(),
address: z.string(),
statement: z
.string()
.default(
"Please ensure that the domain above matches the URL of the current website.",
),
uri: z.string().optional(),
version: z.string().default("1"),
chain_id: z.string().optional(),
nonce: z.string().default(uuidv4()),
issued_at: z
.date()
.default(new Date())
.transform((d) => d.toISOString()),
expiration_time: z.date().transform((d) => d.toISOString()),
invalid_before: z
.date()
.default(new Date())
.transform((d) => d.toISOString()),
resources: z.array(z.string()).optional(),
});
/**
* @internal
*/
export const LoginPayloadSchema = z.object({
payload: LoginPayloadDataSchema,
signature: z.string(),
});
/**
* @internal
*/
const VerifyOptionsSchemaRequired = z.object({
domain: z.string().optional(),
statement: z.string().optional(),
uri: z.string().optional(),
version: z.string().optional(),
chainId: z.string().optional(),
validateNonce: z.function().args(z.string()).optional(),
resources: z.array(z.string()).optional(),
});
/**
* @internal
*/
export const VerifyOptionsSchema = VerifyOptionsSchemaRequired.optional();
/**
* @internal
*/
export const GenerateOptionsSchema = z
.object({
domain: z.string().optional(),
tokenId: z.string().optional(),
expirationTime: z.date().optional(),
invalidBefore: z.date().optional(),
session: z.union([JsonSchema, z.function().args(z.string())]).optional(),
verifyOptions: VerifyOptionsSchemaRequired.omit({
domain: true,
}).optional(),
})
.optional();
/**
* @internal
*/
export const AuthenticationPayloadDataSchema = z.object({
iss: z.string(),
sub: z.string(),
aud: z.string(),
exp: RawDateSchema.transform((b) => b.toNumber()),
nbf: RawDateSchema.transform((b) => b.toNumber()),
iat: RawDateSchema.transform((b) => b.toNumber()),
jti: z.string().default(uuidv4()),
ctx: JsonSchema.optional(),
});
/**
* @internal
*/
export const AuthenticationPayloadSchema = z.object({
payload: AuthenticationPayloadDataSchema,
signature: z.string(),
});
/**
* @internal
*/
export const AuthenticateOptionsSchema = z
.object({
domain: z.string().optional(),
validateTokenId: z.function().args(z.string()).optional(),
})
.optional();
/**
* @public
*/
export type LoginOptions = z.input<typeof LoginOptionsSchema>;
/**
* @public
*/
export type LoginPayloadData = z.output<typeof LoginPayloadDataSchema>;
/**
* @public
*/
export type LoginPayload = z.output<typeof LoginPayloadSchema>;
/**
* @public
*/
export type VerifyOptions = z.input<typeof VerifyOptionsSchema>;
/**
* @public
*/
export type GenerateOptions = z.input<typeof GenerateOptionsSchema>;
/**
* @public
*/
export type AuthenticationPayloadData = z.output<
typeof AuthenticationPayloadDataSchema
>;
/**
* @public
*/
export type AuthenticationPayload = z.output<
typeof AuthenticationPayloadSchema
>;
/**
* @public
*/
export type AuthenticateOptions = z.output<typeof AuthenticateOptionsSchema>;
/**
* @public
*/
export type User<TContext extends Json = Json> = {
address: string;
session?: TContext;
};
export const LoginPayloadOutputSchema = LoginPayloadSchema.extend({
payload: LoginPayloadDataSchema.extend({
issued_at: z.string(),
expiration_time: z.string(),
invalid_before: z.string(),
}),
});
@@ -1,7 +1,6 @@
/**
* @internal
*/
// @ts-expext-error window is not defined
export const isBrowser = () => typeof window !== "undefined";
/**
+28
View File
@@ -0,0 +1,28 @@
import { ThirdwebAuth } from "../core";
import { LoginPayload, VerifyOptions } from "../core/schema";
import { SignerWallet } from "./signer";
import { ethers } from "ethers";
const wallet = new SignerWallet(ethers.Wallet.createRandom());
const authMap = new Map<string, ThirdwebAuth>();
export async function verifyLogin(
domain: string,
payload: LoginPayload,
options?: Omit<VerifyOptions, "domain">,
) {
let auth: ThirdwebAuth;
if (!authMap.has(domain)) {
auth = new ThirdwebAuth(wallet, domain);
authMap.set(domain, auth);
} else {
auth = authMap.get(domain) as ThirdwebAuth;
}
try {
const address = await auth.verify(payload, options);
return { address, error: undefined };
} catch (err: any) {
return { address: undefined, error: err.message };
}
}
+579
View File
@@ -0,0 +1,579 @@
import type { Chain } from "@wagmi/core";
const arbitrum: Chain = {
id: 42_161,
name: "Arbitrum One",
network: "arbitrum",
nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
rpcUrls: {
alchemy: {
http: ["https://arb-mainnet.g.alchemy.com/v2"],
webSocket: ["wss://arb-mainnet.g.alchemy.com/v2"],
},
infura: {
http: ["https://arbitrum-mainnet.infura.io/v3"],
webSocket: ["wss://arbitrum-mainnet.infura.io/ws/v3"],
},
default: {
http: ["https://arb1.arbitrum.io/rpc"],
},
public: {
http: ["https://arb1.arbitrum.io/rpc"],
},
},
blockExplorers: {
etherscan: { name: "Arbiscan", url: "https://arbiscan.io" },
default: { name: "Arbiscan", url: "https://arbiscan.io" },
},
contracts: {
multicall3: {
address: "0xca11bde05977b3631167028862be2a173976ca11",
blockCreated: 7654707,
},
},
};
const arbitrumGoerli: Chain = {
id: 421_613,
name: "Arbitrum Goerli",
network: "arbitrum-goerli",
nativeCurrency: {
name: "Arbitrum Goerli Ether",
symbol: "ETH",
decimals: 18,
},
rpcUrls: {
alchemy: {
http: ["https://arb-goerli.g.alchemy.com/v2"],
webSocket: ["wss://arb-goerli.g.alchemy.com/v2"],
},
infura: {
http: ["https://arbitrum-goerli.infura.io/v3"],
webSocket: ["wss://arbitrum-goerli.infura.io/ws/v3"],
},
default: {
http: ["https://goerli-rollup.arbitrum.io/rpc"],
},
public: {
http: ["https://goerli-rollup.arbitrum.io/rpc"],
},
},
blockExplorers: {
etherscan: { name: "Arbiscan", url: "https://goerli.arbiscan.io/" },
default: { name: "Arbiscan", url: "https://goerli.arbiscan.io/" },
},
contracts: {
multicall3: {
address: "0xca11bde05977b3631167028862be2a173976ca11",
blockCreated: 88114,
},
},
testnet: true,
};
const avalanche: Chain = {
id: 43_114,
name: "Avalanche",
network: "avalanche",
nativeCurrency: {
decimals: 18,
name: "Avalanche",
symbol: "AVAX",
},
rpcUrls: {
default: { http: ["https://api.avax.network/ext/bc/C/rpc"] },
public: { http: ["https://api.avax.network/ext/bc/C/rpc"] },
},
blockExplorers: {
etherscan: { name: "SnowTrace", url: "https://snowtrace.io" },
default: { name: "SnowTrace", url: "https://snowtrace.io" },
},
contracts: {
multicall3: {
address: "0xca11bde05977b3631167028862be2a173976ca11",
blockCreated: 11907934,
},
},
};
const avalancheFuji: Chain = {
id: 43_113,
name: "Avalanche Fuji",
network: "avalanche-fuji",
nativeCurrency: {
decimals: 18,
name: "Avalanche Fuji",
symbol: "AVAX",
},
rpcUrls: {
default: { http: ["https://api.avax-test.network/ext/bc/C/rpc"] },
public: { http: ["https://api.avax-test.network/ext/bc/C/rpc"] },
},
blockExplorers: {
etherscan: { name: "SnowTrace", url: "https://testnet.snowtrace.io" },
default: { name: "SnowTrace", url: "https://testnet.snowtrace.io" },
},
contracts: {
multicall3: {
address: "0xca11bde05977b3631167028862be2a173976ca11",
blockCreated: 7096959,
},
},
testnet: true,
};
const bsc: Chain = {
id: 56,
name: "BNB Smart Chain",
network: "bsc",
nativeCurrency: {
decimals: 18,
name: "BNB",
symbol: "BNB",
},
rpcUrls: {
default: { http: ["https://rpc.ankr.com/bsc"] },
public: { http: ["https://rpc.ankr.com/bsc"] },
},
blockExplorers: {
etherscan: { name: "BscScan", url: "https://bscscan.com" },
default: { name: "BscScan", url: "https://bscscan.com" },
},
contracts: {
multicall3: {
address: "0xca11bde05977b3631167028862be2a173976ca11",
blockCreated: 15921452,
},
},
};
const bscTestnet: Chain = {
id: 97,
name: "Binance Smart Chain Testnet",
network: "bsc-testnet",
nativeCurrency: {
decimals: 18,
name: "BNB",
symbol: "tBNB",
},
rpcUrls: {
default: { http: ["https://bsc-testnet.public.blastapi.io"] },
public: { http: ["https://bsc-testnet.public.blastapi.io"] },
},
blockExplorers: {
etherscan: { name: "BscScan", url: "https://testnet.bscscan.com" },
default: { name: "BscScan", url: "https://testnet.bscscan.com" },
},
contracts: {
multicall3: {
address: "0xca11bde05977b3631167028862be2a173976ca11",
blockCreated: 17422483,
},
},
testnet: true,
};
const fantom: Chain = {
id: 250,
name: "Fantom",
network: "fantom",
nativeCurrency: {
decimals: 18,
name: "Fantom",
symbol: "FTM",
},
rpcUrls: {
default: { http: ["https://rpc.ankr.com/fantom"] },
public: { http: ["https://rpc.ankr.com/fantom"] },
},
blockExplorers: {
etherscan: { name: "FTMScan", url: "https://ftmscan.com" },
default: { name: "FTMScan", url: "https://ftmscan.com" },
},
contracts: {
multicall3: {
address: "0xca11bde05977b3631167028862be2a173976ca11",
blockCreated: 33001987,
},
},
};
const fantomTestnet: Chain = {
id: 4002,
name: "Fantom Testnet",
network: "fantom-testnet",
nativeCurrency: {
decimals: 18,
name: "Fantom",
symbol: "FTM",
},
rpcUrls: {
default: { http: ["https://rpc.testnet.fantom.network"] },
public: { http: ["https://rpc.testnet.fantom.network"] },
},
blockExplorers: {
etherscan: { name: "FTMScan", url: "https://testnet.ftmscan.com" },
default: { name: "FTMScan", url: "https://testnet.ftmscan.com" },
},
contracts: {
multicall3: {
address: "0xca11bde05977b3631167028862be2a173976ca11",
blockCreated: 8328688,
},
},
};
const goerli: Chain = {
id: 5,
network: "goerli",
name: "Goerli",
nativeCurrency: { name: "Goerli Ether", symbol: "ETH", decimals: 18 },
rpcUrls: {
alchemy: {
http: ["https://eth-goerli.g.alchemy.com/v2"],
webSocket: ["wss://eth-goerli.g.alchemy.com/v2"],
},
infura: {
http: ["https://goerli.infura.io/v3"],
webSocket: ["wss://goerli.infura.io/ws/v3"],
},
default: {
http: ["https://rpc.ankr.com/eth_goerli"],
},
public: {
http: ["https://rpc.ankr.com/eth_goerli"],
},
},
blockExplorers: {
etherscan: {
name: "Etherscan",
url: "https://goerli.etherscan.io",
},
default: {
name: "Etherscan",
url: "https://goerli.etherscan.io",
},
},
contracts: {
ensRegistry: {
address: "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e",
},
multicall3: {
address: "0xca11bde05977b3631167028862be2a173976ca11",
blockCreated: 6507670,
},
},
testnet: true,
};
const mainnet: Chain = {
id: 1,
network: "homestead",
name: "Ethereum",
nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
rpcUrls: {
alchemy: {
http: ["https://eth-mainnet.g.alchemy.com/v2"],
webSocket: ["wss://eth-mainnet.g.alchemy.com/v2"],
},
infura: {
http: ["https://mainnet.infura.io/v3"],
webSocket: ["wss://mainnet.infura.io/ws/v3"],
},
default: {
http: ["https://cloudflare-eth.com"],
},
public: {
http: ["https://cloudflare-eth.com"],
},
},
blockExplorers: {
etherscan: {
name: "Etherscan",
url: "https://etherscan.io",
},
default: {
name: "Etherscan",
url: "https://etherscan.io",
},
},
contracts: {
ensRegistry: {
address: "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e",
},
multicall3: {
address: "0xca11bde05977b3631167028862be2a173976ca11",
blockCreated: 14353601,
},
},
};
const optimism: Chain = {
id: 10,
name: "Optimism",
network: "optimism",
nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
rpcUrls: {
alchemy: {
http: ["https://opt-mainnet.g.alchemy.com/v2"],
webSocket: ["wss://opt-mainnet.g.alchemy.com/v2"],
},
infura: {
http: ["https://optimism-mainnet.infura.io/v3"],
webSocket: ["wss://optimism-mainnet.infura.io/ws/v3"],
},
default: {
http: ["https://mainnet.optimism.io"],
},
public: {
http: ["https://mainnet.optimism.io"],
},
},
blockExplorers: {
etherscan: {
name: "Etherscan",
url: "https://optimistic.etherscan.io",
},
default: {
name: "Etherscan",
url: "https://optimistic.etherscan.io",
},
},
contracts: {
multicall3: {
address: "0xca11bde05977b3631167028862be2a173976ca11",
blockCreated: 4286263,
},
},
};
const optimismGoerli: Chain = {
id: 420,
name: "Optimism Goerli",
network: "optimism-goerli",
nativeCurrency: { name: "Goerli Ether", symbol: "ETH", decimals: 18 },
rpcUrls: {
alchemy: {
http: ["https://opt-goerli.g.alchemy.com/v2"],
webSocket: ["wss://opt-goerli.g.alchemy.com/v2"],
},
infura: {
http: ["https://optimism-goerli.infura.io/v3"],
webSocket: ["wss://optimism-goerli.infura.io/ws/v3"],
},
default: {
http: ["https://goerli.optimism.io"],
},
public: {
http: ["https://goerli.optimism.io"],
},
},
blockExplorers: {
etherscan: {
name: "Etherscan",
url: "https://goerli-optimism.etherscan.io",
},
default: {
name: "Etherscan",
url: "https://goerli-optimism.etherscan.io",
},
},
contracts: {
multicall3: {
address: "0xca11bde05977b3631167028862be2a173976ca11",
blockCreated: 49461,
},
},
testnet: true,
};
const polygon: Chain = {
id: 137,
name: "Polygon",
network: "matic",
nativeCurrency: { name: "MATIC", symbol: "MATIC", decimals: 18 },
rpcUrls: {
alchemy: {
http: ["https://polygon-mainnet.g.alchemy.com/v2"],
webSocket: ["wss://polygon-mainnet.g.alchemy.com/v2"],
},
infura: {
http: ["https://polygon-mainnet.infura.io/v3"],
webSocket: ["wss://polygon-mainnet.infura.io/ws/v3"],
},
default: {
http: ["https://polygon-rpc.com"],
},
public: {
http: ["https://polygon-rpc.com"],
},
},
blockExplorers: {
etherscan: {
name: "PolygonScan",
url: "https://polygonscan.com",
},
default: {
name: "PolygonScan",
url: "https://polygonscan.com",
},
},
contracts: {
multicall3: {
address: "0xca11bde05977b3631167028862be2a173976ca11",
blockCreated: 25770160,
},
},
};
const polygonMumbai: Chain = {
id: 80_001,
name: "Polygon Mumbai",
network: "maticmum",
nativeCurrency: { name: "MATIC", symbol: "MATIC", decimals: 18 },
rpcUrls: {
alchemy: {
http: ["https://polygon-mumbai.g.alchemy.com/v2"],
webSocket: ["wss://polygon-mumbai.g.alchemy.com/v2"],
},
infura: {
http: ["https://polygon-mumbai.infura.io/v3"],
webSocket: ["wss://polygon-mumbai.infura.io/ws/v3"],
},
default: {
http: ["https://matic-mumbai.chainstacklabs.com"],
},
public: {
http: ["https://matic-mumbai.chainstacklabs.com"],
},
},
blockExplorers: {
etherscan: {
name: "PolygonScan",
url: "https://mumbai.polygonscan.com",
},
default: {
name: "PolygonScan",
url: "https://mumbai.polygonscan.com",
},
},
contracts: {
multicall3: {
address: "0xca11bde05977b3631167028862be2a173976ca11",
blockCreated: 25770160,
},
},
testnet: true,
};
/**
* @public
* @deprecated - use the chainId number directly instead
*/
export enum ChainId {
Mainnet = 1,
Goerli = 5,
Polygon = 137,
Mumbai = 80001,
Fantom = 250,
FantomTestnet = 4002,
Avalanche = 43114,
AvalancheFujiTestnet = 43113,
Optimism = 10,
OptimismGoerli = 420,
Arbitrum = 42161,
ArbitrumGoerli = 421613,
BinanceSmartChainMainnet = 56,
BinanceSmartChainTestnet = 97,
}
/**
* @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
| ChainId.Goerli
| ChainId.Mumbai
| ChainId.Polygon
| ChainId.Fantom
| ChainId.FantomTestnet
| ChainId.Avalanche
| ChainId.AvalancheFujiTestnet
| ChainId.Optimism
| ChainId.OptimismGoerli
| ChainId.Arbitrum
| ChainId.ArbitrumGoerli
| ChainId.BinanceSmartChainMainnet
| ChainId.BinanceSmartChainTestnet;
/**
* @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,
ChainId.Goerli,
ChainId.Polygon,
ChainId.Mumbai,
ChainId.Fantom,
ChainId.FantomTestnet,
ChainId.Avalanche,
ChainId.AvalancheFujiTestnet,
ChainId.Optimism,
ChainId.OptimismGoerli,
ChainId.Arbitrum,
ChainId.ArbitrumGoerli,
ChainId.BinanceSmartChainMainnet,
ChainId.BinanceSmartChainTestnet,
];
/**
* @public
*/
export const NATIVE_TOKEN_ADDRESS =
"0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee";
export const DEFAULT_API_KEY =
"c6634ad2d97b74baf15ff556016830c251050e6c36b9da508ce3ec80095d3dc1";
export function getRpcUrl(chainId: number) {
return `https://${chainId}.rpc.thirdweb.com/${DEFAULT_API_KEY}`;
}
function enhanceChain<TChain extends Chain>(chain: TChain) {
const twRPC = getRpcUrl(chain.id);
return {
...chain,
rpcUrls: {
...chain.rpcUrls,
default: {
...chain.rpcUrls.default,
http: [twRPC, ...chain.rpcUrls.default.http],
},
public: {
...chain.rpcUrls.public,
http: [twRPC, ...(chain.rpcUrls.public?.http || [])],
},
},
} as TChain;
}
export const supportedChains: Record<SUPPORTED_CHAIN_ID, Chain> = {
[ChainId.Mainnet]: enhanceChain(mainnet),
[ChainId.Goerli]: enhanceChain(goerli),
[ChainId.Polygon]: enhanceChain(polygon),
[ChainId.Mumbai]: enhanceChain(polygonMumbai),
[ChainId.Avalanche]: enhanceChain(avalanche),
[ChainId.AvalancheFujiTestnet]: enhanceChain(avalancheFuji),
[ChainId.Fantom]: enhanceChain(fantom),
[ChainId.FantomTestnet]: enhanceChain(fantomTestnet),
[ChainId.Arbitrum]: enhanceChain(arbitrum),
[ChainId.ArbitrumGoerli]: enhanceChain(arbitrumGoerli),
[ChainId.Optimism]: enhanceChain(optimism),
[ChainId.OptimismGoerli]: enhanceChain(optimismGoerli),
[ChainId.BinanceSmartChainMainnet]: enhanceChain(bsc),
[ChainId.BinanceSmartChainTestnet]: enhanceChain(bscTestnet),
};
export const thirdwebChains: Chain[] = Object.values(supportedChains);
+2
View File
@@ -0,0 +1,2 @@
export * from "./signer";
export * from "./auth";
+93
View File
@@ -0,0 +1,93 @@
import { SUPPORTED_CHAIN_ID, supportedChains } from "./evm";
import type { Ecosystem, GenericAuthWallet } from "@thirdweb-dev/wallets";
import { ethers } from "ethers";
const EIP1271_ABI = [
"function isValidSignature(bytes32 _message, bytes _signature) public view returns (bytes4)",
];
const EIP1271_MAGICVALUE = "0x1626ba7e";
export const checkContractWalletSignature = async (
message: string,
signature: string,
address: string,
chainId: number,
): Promise<boolean> => {
const rpcUrl =
supportedChains[chainId as SUPPORTED_CHAIN_ID]?.rpcUrls.default.http[0];
if (!rpcUrl) {
return false;
}
const provider = new ethers.providers.JsonRpcProvider(rpcUrl);
const walletContract = new ethers.Contract(address, EIP1271_ABI, provider);
const hashMessage = ethers.utils.hashMessage(message);
try {
const res = await walletContract.isValidSignature(hashMessage, signature);
return res === EIP1271_MAGICVALUE;
} catch {
return false;
}
};
export class SignerWallet implements GenericAuthWallet {
type: Ecosystem = "evm";
#signer: ethers.Signer;
constructor(signer: ethers.Signer) {
this.#signer = signer;
}
public async getAddress(): Promise<string> {
return this.#signer.getAddress();
}
public async getChainId(): Promise<number> {
return this.#signer.getChainId();
}
public async signMessage(message: string): Promise<string> {
return await this.#signer.signMessage(message);
}
public async verifySignature(
message: string,
signature: string,
address: string,
chainId?: number,
): Promise<boolean> {
const messageHash = ethers.utils.hashMessage(message);
const messageHashBytes = ethers.utils.arrayify(messageHash);
const recoveredAddress = ethers.utils.recoverAddress(
messageHashBytes,
signature,
);
if (recoveredAddress === address) {
return true;
}
// Check if the address is a smart contract wallet
if (chainId !== undefined) {
try {
const isValid = await checkContractWalletSignature(
message,
signature,
address,
chainId || 1,
);
return isValid;
} catch {
// no-op
}
}
return false;
}
}
export class PrivateKeyWallet extends SignerWallet {
constructor(privateKey: string) {
super(new ethers.Wallet(privateKey));
}
}
+60
View File
@@ -0,0 +1,60 @@
import { Json } from "../../core/schema";
import { ThirdwebAuthContext, ThirdwebAuthUser } from "../types";
import { Request } from "express";
function getToken(req: Request): string | undefined {
if (req.headers["authorization"]) {
const authorizationHeader = req.headers["authorization"].split(" ");
if (authorizationHeader?.length === 2) {
return authorizationHeader[1];
}
return undefined;
}
const cookie: string | undefined = !req.cookies
? undefined
: typeof req.cookies.get === "function"
? (req.cookies as any).get("thirdweb_auth_token")
: (req.cookies as any).thirdweb_auth_token;
return cookie;
}
export async function getUser<
TData extends Json = Json,
TSession extends Json = Json,
>(
req: Request,
ctx: ThirdwebAuthContext<TData, TSession>,
): Promise<ThirdwebAuthUser<TData, TSession> | null> {
const token = getToken(req);
if (!token) {
return null;
}
let authenticatedUser: ThirdwebAuthUser<TData, TSession>;
try {
authenticatedUser = await ctx.auth.authenticate<TSession>(token, {
validateTokenId: async (tokenId: string) => {
if (ctx.authOptions?.validateTokenId) {
await ctx.authOptions?.validateTokenId(tokenId);
}
},
});
} catch (err) {
return null;
}
if (!ctx.callbacks?.onUser) {
return authenticatedUser;
}
const data = await ctx.callbacks.onUser(authenticatedUser);
if (!data) {
return authenticatedUser;
}
return { ...authenticatedUser, data: data };
}
+47 -52
View File
@@ -1,68 +1,63 @@
import { Json, ThirdwebAuth as ThirdwebAuthSDK } from "../core";
import { getUser } from "./helpers/user";
import loginHandler from "./routes/login";
import logoutHandler from "./routes/logout";
import userHandler from "./routes/user";
import {
ThirdwebAuthConfig,
ThirdwebAuthRoute,
ThirdwebAuthUser,
} from "./types";
import { ThirdwebSDK } from "@thirdweb-dev/sdk";
import { ThirdwebAuthConfig, ThirdwebAuthContext } from "./types";
import cookieParser from "cookie-parser";
import { Express, NextFunction, Request, Response } from "express";
import express, { Request, Response } from "express";
export * from "./types";
export function getUser(req: Request): ThirdwebAuthUser | null {
return req.user;
}
export function ThirdwebAuth(app: Express, cfg: ThirdwebAuthConfig) {
const ctx = {
...cfg,
sdk: ThirdwebSDK.fromPrivateKey(cfg.privateKey, "mainnet"),
const asyncHandler =
(fn: CallableFunction) =>
(...args: any[]) => {
const fnReturn = fn(...args);
const next = args[args.length - 1];
return Promise.resolve(fnReturn).catch(next);
};
const authUrl = cfg.authUrl?.replace(/\/$/, "") || "/auth";
export function ThirdwebAuth<
TData extends Json = Json,
TSession extends Json = Json,
>(cfg: ThirdwebAuthConfig<TData, TSession>) {
const ctx = {
...cfg,
auth: new ThirdwebAuthSDK(cfg.wallet, cfg.domain),
};
app.use(cookieParser());
const router = express.Router();
const cookieMiddleware = cookieParser();
app.use(async (req: Request, _: Response, next: NextFunction) => {
const { sdk, domain } = ctx;
let user = null;
const token = req.cookies.thirdweb_auth_token;
router.use(express.json());
router.use(cookieMiddleware);
if (token) {
try {
const address = await sdk.auth.authenticate(domain, token);
if (ctx.callbacks?.user) {
user = await ctx.callbacks.user(address);
}
user = { ...user, address };
} catch {
// No-op
}
}
router.post(
"/login",
asyncHandler((req: Request, res: Response) =>
loginHandler(req, res, ctx as ThirdwebAuthContext),
),
);
req.user = user as ThirdwebAuthUser | null;
next();
});
router.get(
"/user",
asyncHandler((req: Request, res: Response) =>
userHandler(req, res, ctx as ThirdwebAuthContext),
),
);
app.get(`${authUrl}/:route`, (req: Request, res: Response) => {
const action = req.params.route as ThirdwebAuthRoute;
router.post(
"/logout",
asyncHandler((req: Request, res: Response) =>
logoutHandler(req, res, ctx as ThirdwebAuthContext),
),
);
switch (action) {
case "login":
return loginHandler(req, res, ctx);
case "user":
return userHandler(req, res);
case "logout":
return logoutHandler(req, res);
default:
return res.status(400).json({
message: "Invalid route for authentication.",
});
}
});
return {
authRouter: router,
authMiddleware: cookieMiddleware,
getUser: (req: Request) => {
return getUser<TData, TSession>(req, ctx);
},
};
}
+55 -29
View File
@@ -1,38 +1,67 @@
import { ThirdwebAuthContext } from "../types";
import { LoginPayload } from "@thirdweb-dev/sdk";
import { GenerateOptions } from "../../core";
import { LoginPayloadBodySchema, ThirdwebAuthContext } from "../types";
import { serialize } from "cookie";
import { Request, Response } from "express";
function redirectWithError(req: Request, res: Response, error: string) {
const encodedError = encodeURIComponent(error);
const url = new URL(req.headers.referer as string);
url.searchParams.set("error", encodedError);
return res.redirect(url.toString());
}
export default async function handler(
req: Request,
res: Response,
ctx: ThirdwebAuthContext
ctx: ThirdwebAuthContext,
) {
if (req.method !== "GET") {
return redirectWithError(req, res, "INVALID_METHOD");
if (req.method !== "POST") {
return res.status(405).json({ error: "Method not allowed" });
}
const { sdk, domain } = ctx;
const parsedPayload = LoginPayloadBodySchema.safeParse(req.body);
// Get signed login payload from the frontend
const payload = JSON.parse(atob(req.query.payload as string)) as LoginPayload;
if (!payload) {
redirectWithError(req, res, "MISSING_LOGIN_PAYLOAD");
if (!parsedPayload.success) {
return res.status(400).json({ error: "Invalid login payload" });
}
let token;
const payload = parsedPayload.data.payload;
const validateNonce = async (nonce: string) => {
if (ctx.authOptions?.validateNonce) {
await ctx.authOptions?.validateNonce(nonce);
}
};
const getSession = async (address: string) => {
if (ctx.callbacks?.onLogin) {
return ctx.callbacks.onLogin(address, req);
}
};
const expirationTime = ctx.authOptions?.tokenDurationInSeconds
? new Date(Date.now() + 1000 * ctx.authOptions.tokenDurationInSeconds)
: undefined;
const generateOptions: GenerateOptions = {
verifyOptions: {
statement: ctx.authOptions?.statement,
uri: ctx.authOptions?.uri,
version: ctx.authOptions?.version,
chainId: ctx.authOptions?.chainId,
validateNonce,
resources: ctx.authOptions?.resources,
},
expirationTime,
session: getSession,
};
let token: string;
try {
// Generate an access token with the SDK using the signed payload
token = await sdk.auth.generateAuthToken(domain, payload);
} catch {
return redirectWithError(req, res, "INVALID_LOGIN_PAYLOAD");
token = await ctx.auth.generate(payload, generateOptions);
} catch (err: any) {
if (err.message) {
return res.status(400).json({ error: err.message });
} else if (typeof err === "string") {
return res.status(400).json({ error: err });
} else {
return res.status(400).json({ error: "Invalid login payload" });
}
}
// Securely set httpOnly cookie on request to prevent XSS on frontend
@@ -40,17 +69,14 @@ export default async function handler(
res.setHeader(
"Set-Cookie",
serialize("thirdweb_auth_token", token, {
path: "/",
domain: ctx.cookieOptions?.domain,
path: ctx.cookieOptions?.path || "/",
sameSite: ctx.cookieOptions?.sameSite || "none",
httpOnly: true,
secure: true,
sameSite: "strict",
})
}),
);
if (ctx.callbacks?.login) {
const address = sdk.auth.verify(domain, payload);
await ctx.callbacks.login(address);
}
return res.status(301).redirect(req.query.redirect as string);
// Send token in body and as cookie for frontend and backend use cases
return res.status(200).json({ token });
}
+21 -7
View File
@@ -1,21 +1,35 @@
import { getUser } from "../helpers/user";
import { ThirdwebAuthContext } from "../types";
import { serialize } from "cookie";
import { Request, Response } from "express";
export default async function handler(req: Request, res: Response) {
if (req.method !== "GET") {
return res.status(400).json({
error: "Invalid method. Only GET supported.",
export default async function handler(
req: Request,
res: Response,
ctx: ThirdwebAuthContext,
) {
if (req.method !== "POST") {
return res.status(405).json({
error: "Invalid method. Only POST supported.",
});
}
if (ctx.callbacks?.onLogout) {
const user = await getUser(req, ctx);
if (user) {
await ctx.callbacks.onLogout(user, req);
}
}
// Set the access token to 'none' and expire in 5 seconds
res.setHeader(
"Set-Cookie",
serialize("thirdweb_auth_token", "", {
path: "/",
domain: ctx.cookieOptions?.domain,
path: ctx.cookieOptions?.path || "/",
expires: new Date(Date.now() + 5 * 1000),
})
}),
);
return res.status(301).redirect(req.headers.referer as string);
return res.status(200).json({ message: "Successfully logged out" });
}
+10 -3
View File
@@ -1,11 +1,18 @@
import { getUser } from "../helpers/user";
import { ThirdwebAuthContext } from "../types";
import { Request, Response } from "express";
export default async function handler(req: Request, res: Response) {
export default async function handler(
req: Request,
res: Response,
ctx: ThirdwebAuthContext,
) {
if (req.method !== "GET") {
return res.status(400).json({
error: "Invalid method. Only GET supported.",
});
}
return res.status(200).json(req.user);
const user = await getUser(req, ctx);
return res.status(200).json(user);
}
-12
View File
@@ -1,12 +0,0 @@
import { ThirdwebAuthUser } from "..";
export {};
declare global {
// eslint-disable-next-line @typescript-eslint/no-namespace
namespace Express {
export interface Request {
user: ThirdwebAuthUser | null;
}
}
}
+53 -22
View File
@@ -1,32 +1,63 @@
import { ThirdwebSDK } from "@thirdweb-dev/sdk";
import { ThirdwebAuth } from "../../core";
import { Json, LoginPayloadOutputSchema, User } from "../../core/schema";
import { GenericAuthWallet } from "@thirdweb-dev/wallets";
import { Request } from "express";
import { z } from "zod";
export const LoginPayloadBodySchema = z.object({
payload: LoginPayloadOutputSchema,
});
export type ThirdwebAuthRoute = "login" | "user" | "logout";
export type ThirdwebAuthConfig = {
privateKey: string;
export type ThirdwebAuthUser<
TData extends Json = Json,
TSession extends Json = Json,
> = User<TSession> & {
data?: TData;
};
export type ThirdwebAuthConfig<
TData extends Json = Json,
TSession extends Json = Json,
> = {
domain: string;
authUrl?: string;
wallet: GenericAuthWallet;
authOptions?: {
statement?: string;
uri?: string;
version?: string;
chainId?: string;
resources?: string[];
validateNonce?:
| ((nonce: string) => void)
| ((nonce: string) => Promise<void>);
validateTokenId?:
| ((tokenId: string) => void)
| ((tokenId: string) => Promise<void>);
tokenDurationInSeconds?: number;
};
cookieOptions?: {
domain?: string;
path?: string;
sameSite?: "lax" | "strict" | "none";
};
callbacks?: {
login?: (address: string) => (Promise<void> | void);
user?: (address: string) => (Promise<Omit<ThirdwebAuthUser, "address">> | Omit<ThirdwebAuthUser, "address">);
onLogin?:
| ((address: string, req?: Request) => void | TSession)
| ((address: string, req?: Request) => Promise<void | TSession>);
onUser?:
| ((user: User<TSession>, req?: Request) => void | TData)
| ((user: User<TSession>, req?: Request) => Promise<void | TData>);
onLogout?:
| ((user: User, req?: Request) => void)
| ((user: User, req?: Request) => Promise<void>);
};
};
export type ThirdwebAuthContext = {
sdk: ThirdwebSDK;
domain: string;
callbacks?: {
login?: (address: string) => (Promise<void> | void);
user?: (address: string) => (Promise<Omit<ThirdwebAuthUser, "address">> | Omit<ThirdwebAuthUser, "address">);
};
};
export type ThirdwebAuthUser = {
address: string;
[key: string]: any;
};
export type RequestWithUser = Request & {
user: ThirdwebAuthUser | null;
export type ThirdwebAuthContext<
TData extends Json = Json,
TSession extends Json = Json,
> = Omit<Omit<ThirdwebAuthConfig<TData, TSession>, "wallet">, "domain"> & {
auth: ThirdwebAuth;
};
+1
View File
@@ -0,0 +1 @@
export * from "./core";
+50 -125
View File
@@ -1,135 +1,60 @@
import { ThirdwebNextAuthConfig } from "./types";
import { ThirdwebSDK } from "@thirdweb-dev/sdk";
import { serialize } from "cookie";
import { GetServerSidePropsContext, NextApiRequest, NextApiResponse } from "next";
import NextAuth, { NextAuthOptions, Session, unstable_getServerSession } from "next-auth";
import { LoginPayload, ThirdwebAuth, VerifyOptions } from "../core";
import { SignerWallet } from "../evm";
import { ThirdwebProviderConfig } from "./types";
import { ethers } from "ethers";
import { Awaitable, Session } from "next-auth/core/types";
import { JWT } from "next-auth/jwt/types";
import CredentialsProvider from "next-auth/providers/credentials";
export function ThirdwebNextAuth(cfg: ThirdwebNextAuthConfig) {
const sdk = ThirdwebSDK.fromPrivateKey(cfg.privateKey, "mainnet");
export function ThirdwebAuthProvider(cfg: ThirdwebProviderConfig) {
const wallet = new SignerWallet(ethers.Wallet.createRandom());
const auth = new ThirdwebAuth(wallet, cfg.domain);
function ThirdwebProvider(res: GetServerSidePropsContext["res"]) {
return CredentialsProvider({
name: "ThirdwebAuth",
credentials: {
payload: {
label: "Payload",
type: "text",
placeholder: "",
},
return CredentialsProvider({
name: "Credentials",
credentials: {
payload: {
label: "Payload",
type: "text",
placeholder: "",
},
async authorize({ payload }: any) {
try {
const parsed = JSON.parse(payload);
const token = await sdk.auth.generateAuthToken(
cfg.domain,
parsed
);
const address = await sdk.auth.authenticate(cfg.domain, token);
// Securely set httpOnly cookie on request to prevent XSS on frontend
// And set path to / to enable thirdweb_auth_token usage on all endpoints
res.setHeader(
"Set-Cookie",
serialize("thirdweb_auth_token", token, {
path: "/",
httpOnly: true,
secure: true,
sameSite: "strict",
})
);
return { address };
} catch (err) {
return null;
}
},
});
}
function nextOptions (
req: GetServerSidePropsContext["req"],
res: GetServerSidePropsContext["res"]
): NextAuthOptions {
async function session({ session }: { session: Session }) {
const token = req.cookies.thirdweb_auth_token || "";
},
async authorize({ payload }: any) {
try {
const address = await sdk.auth.authenticate(cfg.domain, token);
session.user = { ...session.user, address } as Session["user"];
return session;
} catch {
return session;
const parsedPayload: LoginPayload = JSON.parse(payload);
const verifyOptions: VerifyOptions = {
statement: cfg.authOptions?.statement,
uri: cfg.authOptions?.uri,
version: cfg.authOptions?.version,
chainId: cfg.authOptions?.chainId,
resources: cfg.authOptions?.resources,
validateNonce: async (nonce: string) => {
if (cfg.authOptions?.validateNonce) {
await cfg.authOptions?.validateNonce(nonce);
}
},
};
const address = await auth.verify(parsedPayload, verifyOptions);
return { id: address };
} catch (err) {
return null;
}
}
},
});
}
function signOut() {
res.setHeader(
"Set-Cookie",
serialize("thirdweb_auth_token", "", {
path: "/",
expires: new Date(Date.now() + 5 * 1000),
})
);
}
const providers: NextAuthOptions["providers"] = [
...cfg.nextOptions.providers,
ThirdwebProvider(res),
]
const configSession = cfg.nextOptions.callbacks?.session
const callbacks: NextAuthOptions["callbacks"] = {
...cfg.nextOptions.callbacks,
session: configSession
? async (params) => {
params.session = await session(params);
return configSession(params);
}
: session
export function authSession(params: {
session: Session;
token: JWT;
}): Awaitable<Session> {
if (params.token.sub && ethers.utils.isAddress(params.token.sub)) {
params.session.user = {
...params.session.user,
address: params.token.sub,
};
const configSignOut = cfg.nextOptions.events?.signOut
const events: NextAuthOptions["events"] = {
...cfg.nextOptions.events,
signOut: configSignOut
? async (params) => {
signOut();
return configSignOut(params);
}
: signOut
};
return {
...cfg.nextOptions,
providers,
callbacks,
events,
};
};
async function getUser(
...args:
| [NextApiRequest, NextApiResponse]
| [GetServerSidePropsContext["req"], GetServerSidePropsContext["res"]]
) {
return unstable_getServerSession(args[0], args[1], nextOptions(args[0], args[1]));
}
function NextAuthHandler(
...args: [] | [NextApiRequest, NextApiResponse]
) {
if (args.length === 0) {
return (req: NextApiRequest, res: NextApiResponse) => {
return NextAuth(req, res, nextOptions(req, res));
}
}
return NextAuth(args[0], args[1], nextOptions(args[0], args[1]));
}
return {
NextAuthHandler,
getUser
}
}
return params.session;
}
+14
View File
@@ -0,0 +1,14 @@
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import NextAuth from "next-auth";
declare module "next-auth" {
interface Session {
user: {
id: string;
username: string;
email: string;
address?: string;
[key: string]: string;
};
}
}
+13
View File
@@ -0,0 +1,13 @@
export type ThirdwebProviderConfig = {
domain: string;
authOptions?: {
statement?: string;
uri?: string;
version?: string;
chainId?: string;
resources?: string[];
validateNonce?:
| ((nonce: string) => void)
| ((nonce: string) => Promise<void>);
};
};
@@ -1,7 +0,0 @@
import { NextAuthOptions } from "next-auth";
export type ThirdwebNextAuthConfig = {
privateKey: string;
domain: string;
nextOptions: NextAuthOptions;
}
+65
View File
@@ -0,0 +1,65 @@
import { Json } from "../../core/schema";
import { ThirdwebAuthContext, ThirdwebAuthUser } from "../types";
import { GetServerSidePropsContext, NextApiRequest } from "next";
import { NextRequest } from "next/server";
function getToken(
req: GetServerSidePropsContext["req"] | NextRequest | NextApiRequest,
): string | undefined {
if (!!(req as NextApiRequest).headers["authorization"]) {
const authorizationHeader = (req as NextApiRequest).headers[
"authorization"
]?.split(" ");
if (authorizationHeader?.length === 2) {
return authorizationHeader[1];
}
return undefined;
}
const cookie: string | undefined = !req.cookies
? undefined
: typeof req.cookies.get === "function"
? (req.cookies as any).get("thirdweb_auth_token")
: (req.cookies as any).thirdweb_auth_token;
return cookie;
}
export async function getUser<
TData extends Json = Json,
TSession extends Json = Json,
>(
req: GetServerSidePropsContext["req"] | NextRequest | NextApiRequest,
ctx: ThirdwebAuthContext<TData, TSession>,
): Promise<ThirdwebAuthUser<TData, TSession> | null> {
const token = getToken(req);
if (!token) {
return null;
}
let authenticatedUser: ThirdwebAuthUser<TData, TSession>;
try {
authenticatedUser = await ctx.auth.authenticate<TSession>(token, {
validateTokenId: async (tokenId: string) => {
if (ctx.authOptions?.validateTokenId) {
await ctx.authOptions?.validateTokenId(tokenId);
}
},
});
} catch (err) {
return null;
}
if (!ctx.callbacks?.onUser) {
return authenticatedUser;
}
const data = await ctx.callbacks.onUser(authenticatedUser);
if (!data) {
return authenticatedUser;
}
return { ...authenticatedUser, data: data };
}
+19 -31
View File
@@ -1,3 +1,5 @@
import { Json, ThirdwebAuth as ThirdwebAuthSDK } from "../core";
import { getUser } from "./helpers/user";
import loginHandler from "./routes/login";
import logoutHandler from "./routes/logout";
import userHandler from "./routes/user";
@@ -5,9 +7,7 @@ import {
ThirdwebAuthConfig,
ThirdwebAuthContext,
ThirdwebAuthRoute,
ThirdwebAuthUser,
} from "./types";
import { ThirdwebSDK } from "@thirdweb-dev/sdk";
import { NextRequest } from "next/server";
import {
GetServerSidePropsContext,
@@ -20,7 +20,7 @@ export * from "./types";
async function ThirdwebAuthRouter(
req: NextApiRequest,
res: NextApiResponse,
ctx: ThirdwebAuthContext
ctx: ThirdwebAuthContext,
) {
// Catch-all route must be named with [...thirdweb]
const { thirdweb } = req.query;
@@ -32,7 +32,7 @@ async function ThirdwebAuthRouter(
case "user":
return await userHandler(req, res, ctx);
case "logout":
return await logoutHandler(req, res);
return await logoutHandler(req, res, ctx);
default:
return res.status(400).json({
message: "Invalid route for authentication.",
@@ -40,10 +40,13 @@ async function ThirdwebAuthRouter(
}
}
export function ThirdwebAuth(cfg: ThirdwebAuthConfig) {
export function ThirdwebAuth<
TData extends Json = Json,
TSession extends Json = Json,
>(cfg: ThirdwebAuthConfig<TData, TSession>) {
const ctx = {
...cfg,
sdk: ThirdwebSDK.fromPrivateKey(cfg.privateKey, "mainnet"),
auth: new ThirdwebAuthSDK(cfg.wallet, cfg.domain),
};
function ThirdwebAuthHandler(
@@ -51,33 +54,18 @@ export function ThirdwebAuth(cfg: ThirdwebAuthConfig) {
) {
if (args.length === 0) {
return async (req: NextApiRequest, res: NextApiResponse) =>
await ThirdwebAuthRouter(req, res, ctx);
await ThirdwebAuthRouter(req, res, ctx as ThirdwebAuthContext);
}
return ThirdwebAuthRouter(args[0], args[1], ctx);
return ThirdwebAuthRouter(args[0], args[1], ctx as ThirdwebAuthContext);
}
async function getUser(
req: GetServerSidePropsContext["req"] | NextRequest | NextApiRequest
) {
const { sdk, domain } = ctx;
let user: ThirdwebAuthUser | null = null;
const token =
typeof req.cookies.get === "function"
? (req.cookies as any).get("thirdweb_auth_token")
: (req.cookies as any).thirdweb_auth_token;
if (token) {
try {
const address = await sdk.auth.authenticate(domain, token);
user = { address };
} catch {
// No-op
}
}
return user;
}
return { ThirdwebAuthHandler, getUser };
return {
ThirdwebAuthHandler,
getUser: (
req: GetServerSidePropsContext["req"] | NextRequest | NextApiRequest,
) => {
return getUser<TData, TSession>(req, ctx);
},
};
}
+55 -33
View File
@@ -1,42 +1,67 @@
import { ThirdwebAuthContext } from "../types";
import { LoginPayload } from "@thirdweb-dev/sdk";
import { GenerateOptions } from "../../core";
import { LoginPayloadBodySchema, ThirdwebAuthContext } from "../types";
import { serialize } from "cookie";
import { NextApiRequest, NextApiResponse } from "next";
function redirectWithError(
req: NextApiRequest,
res: NextApiResponse,
error: string
) {
const encodedError = encodeURIComponent(error);
const url = new URL(req.headers.referer as string);
url.searchParams.set("error", encodedError);
return res.redirect(url.toString());
}
export default async function handler(
req: NextApiRequest,
res: NextApiResponse,
ctx: ThirdwebAuthContext
ctx: ThirdwebAuthContext,
) {
if (req.method !== "GET") {
return redirectWithError(req, res, "INVALID_METHOD");
if (req.method !== "POST") {
return res.status(405).json({ error: "Method not allowed" });
}
const { sdk, domain } = ctx;
const parsedPayload = LoginPayloadBodySchema.safeParse(req.body);
// Get signed login payload from the frontend
const payload = JSON.parse(atob(req.query.payload as string)) as LoginPayload;
if (!payload) {
redirectWithError(req, res, "MISSING_LOGIN_PAYLOAD");
if (!parsedPayload.success) {
return res.status(400).json({ error: "Invalid login payload" });
}
let token;
const payload = parsedPayload.data.payload;
const validateNonce = async (nonce: string) => {
if (ctx.authOptions?.validateNonce) {
await ctx.authOptions?.validateNonce(nonce);
}
};
const getSession = async (address: string) => {
if (ctx.callbacks?.onLogin) {
return ctx.callbacks.onLogin(address, req);
}
};
const expirationTime = ctx.authOptions?.tokenDurationInSeconds
? new Date(Date.now() + 1000 * ctx.authOptions.tokenDurationInSeconds)
: undefined;
const generateOptions: GenerateOptions = {
verifyOptions: {
statement: ctx.authOptions?.statement,
uri: ctx.authOptions?.uri,
version: ctx.authOptions?.version,
chainId: ctx.authOptions?.chainId,
validateNonce,
resources: ctx.authOptions?.resources,
},
expirationTime,
session: getSession,
};
let token: string;
try {
// Generate an access token with the SDK using the signed payload
token = await sdk.auth.generateAuthToken(domain, payload);
} catch {
return redirectWithError(req, res, "INVALID_LOGIN_PAYLOAD");
token = await ctx.auth.generate(payload, generateOptions);
} catch (err: any) {
if (err.message) {
return res.status(400).json({ error: err.message });
} else if (typeof err === "string") {
return res.status(400).json({ error: err });
} else {
return res.status(400).json({ error: "Invalid login payload" });
}
}
// Securely set httpOnly cookie on request to prevent XSS on frontend
@@ -44,17 +69,14 @@ export default async function handler(
res.setHeader(
"Set-Cookie",
serialize("thirdweb_auth_token", token, {
path: "/",
domain: ctx.cookieOptions?.domain,
path: ctx.cookieOptions?.path || "/",
sameSite: ctx.cookieOptions?.sameSite || "none",
httpOnly: true,
secure: true,
sameSite: "strict",
})
}),
);
if (ctx.callbacks?.login) {
const address = sdk.auth.verify(domain, payload);
await ctx.callbacks.login(address);
}
return res.status(301).redirect(req.query.redirect as string);
// Send token in body and as cookie for frontend and backend use cases
return res.status(200).json({ token });
}
+18 -7
View File
@@ -1,24 +1,35 @@
import { getUser } from "../helpers/user";
import { ThirdwebAuthContext } from "../types";
import { serialize } from "cookie";
import { NextApiRequest, NextApiResponse } from "next";
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
res: NextApiResponse,
ctx: ThirdwebAuthContext,
) {
if (req.method !== "GET") {
return res.status(400).json({
error: "Invalid method. Only GET supported.",
if (req.method !== "POST") {
return res.status(405).json({
error: "Invalid method. Only POST supported.",
});
}
if (ctx.callbacks?.onLogout) {
const user = await getUser(req, ctx);
if (user) {
await ctx.callbacks.onLogout(user, req);
}
}
// Set the access token to 'none' and expire in 5 seconds
res.setHeader(
"Set-Cookie",
serialize("thirdweb_auth_token", "", {
path: "/",
domain: ctx.cookieOptions?.domain,
path: ctx.cookieOptions?.path || "/",
expires: new Date(Date.now() + 5 * 1000),
})
}),
);
return res.status(301).redirect(req.headers.referer as string);
return res.status(200).json({ message: "Successfully logged out" });
}
+5 -21
View File
@@ -1,34 +1,18 @@
import { ThirdwebAuthContext, ThirdwebAuthUser } from "../types";
import { getUser } from "../helpers/user";
import { ThirdwebAuthContext } from "../types";
import { NextApiRequest, NextApiResponse } from "next";
export default async function handler(
req: NextApiRequest,
res: NextApiResponse,
ctx: ThirdwebAuthContext
ctx: ThirdwebAuthContext,
) {
if (req.method !== "GET") {
return res.status(400).json({
error: "Invalid method. Only GET supported.",
});
}
const { sdk, domain } = ctx;
let user = null;
const token = req.cookies.thirdweb_auth_token;
if (token) {
try {
const address = await sdk.auth.authenticate(domain, token);
if (ctx.callbacks?.user) {
user = await ctx.callbacks.user(address);
}
user = { ...user, address };
} catch {
// No-op
}
}
return res.status(200).json(user as ThirdwebAuthUser | null);
const user = await getUser(req, ctx);
return res.status(200).json(user);
}
+66 -17
View File
@@ -1,26 +1,75 @@
import { ThirdwebSDK } from "@thirdweb-dev/sdk";
import { ThirdwebAuth } from "../../core";
import { Json, LoginPayloadOutputSchema, User } from "../../core/schema";
import { GenericAuthWallet } from "@thirdweb-dev/wallets";
import { GetServerSidePropsContext, NextApiRequest } from "next";
import { NextRequest } from "next/server";
import { z } from "zod";
export const LoginPayloadBodySchema = z.object({
payload: LoginPayloadOutputSchema,
});
type RequestType =
| GetServerSidePropsContext["req"]
| NextRequest
| NextApiRequest;
export type ThirdwebAuthRoute = "login" | "logout" | "user";
export type ThirdwebAuthConfig = {
privateKey: string;
export type ThirdwebAuthUser<
TData extends Json = Json,
TSession extends Json = Json,
> = User<TSession> & {
data?: TData;
};
export type ThirdwebAuthConfig<
TData extends Json = Json,
TSession extends Json = Json,
> = {
domain: string;
wallet: GenericAuthWallet;
authOptions?: {
statement?: string;
uri?: string;
version?: string;
chainId?: string;
resources?: string[];
validateNonce?:
| ((nonce: string) => void)
| ((nonce: string) => Promise<void>);
validateTokenId?:
| ((tokenId: string) => void)
| ((tokenId: string) => Promise<void>);
tokenDurationInSeconds?: number;
};
cookieOptions?: {
domain?: string;
path?: string;
sameSite?: "lax" | "strict" | "none";
};
callbacks?: {
login?: (address: string) => (Promise<void> | void);
user?: (address: string) => (Promise<Omit<ThirdwebAuthUser, "address">> | Omit<ThirdwebAuthUser, "address">);
onLogin?:
| ((address: string, req?: NextApiRequest) => void | TSession)
| ((address: string, req?: NextApiRequest) => Promise<void | TSession>);
onUser?:
| (<TRequestType extends RequestType = RequestType>(
user: User<TSession>,
req?: TRequestType,
) => void | TData)
| (<TRequestType extends RequestType = RequestType>(
user: User<TSession>,
req?: TRequestType,
) => Promise<void | TData>);
onLogout?:
| ((user: User, req?: NextApiRequest) => void)
| ((user: User, req?: NextApiRequest) => Promise<void>);
};
};
export type ThirdwebAuthContext = {
sdk: ThirdwebSDK;
domain: string;
callbacks?: {
login?: (address: string) => (Promise<void> | void);
user?: (address: string) => (Promise<Omit<ThirdwebAuthUser, "address">> | Omit<ThirdwebAuthUser, "address">);
};
};
export type ThirdwebAuthUser = {
address: string;
[key: string]: any;
export type ThirdwebAuthContext<
TData extends Json = Json,
TSession extends Json = Json,
> = Omit<Omit<ThirdwebAuthConfig<TData, TSession>, "wallet">, "domain"> & {
auth: ThirdwebAuth;
};
+28
View File
@@ -0,0 +1,28 @@
import { ThirdwebAuth } from "../core";
import { LoginPayload, VerifyOptions } from "../core/schema";
import { KeypairWallet } from "./signer";
import { Keypair } from "@solana/web3.js";
const wallet = new KeypairWallet(Keypair.generate());
const authMap = new Map<string, ThirdwebAuth>();
export async function verifyLogin(
domain: string,
payload: LoginPayload,
options?: Omit<VerifyOptions, "domain">,
) {
let auth: ThirdwebAuth;
if (!authMap.has(domain)) {
auth = new ThirdwebAuth(wallet, domain);
authMap.set(domain, auth);
} else {
auth = authMap.get(domain) as ThirdwebAuth;
}
try {
const address = await auth.verify(payload, options);
return { address, error: undefined };
} catch (err: any) {
return { address: undefined, error: err.message };
}
}
+2
View File
@@ -0,0 +1,2 @@
export * from "./signer";
export * from "./auth";
+69
View File
@@ -0,0 +1,69 @@
import * as ed25519 from "@noble/ed25519";
import { Signer, Keypair, PublicKey } from "@solana/web3.js";
import type { Ecosystem, GenericAuthWallet } from "@thirdweb-dev/wallets";
import bs58 from "bs58";
import nacl from "tweetnacl";
export interface SolanaSigner {
publicKey: PublicKey;
signMessage(message: Uint8Array): Promise<Uint8Array>;
}
export class SignerWallet implements GenericAuthWallet {
type: Ecosystem = "solana";
private signer: SolanaSigner;
constructor(signer: SolanaSigner) {
this.signer = signer;
}
public async getAddress(): Promise<string> {
return this.signer.publicKey.toBase58();
}
public async signMessage(message: string): Promise<string> {
const encodedMessage = new TextEncoder().encode(message);
const signedMessage = await this.signer.signMessage(encodedMessage);
const signature = bs58.encode(signedMessage);
return signature;
}
public async verifySignature(
message: string,
signature: string,
address: string,
): Promise<boolean> {
return nacl.sign.detached.verify(
new TextEncoder().encode(message),
bs58.decode(signature),
bs58.decode(address),
);
}
}
class KeypairSigner implements SolanaSigner {
private keypair: Signer;
public publicKey: PublicKey;
constructor(keypair: Signer) {
this.keypair = keypair;
this.publicKey = keypair.publicKey;
}
public async signMessage(message: Uint8Array): Promise<Uint8Array> {
return ed25519.sync.sign(message, this.keypair.secretKey.slice(0, 32));
}
}
export class KeypairWallet extends SignerWallet {
constructor(keypair: Keypair) {
super(new KeypairSigner(keypair));
}
}
export class PrivateKeyWallet extends KeypairWallet {
constructor(privateKey: string) {
super(Keypair.fromSecretKey(bs58.decode(privateKey)));
}
}
+8
View File
@@ -0,0 +1,8 @@
{
"extension": [
"ts"
],
"require": [
"@swc-node/register"
]
}
+353
View File
@@ -0,0 +1,353 @@
import { ThirdwebAuth } from "../src/core";
import { SignerWallet } from "../src/evm";
import { expect } from "chai";
import { Wallet } from "ethers";
describe("Wallet Authentication", async () => {
let adminWallet: any, signerWallet: any, attackerWallet: any;
let auth: ThirdwebAuth;
before(async () => {
const [adminSigner, signerSigner, attackerSigner] = [
Wallet.createRandom(),
Wallet.createRandom(),
Wallet.createRandom(),
];
adminWallet = new SignerWallet(adminSigner);
signerWallet = new SignerWallet(signerSigner);
attackerWallet = new SignerWallet(attackerSigner);
auth = new ThirdwebAuth(signerWallet, "thirdweb.com");
});
beforeEach(async () => {
auth.updateWallet(signerWallet);
});
it("Should verify logged in wallet", async () => {
const payload = await auth.login();
auth.updateWallet(adminWallet);
const address = await auth.verify(payload);
expect(address).to.equal(await signerWallet.getAddress());
});
it("Should verify logged in wallet with chain ID and expiration", async () => {
const payload = await auth.login({
expirationTime: new Date(Date.now() + 1000 * 60 * 5),
chainId: "137",
});
auth.updateWallet(adminWallet);
const address = await auth.verify(payload, {
chainId: "137",
});
expect(address).to.equal(await signerWallet.getAddress());
});
it("Should verify payload with resources", async () => {
const payload = await auth.login({
resources: ["https://example.com", "https://test.com"],
});
auth.updateWallet(adminWallet);
const address = await auth.verify(payload, {
resources: ["https://example.com", "https://test.com"],
});
expect(address).to.equal(await signerWallet.getAddress());
});
it("Should reject payload without necessary resources", async () => {
const payload = await auth.login({
resources: ["https://example.com"],
});
auth.updateWallet(adminWallet);
try {
await auth.verify(payload, {
resources: ["https://example.com", "https://test.com"],
});
expect.fail();
} catch (err: any) {
expect(err.message).to.equal(
"Login request is missing required resources: https://test.com",
);
}
});
it("Should verify payload with customized statement", async () => {
const payload = await auth.login({
statement: "Please sign!",
});
auth.updateWallet(adminWallet);
const address = await auth.verify(payload, {
statement: "Please sign!",
});
expect(address).to.equal(await signerWallet.getAddress());
});
it("Should reject payload with incorrect statement", async () => {
const payload = await auth.login({
statement: "Please sign!",
});
auth.updateWallet(adminWallet);
try {
await auth.verify(payload, {
statement: "Please sign again!",
});
expect.fail();
} catch (err: any) {
expect(err.message).to.include(
"Expected statement 'Please sign again!' does not match statement on payload",
);
}
});
it("Should reject invalid nonce", async () => {
const payload = await auth.login();
auth.updateWallet(adminWallet);
try {
await auth.verify(payload, {
validateNonce: (nonce: string) => {
if (nonce === payload.payload.nonce) {
throw new Error();
}
},
});
expect.fail();
} catch (err: any) {
expect(err.message).to.equal("Login request nonce is invalid");
}
});
it("Should accept valid nonce", async () => {
const payload = await auth.login();
auth.updateWallet(adminWallet);
const address = await auth.verify(payload, {
validateNonce: (nonce: string) => {
if (nonce !== payload.payload.nonce) {
throw new Error();
}
},
});
expect(address).to.equal(await signerWallet.getAddress());
});
it("Should reject payload with incorrect domain", async () => {
const payload = await auth.login();
auth.updateWallet(adminWallet);
try {
await auth.verify(payload, { domain: "test.thirdweb.com" });
expect.fail();
} catch (err: any) {
expect(err.message).to.equal(
"Expected domain 'test.thirdweb.com' does not match domain on payload 'thirdweb.com'",
);
}
});
it("Should reject expired login payload", async () => {
const payload = await auth.login({
expirationTime: new Date(Date.now() - 1000 * 60 * 5),
});
auth.updateWallet(adminWallet);
try {
await auth.verify(payload);
expect.fail();
} catch (err: any) {
expect(err.message).to.equal("Login request has expired");
}
});
it("Should reject payload with incorrect chain ID", async () => {
const payload = await auth.login({
chainId: "1",
});
auth.updateWallet(adminWallet);
try {
await auth.verify(payload, {
chainId: "137",
});
expect.fail();
} catch (err: any) {
expect(err.message).to.equal(
"Expected chain ID '137' does not match chain ID on payload '1'",
);
}
});
it("Should reject payload with incorrect signer", async () => {
const payload = await auth.login();
payload.payload.address = await attackerWallet.getAddress();
auth.updateWallet(adminWallet);
try {
await auth.verify(payload);
expect.fail();
} catch (err: any) {
expect(err.message).to.contain("does not match payload address");
}
});
it("Should generate valid authentication token", async () => {
const payload = await auth.login();
auth.updateWallet(adminWallet);
const token = await auth.generate(payload);
const user = await auth.authenticate(token);
expect(user.address).to.equal(await signerWallet.getAddress());
});
it("Should reject token with incorrect domain", async () => {
const payload = await auth.login();
auth.updateWallet(adminWallet);
const token = await auth.generate(payload);
try {
await auth.authenticate(token, { domain: "test.thirdweb.com" });
expect.fail();
} catch (err: any) {
expect(err.message).to.contain(
"Expected token to be for the domain 'test.thirdweb.com', but found token with domain 'thirdweb.com'",
);
}
});
it("Should reject token before invalid before", async () => {
const payload = await auth.login();
auth.updateWallet(adminWallet);
const token = await auth.generate(payload, {
invalidBefore: new Date(Date.now() + 1000 * 60 * 5),
});
try {
await auth.authenticate(token);
expect.fail();
} catch (err: any) {
expect(err.message).to.contain("This token is invalid before");
}
});
it("Should reject expired authentication token", async () => {
const payload = await auth.login();
auth.updateWallet(adminWallet);
const token = await auth.generate(payload, {
expirationTime: new Date(Date.now() - 1000 * 60 * 5),
});
try {
await auth.authenticate(token);
expect.fail();
} catch (err: any) {
expect(err.message).to.contain("This token expired");
}
});
it("Should reject if admin address is not connected wallet address", async () => {
const payload = await auth.login();
auth.updateWallet(adminWallet);
const token = await auth.generate(payload);
auth.updateWallet(signerWallet);
try {
await auth.authenticate(token);
expect.fail();
} catch (err: any) {
expect(err.message).to.contain(
`Expected the connected wallet address '${await signerWallet.getAddress()}' to match the token issuer address '${await adminWallet.getAddress()}'`,
);
}
});
it("Should accept token with valid token ID", async () => {
const payload = await auth.login();
auth.updateWallet(adminWallet);
const token = await auth.generate(payload, {
tokenId: "test",
});
const user = await auth.authenticate(token, {
validateTokenId: (tokenId: string) => {
if (tokenId !== "test") {
throw new Error();
}
},
});
expect(user.address).to.equal(await signerWallet.getAddress());
});
it("Should reject token with invalid token ID", async () => {
const payload = await auth.login();
auth.updateWallet(adminWallet);
const token = await auth.generate(payload, {
tokenId: "test",
});
try {
await auth.authenticate(token, {
validateTokenId: (tokenId: string) => {
if (tokenId !== "invalid") {
throw new Error();
}
},
});
expect.fail();
} catch (err: any) {
expect(err.message).to.contain("Token ID is invalid");
}
});
it("Should propagate session on token", async () => {
const payload = await auth.login();
auth.updateWallet(adminWallet);
const token = await auth.generate(payload, {
session: { role: "admin" },
});
const user = await auth.authenticate(token);
expect(user.address).to.equal(await signerWallet.getAddress());
expect(user.session).to.deep.equal({ role: "admin" });
});
it("Should call session callback function", async () => {
const payload = await auth.login();
auth.updateWallet(adminWallet);
const token = await auth.generate(payload, {
session: (address: string) => {
return { address, role: "admin" };
},
});
const user = await auth.authenticate(token);
expect(user.address).to.equal(await signerWallet.getAddress());
expect(user.session).to.deep.equal({
address: await signerWallet.getAddress(),
role: "admin",
});
});
});
+353
View File
@@ -0,0 +1,353 @@
import { ThirdwebAuth } from "../src/core";
import { KeypairWallet } from "../src/solana";
import { Keypair } from "@solana/web3.js";
import { expect } from "chai";
describe("Wallet Authentication", async () => {
let adminWallet: any, signerWallet: any, attackerWallet: any;
let auth: ThirdwebAuth;
before(async () => {
const [adminSigner, signerSigner, attackerSigner] = [
Keypair.generate(),
Keypair.generate(),
Keypair.generate(),
];
adminWallet = new KeypairWallet(adminSigner);
signerWallet = new KeypairWallet(signerSigner);
attackerWallet = new KeypairWallet(attackerSigner);
auth = new ThirdwebAuth(signerWallet, "thirdweb.com");
});
beforeEach(async () => {
auth.updateWallet(signerWallet);
});
it("Should verify logged in wallet", async () => {
const payload = await auth.login();
auth.updateWallet(adminWallet);
const address = await auth.verify(payload);
expect(address).to.equal(await signerWallet.getAddress());
});
it("Should verify logged in wallet with chain ID and expiration", async () => {
const payload = await auth.login({
expirationTime: new Date(Date.now() + 1000 * 60 * 5),
chainId: "137",
});
auth.updateWallet(adminWallet);
const address = await auth.verify(payload, {
chainId: "137",
});
expect(address).to.equal(await signerWallet.getAddress());
});
it("Should verify payload with resources", async () => {
const payload = await auth.login({
resources: ["https://example.com", "https://test.com"],
});
auth.updateWallet(adminWallet);
const address = await auth.verify(payload, {
resources: ["https://example.com", "https://test.com"],
});
expect(address).to.equal(await signerWallet.getAddress());
});
it("Should reject payload without necessary resources", async () => {
const payload = await auth.login({
resources: ["https://example.com"],
});
auth.updateWallet(adminWallet);
try {
await auth.verify(payload, {
resources: ["https://example.com", "https://test.com"],
});
expect.fail();
} catch (err: any) {
expect(err.message).to.equal(
"Login request is missing required resources: https://test.com",
);
}
});
it("Should verify payload with customized statement", async () => {
const payload = await auth.login({
statement: "Please sign!",
});
auth.updateWallet(adminWallet);
const address = await auth.verify(payload, {
statement: "Please sign!",
});
expect(address).to.equal(await signerWallet.getAddress());
});
it("Should reject payload with incorrect statement", async () => {
const payload = await auth.login({
statement: "Please sign!",
});
auth.updateWallet(adminWallet);
try {
await auth.verify(payload, {
statement: "Please sign again!",
});
expect.fail();
} catch (err: any) {
expect(err.message).to.include(
"Expected statement 'Please sign again!' does not match statement on payload",
);
}
});
it("Should reject invalid nonce", async () => {
const payload = await auth.login();
auth.updateWallet(adminWallet);
try {
await auth.verify(payload, {
validateNonce: (nonce: string) => {
if (nonce === payload.payload.nonce) {
throw new Error();
}
},
});
expect.fail();
} catch (err: any) {
expect(err.message).to.equal("Login request nonce is invalid");
}
});
it("Should accept valid nonce", async () => {
const payload = await auth.login();
auth.updateWallet(adminWallet);
const address = await auth.verify(payload, {
validateNonce: (nonce: string) => {
if (nonce !== payload.payload.nonce) {
throw new Error();
}
},
});
expect(address).to.equal(await signerWallet.getAddress());
});
it("Should reject payload with incorrect domain", async () => {
const payload = await auth.login();
auth.updateWallet(adminWallet);
try {
await auth.verify(payload, { domain: "test.thirdweb.com" });
expect.fail();
} catch (err: any) {
expect(err.message).to.equal(
"Expected domain 'test.thirdweb.com' does not match domain on payload 'thirdweb.com'",
);
}
});
it("Should reject expired login payload", async () => {
const payload = await auth.login({
expirationTime: new Date(Date.now() - 1000 * 60 * 5),
});
auth.updateWallet(adminWallet);
try {
await auth.verify(payload);
expect.fail();
} catch (err: any) {
expect(err.message).to.equal("Login request has expired");
}
});
it("Should reject payload with incorrect chain ID", async () => {
const payload = await auth.login({
chainId: "1",
});
auth.updateWallet(adminWallet);
try {
await auth.verify(payload, {
chainId: "137",
});
expect.fail();
} catch (err: any) {
expect(err.message).to.equal(
"Expected chain ID '137' does not match chain ID on payload '1'",
);
}
});
it("Should reject payload with incorrect signer", async () => {
const payload = await auth.login();
payload.payload.address = await attackerWallet.getAddress();
auth.updateWallet(adminWallet);
try {
await auth.verify(payload);
expect.fail();
} catch (err: any) {
expect(err.message).to.contain("does not match payload address");
}
});
it("Should generate valid authentication token", async () => {
const payload = await auth.login();
auth.updateWallet(adminWallet);
const token = await auth.generate(payload);
const user = await auth.authenticate(token);
expect(user.address).to.equal(await signerWallet.getAddress());
});
it("Should reject token with incorrect domain", async () => {
const payload = await auth.login();
auth.updateWallet(adminWallet);
const token = await auth.generate(payload);
try {
await auth.authenticate(token, { domain: "test.thirdweb.com" });
expect.fail();
} catch (err: any) {
expect(err.message).to.contain(
"Expected token to be for the domain 'test.thirdweb.com', but found token with domain 'thirdweb.com'",
);
}
});
it("Should reject token before invalid before", async () => {
const payload = await auth.login();
auth.updateWallet(adminWallet);
const token = await auth.generate(payload, {
invalidBefore: new Date(Date.now() + 1000 * 60 * 5),
});
try {
await auth.authenticate(token);
expect.fail();
} catch (err: any) {
expect(err.message).to.contain("This token is invalid before");
}
});
it("Should reject expired authentication token", async () => {
const payload = await auth.login();
auth.updateWallet(adminWallet);
const token = await auth.generate(payload, {
expirationTime: new Date(Date.now() - 1000 * 60 * 5),
});
try {
await auth.authenticate(token);
expect.fail();
} catch (err: any) {
expect(err.message).to.contain("This token expired");
}
});
it("Should reject if admin address is not connected wallet address", async () => {
const payload = await auth.login();
auth.updateWallet(adminWallet);
const token = await auth.generate(payload);
auth.updateWallet(signerWallet);
try {
await auth.authenticate(token);
expect.fail();
} catch (err: any) {
expect(err.message).to.contain(
`Expected the connected wallet address '${await signerWallet.getAddress()}' to match the token issuer address '${await adminWallet.getAddress()}'`,
);
}
});
it("Should accept token with valid token ID", async () => {
const payload = await auth.login();
auth.updateWallet(adminWallet);
const token = await auth.generate(payload, {
tokenId: "test",
});
const user = await auth.authenticate(token, {
validateTokenId: (tokenId: string) => {
if (tokenId !== "test") {
throw new Error();
}
},
});
expect(user.address).to.equal(await signerWallet.getAddress());
});
it("Should reject token with invalid token ID", async () => {
const payload = await auth.login();
auth.updateWallet(adminWallet);
const token = await auth.generate(payload, {
tokenId: "test",
});
try {
await auth.authenticate(token, {
validateTokenId: (tokenId: string) => {
if (tokenId !== "invalid") {
throw new Error();
}
},
});
expect.fail();
} catch (err: any) {
expect(err.message).to.contain("Token ID is invalid");
}
});
it("Should propagate session on token", async () => {
const payload = await auth.login();
auth.updateWallet(adminWallet);
const token = await auth.generate(payload, {
session: { role: "admin" },
});
const user = await auth.authenticate(token);
expect(user.address).to.equal(await signerWallet.getAddress());
expect(user.session).to.deep.equal({ role: "admin" });
});
it("Should call session callback function", async () => {
const payload = await auth.login();
auth.updateWallet(adminWallet);
const token = await auth.generate(payload, {
session: (address: string) => {
return { address, role: "admin" };
},
});
const user = await auth.authenticate(token);
expect(user.address).to.equal(await signerWallet.getAddress());
expect(user.session).to.deep.equal({
address: await signerWallet.getAddress(),
role: "admin",
});
});
});
+1 -1
View File
@@ -1,5 +1,5 @@
{
"extends": "@thirdweb-dev/tsconfig/base.json",
"extends": "@thirdweb-dev/tsconfig/sdk.json",
"include": ["."],
"exclude": ["dist", "build", "node_modules"]
}
+67
View File
@@ -0,0 +1,67 @@
# @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
- [#608](https://github.com/thirdweb-dev/js/pull/608) [`3d644fb`](https://github.com/thirdweb-dev/js/commit/3d644fb8cbae8bc3ee624505831b9f5c6996898a) Thanks [@jnsdls](https://github.com/jnsdls)! - update chains
## 0.1.2
### Patch Changes
- [#601](https://github.com/thirdweb-dev/js/pull/601) [`66cf1fb`](https://github.com/thirdweb-dev/js/commit/66cf1fb5c2e8deb486543ee028d786bb8eef6c19) Thanks [@jnsdls](https://github.com/jnsdls)! - upgrade dependencies
## 0.1.1
### Patch Changes
- [#599](https://github.com/thirdweb-dev/js/pull/599) [`f580b8a`](https://github.com/thirdweb-dev/js/commit/f580b8ac06534df24b0194cbc632b4a8fd447611) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - New chains added
## 0.1.0
### Minor Changes
- [`af8cf40`](https://github.com/thirdweb-dev/js/commit/af8cf40e4e1dab6afcc7622f7f9bbcfc6e8534d8) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Initial release for `@thirdweb-dev/chains`.
Use this package to easily configure chains with `@thirdweb-dev/sdk` and `@thirdweb-dev/react`.
### Patch Changes
- [`6a50719`](https://github.com/thirdweb-dev/js/commit/6a507194861b0712fd753c49ac63a8af68eb21d5) Thanks [@jnsdls](https://github.com/jnsdls)! - add `getChainRPCs` export to get a list of RPCs instead of a single RPC via `getChainRPC`
- [`5d25ee1`](https://github.com/thirdweb-dev/js/commit/5d25ee1ab7abb4bfbded283a18f2d7740bb6995d) Thanks [@jnsdls](https://github.com/jnsdls)! - fix `getChainRPC()` utility function logic
- [`d0bcd2c`](https://github.com/thirdweb-dev/js/commit/d0bcd2c5871ca9480efc8d97e27e337eb9bbf830) Thanks [@jnsdls](https://github.com/jnsdls)! - add new chains + localhost special case
- [#589](https://github.com/thirdweb-dev/js/pull/589) [`017b0d5`](https://github.com/thirdweb-dev/js/commit/017b0d56b64651b290440b60789e058afba9f9a5) Thanks [@jnsdls](https://github.com/jnsdls)! - add `minimizeChain` and `configureChain` util functions
- [`500a0e6`](https://github.com/thirdweb-dev/js/commit/500a0e671b3feb01aedd2c34443b682d0934f389) Thanks [@jnsdls](https://github.com/jnsdls)! - add thirdweb rpc to all available chains
+36
View File
@@ -0,0 +1,36 @@
<p align="center">
<br />
<a href="https://thirdweb.com"><img src="https://github.com/thirdweb-dev/js/blob/main/packages/sdk/logo.svg?raw=true" width="200" alt=""/></a>
<br />
</p>
<h1 align="center">thirdweb chains</h1>
<p align="center">
<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 />
## 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.
+57
View File
@@ -0,0 +1,57 @@
export default {
"name": "Ethereum Mainnet",
"chain": "ETH",
"icon": {
"url": "ipfs://QmcxZHpyJa8T4i63xqjPYrZ6tKrt55tZJpbXcjSDKuKaf9/ethereum/512.png",
"height": 512,
"width": 512,
"format": "png",
"sizes": [
512,
256,
128,
64,
32,
16
]
},
"rpc": [
"https://ethereum.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://eth-mainnet.g.alchemy.com/v2/${ALCHEMY_API_KEY}",
"https://mainnet.infura.io/v3/${INFURA_API_KEY}",
"wss://mainnet.infura.io/ws/v3/${INFURA_API_KEY}",
"https://api.mycryptoapi.com/eth",
"https://cloudflare-eth.com"
],
"features": [
{
"name": "EIP1559"
},
{
"name": "EIP155"
}
],
"faucets": [],
"nativeCurrency": {
"name": "Ether",
"symbol": "ETH",
"decimals": 18
},
"infoURL": "https://ethereum.org",
"shortName": "eth",
"chainId": 1,
"networkId": 1,
"slip44": 60,
"ens": {
"registry": "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e"
},
"explorers": [
{
"name": "etherscan",
"url": "https://etherscan.io",
"standard": "EIP3091"
}
],
"testnet": false,
"slug": "ethereum"
} as const;
+43
View File
@@ -0,0 +1,43 @@
export default {
"name": "Optimism",
"chain": "ETH",
"rpc": [
"https://optimism.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://opt-mainnet.g.alchemy.com/v2/${ALCHEMY_API_KEY}",
"https://optimism-mainnet.infura.io/v3/${INFURA_API_KEY}",
"https://mainnet.optimism.io/"
],
"faucets": [],
"nativeCurrency": {
"name": "Ether",
"symbol": "ETH",
"decimals": 18
},
"infoURL": "https://optimism.io",
"shortName": "oeth",
"chainId": 10,
"networkId": 10,
"explorers": [
{
"name": "etherscan",
"url": "https://optimistic.etherscan.io",
"standard": "EIP3091"
}
],
"icon": {
"url": "ipfs://QmcxZHpyJa8T4i63xqjPYrZ6tKrt55tZJpbXcjSDKuKaf9/optimism/512.png",
"height": 512,
"width": 512,
"format": "png",
"sizes": [
512,
256,
128,
64,
32,
16
]
},
"testnet": false,
"slug": "optimism"
} as const;
+50
View File
@@ -0,0 +1,50 @@
export default {
"name": "Gnosis",
"chain": "GNO",
"icon": {
"url": "ipfs://bafybeidk4swpgdyqmpz6shd5onvpaujvwiwthrhypufnwr6xh3dausz2dm",
"width": 1800,
"height": 1800,
"format": "png"
},
"rpc": [
"https://gnosis.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc.gnosischain.com",
"https://rpc.ankr.com/gnosis",
"https://gnosischain-rpc.gateway.pokt.network",
"https://gnosis-mainnet.public.blastapi.io",
"wss://rpc.gnosischain.com/wss"
],
"faucets": [
"https://gnosisfaucet.com",
"https://faucet.gimlu.com/gnosis",
"https://stakely.io/faucet/gnosis-chain-xdai",
"https://faucet.prussia.dev/xdai"
],
"nativeCurrency": {
"name": "xDAI",
"symbol": "xDAI",
"decimals": 18
},
"infoURL": "https://docs.gnosischain.com",
"shortName": "gno",
"chainId": 100,
"networkId": 100,
"slip44": 700,
"explorers": [
{
"name": "gnosisscan",
"url": "https://gnosisscan.io",
"icon": "gnosisscan",
"standard": "EIP3091"
},
{
"name": "blockscout",
"url": "https://blockscout.com/xdai/mainnet",
"icon": "blockscout",
"standard": "EIP3091"
}
],
"testnet": false,
"slug": "gnosis"
} as const;
+31
View File
@@ -0,0 +1,31 @@
export default {
"name": "GTON Mainnet",
"chain": "GTON",
"rpc": [
"https://gton.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc.gton.network/"
],
"faucets": [],
"nativeCurrency": {
"name": "GCD",
"symbol": "GCD",
"decimals": 18
},
"infoURL": "https://gton.capital",
"shortName": "gton",
"chainId": 1000,
"networkId": 1000,
"explorers": [
{
"name": "GTON Network Explorer",
"url": "https://explorer.gton.network",
"standard": "EIP3091"
}
],
"parent": {
"type": "L2",
"chain": "eip155-1"
},
"testnet": false,
"slug": "gton"
} as const;
+23
View File
@@ -0,0 +1,23 @@
export default {
"name": "Smart Bitcoin Cash",
"chain": "smartBCH",
"rpc": [
"https://smart-bitcoin-cash.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://smartbch.greyh.at",
"https://rpc-mainnet.smartbch.org",
"https://smartbch.fountainhead.cash/mainnet",
"https://smartbch.devops.cash/mainnet"
],
"faucets": [],
"nativeCurrency": {
"name": "Bitcoin Cash",
"symbol": "BCH",
"decimals": 18
},
"infoURL": "https://smartbch.org/",
"shortName": "smartbch",
"chainId": 10000,
"networkId": 10000,
"testnet": false,
"slug": "smart-bitcoin-cash"
} as const;
+20
View File
@@ -0,0 +1,20 @@
export default {
"name": "QuarkChain Mainnet Root",
"chain": "QuarkChain",
"rpc": [
"https://quarkchain-root.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"http://jrpc.mainnet.quarkchain.io:38391"
],
"faucets": [],
"nativeCurrency": {
"name": "QKC",
"symbol": "QKC",
"decimals": 18
},
"infoURL": "https://www.quarkchain.io",
"shortName": "qkc-r",
"chainId": 100000,
"networkId": 100000,
"testnet": false,
"slug": "quarkchain-root"
} as const;
+32
View File
@@ -0,0 +1,32 @@
export default {
"name": "QuarkChain Mainnet Shard 0",
"chain": "QuarkChain",
"rpc": [
"https://quarkchain-shard-0.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://mainnet-s0-ethapi.quarkchain.io",
"http://eth-jrpc.mainnet.quarkchain.io:39000"
],
"faucets": [],
"nativeCurrency": {
"name": "QKC",
"symbol": "QKC",
"decimals": 18
},
"infoURL": "https://www.quarkchain.io",
"shortName": "qkc-s0",
"chainId": 100001,
"networkId": 100001,
"parent": {
"chain": "eip155-100000",
"type": "shard"
},
"explorers": [
{
"name": "quarkchain-mainnet",
"url": "https://mainnet.quarkchain.io/0",
"standard": "EIP3091"
}
],
"testnet": false,
"slug": "quarkchain-shard-0"
} as const;
+32
View File
@@ -0,0 +1,32 @@
export default {
"name": "QuarkChain Mainnet Shard 1",
"chain": "QuarkChain",
"rpc": [
"https://quarkchain-shard-1.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://mainnet-s1-ethapi.quarkchain.io",
"http://eth-jrpc.mainnet.quarkchain.io:39001"
],
"faucets": [],
"nativeCurrency": {
"name": "QKC",
"symbol": "QKC",
"decimals": 18
},
"infoURL": "https://www.quarkchain.io",
"shortName": "qkc-s1",
"chainId": 100002,
"networkId": 100002,
"parent": {
"chain": "eip155-100000",
"type": "shard"
},
"explorers": [
{
"name": "quarkchain-mainnet",
"url": "https://mainnet.quarkchain.io/1",
"standard": "EIP3091"
}
],
"testnet": false,
"slug": "quarkchain-shard-1"
} as const;
+32
View File
@@ -0,0 +1,32 @@
export default {
"name": "QuarkChain Mainnet Shard 2",
"chain": "QuarkChain",
"rpc": [
"https://quarkchain-shard-2.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://mainnet-s2-ethapi.quarkchain.io",
"http://eth-jrpc.mainnet.quarkchain.io:39002"
],
"faucets": [],
"nativeCurrency": {
"name": "QKC",
"symbol": "QKC",
"decimals": 18
},
"infoURL": "https://www.quarkchain.io",
"shortName": "qkc-s2",
"chainId": 100003,
"networkId": 100003,
"parent": {
"chain": "eip155-100000",
"type": "shard"
},
"explorers": [
{
"name": "quarkchain-mainnet",
"url": "https://mainnet.quarkchain.io/2",
"standard": "EIP3091"
}
],
"testnet": false,
"slug": "quarkchain-shard-2"
} as const;
+32
View File
@@ -0,0 +1,32 @@
export default {
"name": "QuarkChain Mainnet Shard 3",
"chain": "QuarkChain",
"rpc": [
"https://quarkchain-shard-3.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://mainnet-s3-ethapi.quarkchain.io",
"http://eth-jrpc.mainnet.quarkchain.io:39003"
],
"faucets": [],
"nativeCurrency": {
"name": "QKC",
"symbol": "QKC",
"decimals": 18
},
"infoURL": "https://www.quarkchain.io",
"shortName": "qkc-s3",
"chainId": 100004,
"networkId": 100004,
"parent": {
"chain": "eip155-100000",
"type": "shard"
},
"explorers": [
{
"name": "quarkchain-mainnet",
"url": "https://mainnet.quarkchain.io/3",
"standard": "EIP3091"
}
],
"testnet": false,
"slug": "quarkchain-shard-3"
} as const;
+32
View File
@@ -0,0 +1,32 @@
export default {
"name": "QuarkChain Mainnet Shard 4",
"chain": "QuarkChain",
"rpc": [
"https://quarkchain-shard-4.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://mainnet-s4-ethapi.quarkchain.io",
"http://eth-jrpc.mainnet.quarkchain.io:39004"
],
"faucets": [],
"nativeCurrency": {
"name": "QKC",
"symbol": "QKC",
"decimals": 18
},
"infoURL": "https://www.quarkchain.io",
"shortName": "qkc-s4",
"chainId": 100005,
"networkId": 100005,
"parent": {
"chain": "eip155-100000",
"type": "shard"
},
"explorers": [
{
"name": "quarkchain-mainnet",
"url": "https://mainnet.quarkchain.io/4",
"standard": "EIP3091"
}
],
"testnet": false,
"slug": "quarkchain-shard-4"
} as const;
+32
View File
@@ -0,0 +1,32 @@
export default {
"name": "QuarkChain Mainnet Shard 5",
"chain": "QuarkChain",
"rpc": [
"https://quarkchain-shard-5.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://mainnet-s5-ethapi.quarkchain.io",
"http://eth-jrpc.mainnet.quarkchain.io:39005"
],
"faucets": [],
"nativeCurrency": {
"name": "QKC",
"symbol": "QKC",
"decimals": 18
},
"infoURL": "https://www.quarkchain.io",
"shortName": "qkc-s5",
"chainId": 100006,
"networkId": 100006,
"parent": {
"chain": "eip155-100000",
"type": "shard"
},
"explorers": [
{
"name": "quarkchain-mainnet",
"url": "https://mainnet.quarkchain.io/5",
"standard": "EIP3091"
}
],
"testnet": false,
"slug": "quarkchain-shard-5"
} as const;
+32
View File
@@ -0,0 +1,32 @@
export default {
"name": "QuarkChain Mainnet Shard 6",
"chain": "QuarkChain",
"rpc": [
"https://quarkchain-shard-6.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://mainnet-s6-ethapi.quarkchain.io",
"http://eth-jrpc.mainnet.quarkchain.io:39006"
],
"faucets": [],
"nativeCurrency": {
"name": "QKC",
"symbol": "QKC",
"decimals": 18
},
"infoURL": "https://www.quarkchain.io",
"shortName": "qkc-s6",
"chainId": 100007,
"networkId": 100007,
"parent": {
"chain": "eip155-100000",
"type": "shard"
},
"explorers": [
{
"name": "quarkchain-mainnet",
"url": "https://mainnet.quarkchain.io/6",
"standard": "EIP3091"
}
],
"testnet": false,
"slug": "quarkchain-shard-6"
} as const;
+32
View File
@@ -0,0 +1,32 @@
export default {
"name": "QuarkChain Mainnet Shard 7",
"chain": "QuarkChain",
"rpc": [
"https://quarkchain-shard-7.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://mainnet-s7-ethapi.quarkchain.io",
"http://eth-jrpc.mainnet.quarkchain.io:39007"
],
"faucets": [],
"nativeCurrency": {
"name": "QKC",
"symbol": "QKC",
"decimals": 18
},
"infoURL": "https://www.quarkchain.io",
"shortName": "qkc-s7",
"chainId": 100008,
"networkId": 100008,
"parent": {
"chain": "eip155-100000",
"type": "shard"
},
"explorers": [
{
"name": "quarkchain-mainnet",
"url": "https://mainnet.quarkchain.io/7",
"standard": "EIP3091"
}
],
"testnet": false,
"slug": "quarkchain-shard-7"
} as const;
+29
View File
@@ -0,0 +1,29 @@
export default {
"name": "VeChain",
"chain": "VeChain",
"rpc": [],
"faucets": [],
"nativeCurrency": {
"name": "VeChain",
"symbol": "VET",
"decimals": 18
},
"infoURL": "https://vechain.org",
"shortName": "vechain",
"chainId": 100009,
"networkId": 100009,
"explorers": [
{
"name": "VeChain Stats",
"url": "https://vechainstats.com",
"standard": "none"
},
{
"name": "VeChain Explorer",
"url": "https://explore.vechain.org",
"standard": "none"
}
],
"testnet": false,
"slug": "vechain"
} as const;
+21
View File
@@ -0,0 +1,21 @@
export default {
"name": "Smart Bitcoin Cash Testnet",
"chain": "smartBCHTest",
"rpc": [
"https://smart-bitcoin-cash-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc-testnet.smartbch.org",
"https://smartbch.devops.cash/testnet"
],
"faucets": [],
"nativeCurrency": {
"name": "Bitcoin Cash Test Token",
"symbol": "BCHT",
"decimals": 18
},
"infoURL": "http://smartbch.org/",
"shortName": "smartbchtest",
"chainId": 10001,
"networkId": 10001,
"testnet": true,
"slug": "smart-bitcoin-cash-testnet"
} as const;
+26
View File
@@ -0,0 +1,26 @@
export default {
"name": "VeChain Testnet",
"chain": "VeChain",
"rpc": [],
"faucets": [
"https://faucet.vecha.in"
],
"nativeCurrency": {
"name": "VeChain",
"symbol": "VET",
"decimals": 18
},
"infoURL": "https://vechain.org",
"shortName": "vechain-testnet",
"chainId": 100010,
"networkId": 100010,
"explorers": [
{
"name": "VeChain Explorer",
"url": "https://explore-testnet.vechain.org",
"standard": "none"
}
],
"testnet": true,
"slug": "vechain-testnet"
} as const;
+22
View File
@@ -0,0 +1,22 @@
export default {
"name": "Klaytn Testnet Baobab",
"chain": "KLAY",
"rpc": [
"https://klaytn-testnet-baobab.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://api.baobab.klaytn.net:8651"
],
"faucets": [
"https://baobab.wallet.klaytn.com/access?next=faucet"
],
"nativeCurrency": {
"name": "KLAY",
"symbol": "KLAY",
"decimals": 18
},
"infoURL": "https://www.klaytn.com/",
"shortName": "Baobab",
"chainId": 1001,
"networkId": 1001,
"testnet": true,
"slug": "klaytn-testnet-baobab"
} as const;
+34
View File
@@ -0,0 +1,34 @@
export default {
"name": "Gon Chain",
"chain": "GonChain",
"icon": {
"url": "ipfs://QmPtiJGaApbW3ATZhPW3pKJpw3iGVrRGsZLWhrDKF9ZK18",
"width": 1024,
"height": 1024,
"format": "png"
},
"rpc": [
"https://gon-chain.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://node1.testnet.gaiaopen.network",
"http://database1.gaiaopen.network"
],
"faucets": [],
"nativeCurrency": {
"name": "Gon Token",
"symbol": "GT",
"decimals": 18
},
"infoURL": "",
"shortName": "gon",
"chainId": 10024,
"networkId": 10024,
"explorers": [
{
"name": "Gon Explorer",
"url": "https://gonscan.com",
"standard": "none"
}
],
"testnet": true,
"slug": "gon-chain"
} as const;
+35
View File
@@ -0,0 +1,35 @@
export default {
"name": "T-EKTA",
"title": "EKTA Testnet T-EKTA",
"chain": "T-EKTA",
"rpc": [
"https://t-ekta.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://test.ekta.io:8545"
],
"faucets": [],
"nativeCurrency": {
"name": "T-EKTA",
"symbol": "T-EKTA",
"decimals": 18
},
"infoURL": "https://www.ekta.io",
"shortName": "t-ekta",
"chainId": 1004,
"networkId": 1004,
"icon": {
"url": "ipfs://QmfMd564KUPK8eKZDwGCT71ZC2jMnUZqP6LCtLpup3rHH1",
"width": 2100,
"height": 2100,
"format": "png"
},
"explorers": [
{
"name": "test-ektascan",
"url": "https://test.ektascan.io",
"icon": "ekta",
"standard": "EIP3091"
}
],
"testnet": true,
"slug": "t-ekta"
} as const;
+31
View File
@@ -0,0 +1,31 @@
export default {
"name": "Plian Testnet Subchain 1",
"chain": "Plian",
"rpc": [
"https://plian-testnet-subchain-1.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://testnet.plian.io/child_test"
],
"faucets": [],
"nativeCurrency": {
"name": "Plian Token",
"symbol": "TPI",
"decimals": 18
},
"infoURL": "https://plian.org/",
"shortName": "plian-testnet-l2",
"chainId": 10067275,
"networkId": 10067275,
"explorers": [
{
"name": "piscan",
"url": "https://testnet.plian.org/child_test",
"standard": "EIP3091"
}
],
"parent": {
"chain": "eip155-16658437",
"type": "L2"
},
"testnet": true,
"slug": "plian-testnet-subchain-1"
} as const;
+20
View File
@@ -0,0 +1,20 @@
export default {
"name": "Newton Testnet",
"chain": "NEW",
"rpc": [
"https://newton-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc1.newchain.newtonproject.org"
],
"faucets": [],
"nativeCurrency": {
"name": "Newton",
"symbol": "NEW",
"decimals": 18
},
"infoURL": "https://www.newtonproject.org/",
"shortName": "tnew",
"chainId": 1007,
"networkId": 1007,
"testnet": true,
"slug": "newton-testnet"
} as const;
+34
View File
@@ -0,0 +1,34 @@
export default {
"name": "Eurus Mainnet",
"chain": "EUN",
"rpc": [
"https://eurus.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://mainnet.eurus.network/"
],
"faucets": [],
"nativeCurrency": {
"name": "Eurus",
"symbol": "EUN",
"decimals": 18
},
"infoURL": "https://eurus.network",
"shortName": "eun",
"chainId": 1008,
"networkId": 1008,
"icon": {
"url": "ipfs://QmaGd5L9jGPbfyGXBFhu9gjinWJ66YtNrXq8x6Q98Eep9e",
"width": 471,
"height": 471,
"format": "svg"
},
"explorers": [
{
"name": "eurusexplorer",
"url": "https://explorer.eurus.network",
"icon": "eurus",
"standard": "none"
}
],
"testnet": false,
"slug": "eurus"
} as const;
+20
View File
@@ -0,0 +1,20 @@
export default {
"name": "SJATSH",
"chain": "ETH",
"rpc": [
"https://sjatsh.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"http://geth.free.idcfengye.com"
],
"faucets": [],
"nativeCurrency": {
"name": "Ether",
"symbol": "ETH",
"decimals": 18
},
"infoURL": "https://sjis.me",
"shortName": "SJ",
"chainId": 10086,
"networkId": 10086,
"testnet": false,
"slug": "sjatsh"
} as const;
+21
View File
@@ -0,0 +1,21 @@
export default {
"name": "EtherInc",
"chain": "ETI",
"rpc": [
"https://etherinc.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://api.einc.io/jsonrpc/mainnet"
],
"faucets": [],
"nativeCurrency": {
"name": "EtherInc Ether",
"symbol": "ETI",
"decimals": 18
},
"infoURL": "https://einc.io",
"shortName": "eti",
"chainId": 101,
"networkId": 1,
"slip44": 464,
"testnet": false,
"slug": "etherinc"
} as const;
+21
View File
@@ -0,0 +1,21 @@
export default {
"name": "Evrice Network",
"chain": "EVC",
"rpc": [
"https://evrice-network.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://meta.evrice.com"
],
"faucets": [],
"nativeCurrency": {
"name": "Evrice",
"symbol": "EVC",
"decimals": 18
},
"infoURL": "https://evrice.com",
"shortName": "EVC",
"chainId": 1010,
"networkId": 1010,
"slip44": 1020,
"testnet": false,
"slug": "evrice-network"
} as const;
+22
View File
@@ -0,0 +1,22 @@
export default {
"name": "Blockchain Genesis Mainnet",
"chain": "GEN",
"rpc": [
"https://blockchain-genesis.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://eu.mainnet.xixoio.com",
"https://us.mainnet.xixoio.com",
"https://asia.mainnet.xixoio.com"
],
"faucets": [],
"nativeCurrency": {
"name": "GEN",
"symbol": "GEN",
"decimals": 18
},
"infoURL": "https://www.xixoio.com/",
"shortName": "GEN",
"chainId": 10101,
"networkId": 10101,
"testnet": false,
"slug": "blockchain-genesis"
} as const;
+35
View File
@@ -0,0 +1,35 @@
export default {
"name": "Soverun Testnet",
"chain": "SVRN",
"icon": {
"url": "ipfs://QmTYazUzgY9Nn2mCjWwFUSLy3dG6i2PvALpwCNQvx1zXyi",
"width": 1154,
"height": 1154,
"format": "png"
},
"rpc": [
"https://soverun-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://testnet-rpc.soverun.com"
],
"faucets": [
"https://faucet.soverun.com"
],
"nativeCurrency": {
"name": "Soverun",
"symbol": "SVRN",
"decimals": 18
},
"infoURL": "https://soverun.com",
"shortName": "SVRNt",
"chainId": 101010,
"networkId": 101010,
"explorers": [
{
"name": "Soverun",
"url": "https://testnet.soverun.com",
"standard": "EIP3091"
}
],
"testnet": true,
"slug": "soverun-testnet"
} as const;
+35
View File
@@ -0,0 +1,35 @@
export default {
"name": "Soverun Mainnet",
"chain": "SVRN",
"icon": {
"url": "ipfs://QmTYazUzgY9Nn2mCjWwFUSLy3dG6i2PvALpwCNQvx1zXyi",
"width": 1154,
"height": 1154,
"format": "png"
},
"rpc": [
"https://soverun.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://mainnet-rpc.soverun.com"
],
"faucets": [
"https://faucet.soverun.com"
],
"nativeCurrency": {
"name": "Soverun",
"symbol": "SVRN",
"decimals": 18
},
"infoURL": "https://soverun.com",
"shortName": "SVRNm",
"chainId": 10101010,
"networkId": 10101010,
"explorers": [
{
"name": "Soverun",
"url": "https://explorer.soverun.com",
"standard": "EIP3091"
}
],
"testnet": false,
"slug": "soverun"
} as const;
+20
View File
@@ -0,0 +1,20 @@
export default {
"name": "Newton",
"chain": "NEW",
"rpc": [
"https://newton.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://global.rpc.mainnet.newtonproject.org"
],
"faucets": [],
"nativeCurrency": {
"name": "Newton",
"symbol": "NEW",
"decimals": 18
},
"infoURL": "https://www.newtonproject.org/",
"shortName": "new",
"chainId": 1012,
"networkId": 1012,
"testnet": false,
"slug": "newton"
} as const;
+28
View File
@@ -0,0 +1,28 @@
export default {
"name": "Web3Games Testnet",
"chain": "Web3Games",
"icon": {
"url": "ipfs://QmUc57w3UTHiWapNW9oQb1dP57ymtdemTTbpvGkjVHBRCo",
"width": 192,
"height": 192,
"format": "png"
},
"rpc": [
"https://web3games-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://testnet-rpc-0.web3games.org/evm",
"https://testnet-rpc-1.web3games.org/evm",
"https://testnet-rpc-2.web3games.org/evm"
],
"faucets": [],
"nativeCurrency": {
"name": "Web3Games",
"symbol": "W3G",
"decimals": 18
},
"infoURL": "https://web3games.org/",
"shortName": "tw3g",
"chainId": 102,
"networkId": 102,
"testnet": true,
"slug": "web3games-testnet"
} as const;
+37
View File
@@ -0,0 +1,37 @@
export default {
"name": "Chiado Testnet",
"chain": "CHI",
"icon": {
"url": "ipfs://bafybeidk4swpgdyqmpz6shd5onvpaujvwiwthrhypufnwr6xh3dausz2dm",
"width": 1800,
"height": 1800,
"format": "png"
},
"rpc": [
"https://chiado-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc.chiadochain.net",
"https://rpc.eu-central-2.gateway.fm/v3/gnosis/archival/chiado"
],
"faucets": [
"https://gnosisfaucet.com"
],
"nativeCurrency": {
"name": "Chiado xDAI",
"symbol": "xDAI",
"decimals": 18
},
"infoURL": "https://docs.gnosischain.com",
"shortName": "chi",
"chainId": 10200,
"networkId": 10200,
"explorers": [
{
"name": "blockscout",
"url": "https://blockscout.chiadochain.net",
"icon": "blockscout",
"standard": "EIP3091"
}
],
"testnet": true,
"slug": "chiado-testnet"
} as const;
+17
View File
@@ -0,0 +1,17 @@
export default {
"name": "Sakura",
"chain": "Sakura",
"rpc": [],
"faucets": [],
"nativeCurrency": {
"name": "Sakura",
"symbol": "SKU",
"decimals": 18
},
"infoURL": "https://clover.finance/sakura",
"shortName": "sku",
"chainId": 1022,
"networkId": 1022,
"testnet": false,
"slug": "sakura"
} as const;
+17
View File
@@ -0,0 +1,17 @@
export default {
"name": "Clover Testnet",
"chain": "Clover",
"rpc": [],
"faucets": [],
"nativeCurrency": {
"name": "Clover",
"symbol": "CLV",
"decimals": 18
},
"infoURL": "https://clover.finance",
"shortName": "tclv",
"chainId": 1023,
"networkId": 1023,
"testnet": true,
"slug": "clover-testnet"
} as const;
+20
View File
@@ -0,0 +1,20 @@
export default {
"name": "CLV Parachain",
"chain": "CLV",
"rpc": [
"https://clv-parachain.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://api-para.clover.finance"
],
"faucets": [],
"nativeCurrency": {
"name": "CLV",
"symbol": "CLV",
"decimals": 18
},
"infoURL": "https://clv.org",
"shortName": "clv",
"chainId": 1024,
"networkId": 1024,
"testnet": false,
"slug": "clv-parachain"
} as const;
+27
View File
@@ -0,0 +1,27 @@
export default {
"name": "0XTade",
"chain": "0XTade Chain",
"rpc": [
"https://0xtade.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://node.0xtchain.com"
],
"faucets": [],
"nativeCurrency": {
"name": "0XT",
"symbol": "0XT",
"decimals": 18
},
"infoURL": "https://www.0xtrade.finance/",
"shortName": "0xt",
"chainId": 10248,
"networkId": 10248,
"explorers": [
{
"name": "0xtrade Scan",
"url": "https://www.0xtscan.com",
"standard": "none"
}
],
"testnet": false,
"slug": "0xtade"
} as const;
+27
View File
@@ -0,0 +1,27 @@
export default {
"name": "BitTorrent Chain Testnet",
"chain": "BTTC",
"rpc": [
"https://bittorrent-chain-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://testrpc.bittorrentchain.io/"
],
"faucets": [],
"nativeCurrency": {
"name": "BitTorrent",
"symbol": "BTT",
"decimals": 18
},
"infoURL": "https://bittorrentchain.io/",
"shortName": "tbtt",
"chainId": 1028,
"networkId": 1028,
"explorers": [
{
"name": "testbttcscan",
"url": "https://testscan.bittorrentchain.io",
"standard": "none"
}
],
"testnet": true,
"slug": "bittorrent-chain-testnet"
} as const;
+33
View File
@@ -0,0 +1,33 @@
export default {
"name": "Conflux eSpace",
"chain": "Conflux",
"rpc": [
"https://conflux-espace.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://evm.confluxrpc.com"
],
"faucets": [],
"nativeCurrency": {
"name": "CFX",
"symbol": "CFX",
"decimals": 18
},
"infoURL": "https://confluxnetwork.org",
"shortName": "cfx",
"chainId": 1030,
"networkId": 1030,
"icon": {
"url": "ipfs://bafkreifj7n24u2dslfijfihwqvpdeigt5aj3k3sxv6s35lv75sxsfr3ojy",
"width": 460,
"height": 576,
"format": "png"
},
"explorers": [
{
"name": "Conflux Scan",
"url": "https://evm.confluxscan.net",
"standard": "none"
}
],
"testnet": false,
"slug": "conflux-espace"
} as const;
+35
View File
@@ -0,0 +1,35 @@
export default {
"name": "Crystaleum",
"chain": "crystal",
"rpc": [
"https://crystaleum.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://evm.cryptocurrencydevs.org",
"https://rpc.crystaleum.org"
],
"faucets": [],
"nativeCurrency": {
"name": "CRFI",
"symbol": "◈",
"decimals": 18
},
"infoURL": "https://crystaleum.org",
"shortName": "CRFI",
"chainId": 103090,
"networkId": 1,
"icon": {
"url": "ipfs://Qmbry1Uc6HnXmqFNXW5dFJ7To8EezCCjNr4TqqvAyzXS4h",
"width": 150,
"height": 150,
"format": "png"
},
"explorers": [
{
"name": "blockscout",
"url": "https://scan.crystaleum.org",
"icon": "crystal",
"standard": "EIP3091"
}
],
"testnet": false,
"slug": "crystaleum"
} as const;
+27
View File
@@ -0,0 +1,27 @@
export default {
"name": "Proxy Network Testnet",
"chain": "Proxy Network",
"rpc": [
"https://proxy-network-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"http://128.199.94.183:8041"
],
"faucets": [],
"nativeCurrency": {
"name": "PRX",
"symbol": "PRX",
"decimals": 18
},
"infoURL": "https://theproxy.network",
"shortName": "prx",
"chainId": 1031,
"networkId": 1031,
"explorers": [
{
"name": "proxy network testnet",
"url": "http://testnet-explorer.theproxy.network",
"standard": "EIP3091"
}
],
"testnet": true,
"slug": "proxy-network-testnet"
} as const;
+36
View File
@@ -0,0 +1,36 @@
export default {
"name": "Bronos Testnet",
"chain": "Bronos",
"rpc": [
"https://bronos-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://evm-testnet.bronos.org"
],
"faucets": [
"https://faucet.bronos.org"
],
"nativeCurrency": {
"name": "tBRO",
"symbol": "tBRO",
"decimals": 18
},
"infoURL": "https://bronos.org",
"shortName": "bronos-testnet",
"chainId": 1038,
"networkId": 1038,
"icon": {
"url": "ipfs://bafybeifkgtmhnq4sxu6jn22i7ass7aih6ubodr77k6ygtu4tjbvpmkw2ga",
"width": 500,
"height": 500,
"format": "png"
},
"explorers": [
{
"name": "Bronos Testnet Explorer",
"url": "https://tbroscan.bronos.org",
"standard": "none",
"icon": "bronos"
}
],
"testnet": true,
"slug": "bronos-testnet"
} as const;
+31
View File
@@ -0,0 +1,31 @@
export default {
"name": "Bronos Mainnet",
"chain": "Bronos",
"rpc": [],
"faucets": [],
"nativeCurrency": {
"name": "BRO",
"symbol": "BRO",
"decimals": 18
},
"infoURL": "https://bronos.org",
"shortName": "bronos-mainnet",
"chainId": 1039,
"networkId": 1039,
"icon": {
"url": "ipfs://bafybeifkgtmhnq4sxu6jn22i7ass7aih6ubodr77k6ygtu4tjbvpmkw2ga",
"width": 500,
"height": 500,
"format": "png"
},
"explorers": [
{
"name": "Bronos Explorer",
"url": "https://broscan.bronos.org",
"standard": "none",
"icon": "bronos"
}
],
"testnet": false,
"slug": "bronos"
} as const;
+34
View File
@@ -0,0 +1,34 @@
export default {
"name": "Kaiba Lightning Chain Testnet",
"chain": "tKLC",
"rpc": [
"https://kaiba-lightning-chain-testnet.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://klc.live/"
],
"faucets": [],
"nativeCurrency": {
"name": "Kaiba Testnet Token",
"symbol": "tKAIBA",
"decimals": 18
},
"infoURL": "https://kaibadefi.com",
"shortName": "tklc",
"chainId": 104,
"networkId": 104,
"icon": {
"url": "ipfs://bafybeihbsw3ky7yf6llpww6fabo4dicotcgwjpefscoxrppstjx25dvtea",
"width": 932,
"height": 932,
"format": "png"
},
"explorers": [
{
"name": "kaibascan",
"url": "https://kaibascan.io",
"icon": "kaibascan",
"standard": "EIP3091"
}
],
"testnet": true,
"slug": "kaiba-lightning-chain-testnet"
} as const;

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