Compare commits

..
Author SHA1 Message Date
Jonas DanielsGitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
b4df56f40f Version Packages (#2786)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-04-17 14:20:16 -07:00
Jonas DanielsandGitHub 4a6eed5d99 chore: update release-artifacts timeout (#2804) 2024-04-17 14:15:25 -07:00
Jonas DanielsandGitHub a54c745977 feat: Added new extensions for English Auctions (#2803) 2024-04-17 14:13:55 -07:00
Jonas DanielsandGitHub 0c95e80665 feat(marketplace): add more english auction extensions (#2794)
Signed-off-by: Jonas Daniels <[email protected]>
2024-04-17 13:28:45 -07:00
github-actions[bot]GitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
31b6a4ffe1 chore(chains): update chains (#2791)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-04-17 12:17:45 -07:00
Jonas DanielsandGitHub 4f2a3fb1f1 docs: Update terminology in useSendTransaction.tsx (#2800) 2024-04-17 12:16:39 -07:00
Jonas DanielsandGitHub 37bd0e42a5 fix(cli): fix spawn issue on windows (#2799) 2024-04-17 11:52:17 -07:00
Joaquim VergesandGitHub f5abbe8b54 feat: Add deployPublishedContract deploy extension (#2788) 2024-04-17 18:12:27 +00:00
Jonas DanielsandGitHub b1d9e4aa97 chore: Remove unused code from LocalWallet (#2798) 2024-04-17 17:35:32 +00:00
EimanandGitHub 5398d6813e fixed mintAdditionalSupplyTo example (#2796) 2024-04-17 09:39:53 -07:00
FirekeeperandGitHub bf0509e746 Unity 4.12 - Engine Relayer Support (#2792) 2024-04-17 15:53:00 +00:00
Joaquim VergesandGitHub 7c178923f9 fix: claim with price and no allowlists (#2795) 2024-04-17 22:03:16 +12:00
300e4c8a51 feat: Integrate Buy Modal with useSendTransaction hook (#2767)
Signed-off-by: Manan Tank <[email protected]>
Co-authored-by: Jonas Daniels <[email protected]>
2024-04-16 15:14:44 -07:00
github-actions[bot]GitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
8cb8a74002 chore(chains): update chains (#2789)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-04-16 13:50:01 -07:00
Manan TankandGitHub dc7ea82f8a show email selection by default for in-app wallet in Connect UI (#2790) 2024-04-16 13:02:08 -07:00
github-actions[bot]GitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
8541709359 chore(chains): update chains (#2787)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-04-15 22:40:56 -07:00
github-actions[bot]GitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
76f93a4346 chore(chains): update chains (#2777)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-04-15 18:46:12 -07:00
Jonas DanielsandGitHub 4c7153c95d chore: update dependencies (#2785) 2024-04-15 18:45:47 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2fd9c92c49 build(deps): bump eslint-config-next from 13.4.12 to 14.2.1 (#2780)
Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-16 01:39:01 +00:00
Jonas DanielsandGitHub 2de2b69934 chore(tests): add test for gas cost for native token (#2783) 2024-04-15 15:27:37 -07:00
147 changed files with 3577 additions and 1845 deletions
-2
View File
@@ -74,7 +74,6 @@ jobs:
- name: Set up foundry
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly-440ec525deb00b4dca138794865c27d1e8ea4d01
cache: false
- run: pnpm test
@@ -115,7 +114,6 @@ jobs:
- name: Set up foundry
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly-440ec525deb00b4dca138794865c27d1e8ea4d01
cache: false
- name: Run benchmarks
+1 -1
View File
@@ -20,7 +20,7 @@ env:
jobs:
release-artifacts:
timeout-minutes: 15
timeout-minutes: 60
runs-on: ubuntu-latest-16
steps:
- name: Checkout branch
+7
View File
@@ -1,5 +1,12 @@
# @thirdweb-dev/auth
## 4.1.62
### Patch Changes
- Updated dependencies []:
- @thirdweb-dev/wallets@2.5.4
## 4.1.61
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/auth",
"version": "4.1.61",
"version": "4.1.62",
"main": "dist/thirdweb-dev-auth.cjs.js",
"module": "dist/thirdweb-dev-auth.esm.js",
"browser": {
+6
View File
@@ -1,5 +1,11 @@
# @thirdweb-dev/chains
## 0.1.95
### Patch Changes
- [#2777](https://github.com/thirdweb-dev/js/pull/2777) [`76f93a4`](https://github.com/thirdweb-dev/js/commit/76f93a4346bc7627a6b0e4e49d212e245ad91be0) Thanks [@github-actions](https://github.com/apps/github-actions)! - Synced Chains Package
## 0.1.94
### Patch Changes
+30
View File
@@ -0,0 +1,30 @@
import type { Chain } from "../src/types";
export default {
"chain": "Avalanche",
"chainId": 11881,
"explorers": [],
"faucets": [],
"features": [],
"icon": {
"url": "https://images.ctfassets.net/9bazykntljf6/62CceHSYsRS4D9fgDSkLRB/877cb8f26954e1743ff535fd7fdaf78f/avacloud-placeholder.svg",
"width": 256,
"height": 256,
"format": "svg"
},
"infoURL": "https://avacloud.io",
"name": "QaUser2353 Testnet",
"nativeCurrency": {
"name": "QaUser2353 Testnet Token",
"symbol": "ODB",
"decimals": 18
},
"networkId": 11881,
"redFlags": [],
"rpc": [
"https://11881.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://subnets.avax.network/defi-kingdoms/dfk-chain/rpc"
],
"shortName": "QaUser2353 Testnet",
"slug": "qauser2353-testnet",
"testnet": true
} as const satisfies Chain;
+20
View File
@@ -0,0 +1,20 @@
import type { Chain } from "../src/types";
export default {
"chain": "PLAY",
"chainId": 161212,
"explorers": [],
"faucets": [],
"infoURL": "https://www.playfi.ai/",
"name": "PlayFi Mainnet",
"nativeCurrency": {
"name": "Play",
"symbol": "PLAY",
"decimals": 18
},
"networkId": 161212,
"rpc": [],
"shortName": "playfi",
"slug": "playfi",
"status": "incubating",
"testnet": false
} as const satisfies Chain;
+38
View File
@@ -0,0 +1,38 @@
import type { Chain } from "../src/types";
export default {
"chain": "ETH",
"chainId": 1612127,
"explorers": [
{
"name": "PlayFi Block Explorer",
"url": "https://albireo-explorer.playfi.ai",
"standard": "EIP3091"
}
],
"faucets": [],
"infoURL": "https://www.playfi.ai/",
"name": "PlayFi Albireo Testnet",
"nativeCurrency": {
"name": "Ether",
"symbol": "ETH",
"decimals": 18
},
"networkId": 1612127,
"parent": {
"type": "L2",
"chain": "eip155-1",
"bridges": [
{
"url": "https://portal.playfi.ai/bridge"
}
]
},
"rpc": [
"https://1612127.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://albireo-rpc.playfi.ai"
],
"shortName": "alberio",
"slip44": 1,
"slug": "playfi-albireo-testnet",
"testnet": true
} as const satisfies Chain;
+5 -2
View File
@@ -5,7 +5,7 @@ export default {
"explorers": [
{
"name": "Titan Explorer",
"url": "https://titan-explorer-light.titanlab.io/Titan",
"url": "https://tkxscan.io/Titan",
"standard": "none",
"icon": {
"url": "ipfs://bafkreicyvc7t55zsejv6vwaxbmhvea5vdfkkbgqkmn65rhyyifpg3mq3ua",
@@ -32,7 +32,10 @@ export default {
"networkId": 18888,
"rpc": [
"https://18888.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://titan-json-rpc.titanlab.io"
"https://titan-json-rpc.titanlab.io",
"https://titan-json-rpc-tokyo.titanlab.io",
"https://titan-json-rpc-seoul.titanlab.io",
"https://titan-json-rpc-hongkong.titanlab.io"
],
"shortName": "titan_tkx",
"slip44": 1,
+1 -1
View File
@@ -26,6 +26,6 @@ export default {
],
"shortName": "okb",
"slug": "x-layer",
"status": "incubating",
"status": "active",
"testnet": false
} as const satisfies Chain;
+35
View File
@@ -0,0 +1,35 @@
import type { Chain } from "../src/types";
export default {
"chain": "VANAR",
"chainId": 2040,
"explorers": [],
"faucets": [],
"features": [
{
"name": "EIP155"
}
],
"icon": {
"url": "ipfs://Qmbx25iq4Vn4zLooPit9bbguXJzdiogwtVQWtSseyQPuSC",
"width": 1000,
"height": 1628,
"format": "png"
},
"infoURL": "https://vanarchain.com",
"name": "Vanar Mainnet",
"nativeCurrency": {
"name": "VANRY",
"symbol": "VANRY",
"decimals": 18
},
"networkId": 2040,
"rpc": [
"https://2040.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc.vanarchain.com",
"wss://ws.vanarchain.com"
],
"shortName": "Vanar",
"slug": "vanar",
"testnet": false,
"title": "Vanarchain"
} as const satisfies Chain;
+17 -3
View File
@@ -2,9 +2,22 @@ import type { Chain } from "../src/types";
export default {
"chain": "Avalanche",
"chainId": 2121,
"explorers": [],
"explorers": [
{
"name": "catenascan",
"url": "https://catenascan.com",
"standard": "EIP3091"
}
],
"faucets": [],
"features": [],
"features": [
{
"name": "EIP155"
},
{
"name": "EIP1559"
}
],
"icon": {
"url": "https://images.ctfassets.net/9bazykntljf6/62CceHSYsRS4D9fgDSkLRB/877cb8f26954e1743ff535fd7fdaf78f/avacloud-placeholder.svg",
"width": 256,
@@ -22,7 +35,8 @@ export default {
"redFlags": [],
"rpc": [
"https://2121.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://subnets.avacloud-dev.io/cb82eb40-2d0d-4188-905b-d50c4b09b40b"
"https://subnets.avacloud-dev.io/cb82eb40-2d0d-4188-905b-d50c4b09b40b",
"https://rpc1.catenarpc.com"
],
"shortName": "M TEST 1103-2",
"slug": "m-test-1103-2",
+40
View File
@@ -0,0 +1,40 @@
import type { Chain } from "../src/types";
export default {
"chain": "B2",
"chainId": 213,
"explorers": [
{
"name": "B2 Hub Mainnet Explorer",
"url": "https://hub-explorer.bsquared.network",
"standard": "EIP3091",
"icon": {
"url": "ipfs://QmPV6ASrQDEkEW3g3ni7p2rJMPeciRLpEpvrAc1QfzVkx9",
"width": 640,
"height": 640,
"format": "png"
}
}
],
"faucets": [],
"icon": {
"url": "ipfs://QmPV6ASrQDEkEW3g3ni7p2rJMPeciRLpEpvrAc1QfzVkx9",
"width": 640,
"height": 640,
"format": "png"
},
"infoURL": "https://www.bsquared.network",
"name": "B2 Hub Mainnet",
"nativeCurrency": {
"name": "BSquared Token",
"symbol": "B2",
"decimals": 18
},
"networkId": 213,
"rpc": [
"https://213.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://hub-rpc.bsquared.network"
],
"shortName": "B2Hub-mainnet",
"slug": "b2-hub",
"testnet": false
} as const satisfies Chain;
+29
View File
@@ -0,0 +1,29 @@
import type { Chain } from "../src/types";
export default {
"chain": "BIGSB Testnet",
"chainId": 2136,
"explorers": [
{
"name": "Polkadot.js",
"url": "https://polkadot.js.org/apps/?rpc=wss://test-market.bigsb.network#/explorer",
"standard": "none"
}
],
"faucets": [],
"infoURL": "https://bigshortbets.com/",
"name": "BigShortBets Testnet",
"nativeCurrency": {
"name": "Dolarz",
"symbol": "Dolarz",
"decimals": 18
},
"networkId": 2136,
"rpc": [
"https://2136.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://test-market.bigsb.io",
"wss://test-market.bigsb.io"
],
"shortName": "bigsb_testnet",
"slug": "bigshortbets-testnet",
"testnet": true
} as const satisfies Chain;
+51
View File
@@ -0,0 +1,51 @@
import type { Chain } from "../src/types";
export default {
"chain": "B2",
"chainId": 223,
"explorers": [
{
"name": "blockscout",
"url": "https://explorer.bsquared.network",
"standard": "EIP3091",
"icon": {
"url": "ipfs://QmPV6ASrQDEkEW3g3ni7p2rJMPeciRLpEpvrAc1QfzVkx9",
"width": 640,
"height": 640,
"format": "png"
}
}
],
"faucets": [],
"icon": {
"url": "ipfs://QmPV6ASrQDEkEW3g3ni7p2rJMPeciRLpEpvrAc1QfzVkx9",
"width": 640,
"height": 640,
"format": "png"
},
"infoURL": "https://www.bsquared.network",
"name": "B2 Mainnet",
"nativeCurrency": {
"name": "Bitcoin",
"symbol": "BTC",
"decimals": 18
},
"networkId": 223,
"parent": {
"type": "L2",
"chain": "eip155-213",
"bridges": [
{
"url": "https://www.bsquared.network/bridge"
}
]
},
"rpc": [
"https://223.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc.bsquared.network",
"https://b2-mainnet.alt.technology"
],
"shortName": "B2-mainnet",
"slug": "b2",
"testnet": false,
"title": "B2 Mainnet"
} as const satisfies Chain;
+6
View File
@@ -12,6 +12,12 @@ export default {
"faucets": [
"https://faucet.opside.network"
],
"icon": {
"url": "ipfs://QmeCyZeibUoHNoYGzy1GkzH2uhxyRHKvH51PdaUMer4VTo",
"width": 591,
"height": 591,
"format": "png"
},
"infoURL": "https://opside.network",
"name": "Opside Testnet",
"nativeCurrency": {
+2 -3
View File
@@ -5,7 +5,7 @@ export default {
"explorers": [
{
"name": "Atleta Testnet Explorer",
"url": "http://185.234.69.18/?rpc=wss%3A%2F%2Fatleta-testnet-rpc.quark.blue%3A9944#/explorer",
"url": "https://polkadot-explorer.atleta.network/#/explorer",
"standard": "none",
"icon": {
"url": "ipfs://QmV2JVr4FCcb6aRiUoA3wS5erLoxtLBLonQ1Nvz8fNuEcR",
@@ -33,8 +33,7 @@ export default {
},
"networkId": 2340,
"rpc": [
"https://2340.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://atleta-testnet-rpc.quark.blue:9944"
"wss://testnet-rpc.atleta.network:9944"
],
"shortName": "atla",
"slip44": 1,
+42
View File
@@ -0,0 +1,42 @@
import type { Chain } from "../src/types";
export default {
"chain": "KLAOS Nova",
"chainId": 27181,
"explorers": [
{
"name": "blockscout",
"url": "https://blockscout.klaosnova.laosfoundation.io",
"standard": "EIP3091",
"icon": {
"url": "ipfs://QmW26eoxJeyUfikZ4DUT1Gfk78sBkvydEo8QzHa1BXjUUL",
"width": 580,
"height": 580,
"format": "png"
}
}
],
"faucets": [],
"icon": {
"url": "ipfs://QmW26eoxJeyUfikZ4DUT1Gfk78sBkvydEo8QzHa1BXjUUL",
"width": 580,
"height": 580,
"format": "png"
},
"infoURL": "https://www.laosfoundation.io/",
"name": "KLAOS Nova",
"nativeCurrency": {
"name": "KLAOS",
"symbol": "KLAOS",
"decimals": 18
},
"networkId": 27181,
"rpc": [
"https://27181.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc.klaosnova.laosfoundation.io",
"wss://rpc.klaosnova.laosfoundation.io"
],
"shortName": "klaosnova",
"slug": "klaos-nova",
"testnet": true,
"title": "KLAOS Nova Test Chain"
} as const satisfies Chain;
+25 -3
View File
@@ -2,9 +2,28 @@ import type { Chain } from "../src/types";
export default {
"chain": "XR Sepolia",
"chainId": 2730,
"explorers": [],
"explorers": [
{
"name": "XR Sepolia Explorer",
"url": "https://xr-sepolia-testnet.explorer.caldera.xyz",
"standard": "EIP3091",
"icon": {
"url": "ipfs://QmYtUimyqHkkFxYdbXXRbUqNg2VLPUg6Uu2C2nmFWowiZM",
"width": 551,
"height": 540,
"format": "png"
}
}
],
"faucets": [],
"features": [],
"features": [
{
"name": "EIP155"
},
{
"name": "EIP1559"
}
],
"icon": {
"url": "ipfs://QmRdBsZF2sgWitedT5qAtBZwrYwY1xecHN9u5fgddqA1eL/xr-sepolia.png",
"width": 300,
@@ -27,9 +46,12 @@ export default {
"redFlags": [],
"rpc": [
"https://2730.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://xr-sepolia-testnet.rpc.caldera.xyz/infra-partner-http"
"https://xr-sepolia-testnet.rpc.caldera.xyz/infra-partner-http",
"https://xr-sepolia-testnet.rpc.caldera.xyz/http"
],
"shortName": "xr-sepolia",
"slip44": 60,
"slug": "xr-sepolia",
"status": "active",
"testnet": true
} as const satisfies Chain;
+30
View File
@@ -0,0 +1,30 @@
import type { Chain } from "../src/types";
export default {
"chain": "Avalanche",
"chainId": 313310,
"explorers": [],
"faucets": [],
"features": [],
"icon": {
"url": "https://images.ctfassets.net/9bazykntljf6/62CceHSYsRS4D9fgDSkLRB/877cb8f26954e1743ff535fd7fdaf78f/avacloud-placeholder.svg",
"width": 256,
"height": 256,
"format": "svg"
},
"infoURL": "https://avacloud.io",
"name": "LT10",
"nativeCurrency": {
"name": "LT10 Token",
"symbol": "LT",
"decimals": 18
},
"networkId": 313310,
"redFlags": [],
"rpc": [
"https://313310.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://subnets.avax.network/lt10/testnet/rpc"
],
"shortName": "LT10",
"slug": "lt10",
"testnet": true
} as const satisfies Chain;
+30
View File
@@ -0,0 +1,30 @@
import type { Chain } from "../src/types";
export default {
"chain": "Avalanche",
"chainId": 31338,
"explorers": [],
"faucets": [],
"features": [],
"icon": {
"url": "https://images.ctfassets.net/9bazykntljf6/62CceHSYsRS4D9fgDSkLRB/877cb8f26954e1743ff535fd7fdaf78f/avacloud-placeholder.svg",
"width": 256,
"height": 256,
"format": "svg"
},
"infoURL": "https://avacloud.io",
"name": "LT8 Testnet",
"nativeCurrency": {
"name": "LT8 Testnet Token",
"symbol": "LT",
"decimals": 18
},
"networkId": 31338,
"redFlags": [],
"rpc": [
"https://31338.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://subnets.avax.network/lt8/testnet/rpc"
],
"shortName": "LT8 Testnet",
"slug": "lt8-testnet",
"testnet": true
} as const satisfies Chain;
+30
View File
@@ -0,0 +1,30 @@
import type { Chain } from "../src/types";
export default {
"chain": "Avalanche",
"chainId": 31339,
"explorers": [],
"faucets": [],
"features": [],
"icon": {
"url": "https://images.ctfassets.net/9bazykntljf6/62CceHSYsRS4D9fgDSkLRB/877cb8f26954e1743ff535fd7fdaf78f/avacloud-placeholder.svg",
"width": 256,
"height": 256,
"format": "svg"
},
"infoURL": "https://avacloud.io",
"name": "LT9",
"nativeCurrency": {
"name": "LT9 Token",
"symbol": "LT",
"decimals": 18
},
"networkId": 31339,
"redFlags": [],
"rpc": [
"https://31339.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://subnets.avax.network/lt9/testnet/rpc"
],
"shortName": "LT9",
"slug": "lt9",
"testnet": true
} as const satisfies Chain;
+47
View File
@@ -0,0 +1,47 @@
import type { Chain } from "../src/types";
export default {
"chain": "UPchain",
"chainId": 336655,
"explorers": [
{
"name": "UPchain Testnet Explorer",
"url": "https://explorer-testnet.uniport.network",
"standard": "EIP3091",
"icon": {
"url": "ipfs://QmNMqcPyQnaaFfUDsmsnu2T6agZfoWij3zFYebCNUPkfAH",
"width": 320,
"height": 320,
"format": "jpg"
}
}
],
"faucets": [
"https://faucet-testnet.uniport.network"
],
"features": [
{
"name": "EIP155"
}
],
"icon": {
"url": "ipfs://QmNMqcPyQnaaFfUDsmsnu2T6agZfoWij3zFYebCNUPkfAH",
"width": 320,
"height": 320,
"format": "jpg"
},
"infoURL": "https://uniport.network",
"name": "UPchain Testnet",
"nativeCurrency": {
"name": "UBTC",
"symbol": "UBTC",
"decimals": 18
},
"networkId": 336655,
"rpc": [
"https://336655.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc-testnet.uniport.network"
],
"shortName": "UPchain-testnet",
"slug": "upchain-testnet",
"testnet": true
} as const satisfies Chain;
+45
View File
@@ -0,0 +1,45 @@
import type { Chain } from "../src/types";
export default {
"chain": "UPchain",
"chainId": 336666,
"explorers": [
{
"name": "UPchain Mainnet Explorer",
"url": "https://explorer.uniport.network",
"standard": "EIP3091",
"icon": {
"url": "ipfs://QmNMqcPyQnaaFfUDsmsnu2T6agZfoWij3zFYebCNUPkfAH",
"width": 320,
"height": 320,
"format": "jpg"
}
}
],
"faucets": [],
"features": [
{
"name": "EIP155"
}
],
"icon": {
"url": "ipfs://QmNMqcPyQnaaFfUDsmsnu2T6agZfoWij3zFYebCNUPkfAH",
"width": 320,
"height": 320,
"format": "jpg"
},
"infoURL": "https://uniport.network",
"name": "UPchain Mainnet",
"nativeCurrency": {
"name": "UBTC",
"symbol": "UBTC",
"decimals": 18
},
"networkId": 336666,
"rpc": [
"https://336666.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc.uniport.network"
],
"shortName": "UPchain-mainnet",
"slug": "upchain",
"testnet": false
} as const satisfies Chain;
+6
View File
@@ -12,6 +12,12 @@ export default {
"faucets": [
"https://sepoliafaucet.com/"
],
"icon": {
"url": "ipfs://qmxhs7fvjanzwm14vjpbnmklre32gsiy9chsarrnbtfa1n",
"width": 1280,
"height": 1280,
"format": "png"
},
"infoURL": "https://docs.apexlayer.xyz/",
"name": "APEX Testnet",
"nativeCurrency": {
+40
View File
@@ -0,0 +1,40 @@
import type { Chain } from "../src/types";
export default {
"chain": "AIE",
"chainId": 413413,
"explorers": [
{
"name": "aiescan-testnet",
"url": "https://testnet.aiescan.io",
"standard": "none",
"icon": {
"url": "ipfs://bafkreihok46mhn5yf7b5jgmq7tiyw2fw76wklvj4frpc3gbswgfxzerhhm",
"width": 3481,
"height": 3500,
"format": "png"
}
}
],
"faucets": [],
"icon": {
"url": "ipfs://bafkreihok46mhn5yf7b5jgmq7tiyw2fw76wklvj4frpc3gbswgfxzerhhm",
"width": 3481,
"height": 3500,
"format": "png"
},
"infoURL": "https://testnet.aiescan.io",
"name": "AIE Testnet",
"nativeCurrency": {
"name": "AIE",
"symbol": "tAIE",
"decimals": 18
},
"networkId": 413413,
"rpc": [
"https://413413.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc1-testnet.aiechain.io"
],
"shortName": "aiet",
"slug": "aie-testnet",
"testnet": true
} as const satisfies Chain;
+30
View File
@@ -0,0 +1,30 @@
import type { Chain } from "../src/types";
export default {
"chain": "Avalanche",
"chainId": 48795,
"explorers": [],
"faucets": [],
"features": [],
"icon": {
"url": "https://images.ctfassets.net/9bazykntljf6/62CceHSYsRS4D9fgDSkLRB/877cb8f26954e1743ff535fd7fdaf78f/avacloud-placeholder.svg",
"width": 256,
"height": 256,
"format": "svg"
},
"infoURL": "https://avacloud.io",
"name": "Space",
"nativeCurrency": {
"name": "Space Token",
"symbol": "FUEL",
"decimals": 18
},
"networkId": 48795,
"redFlags": [],
"rpc": [
"https://48795.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://subnets.avax.network/space/testnet/rpc"
],
"shortName": "Space",
"slug": "space",
"testnet": true
} as const satisfies Chain;
+30
View File
@@ -0,0 +1,30 @@
import type { Chain } from "../src/types";
export default {
"chain": "Avalanche",
"chainId": 504441,
"explorers": [],
"faucets": [],
"features": [],
"icon": {
"url": "https://images.ctfassets.net/9bazykntljf6/62CceHSYsRS4D9fgDSkLRB/877cb8f26954e1743ff535fd7fdaf78f/avacloud-placeholder.svg",
"width": 256,
"height": 256,
"format": "svg"
},
"infoURL": "https://avacloud.io",
"name": "Playdapp Network",
"nativeCurrency": {
"name": "Playdapp Network Token",
"symbol": "PDA",
"decimals": 18
},
"networkId": 504441,
"redFlags": [],
"rpc": [
"https://504441.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://subnets.avax.network/playdappne/mainnet/rpc"
],
"shortName": "Playdapp Network",
"slug": "playdapp-network",
"testnet": false
} as const satisfies Chain;
+30
View File
@@ -0,0 +1,30 @@
import type { Chain } from "../src/types";
export default {
"chain": "Photon",
"chainId": 54555,
"explorers": [
{
"name": "photon_testnet_explorer",
"url": "https://testnet.photonchain.io",
"standard": "none"
}
],
"faucets": [
"https://photonchain.io/airdrop"
],
"infoURL": "https://photonchain.io",
"name": "Photon Testnet",
"nativeCurrency": {
"name": "Photon",
"symbol": "PTON",
"decimals": 18
},
"networkId": 54555,
"rpc": [
"https://54555.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc-test.photonchain.io"
],
"shortName": "pton",
"slug": "photon-testnet",
"testnet": true
} as const satisfies Chain;
+35
View File
@@ -0,0 +1,35 @@
import type { Chain } from "../src/types";
export default {
"chain": "ETH",
"chainId": 62050,
"explorers": [],
"faucets": [],
"features": [
{
"name": "EIP1559"
}
],
"icon": {
"url": "ipfs://bafkreid3xv3zkuo2cygwt7vwm5c2aqjbyhy5qxn7xkc66ajhu2mjh2ybki",
"width": 1000,
"height": 1000,
"format": "png"
},
"infoURL": "https://optopia.ai",
"name": "Optopia Mainnet",
"nativeCurrency": {
"name": "Ether",
"symbol": "ETH",
"decimals": 18
},
"networkId": 62050,
"parent": {
"type": "L2",
"chain": "eip155-1"
},
"rpc": [],
"shortName": "Optopia",
"slug": "optopia",
"status": "incubating",
"testnet": false
} as const satisfies Chain;
+40
View File
@@ -0,0 +1,40 @@
import type { Chain } from "../src/types";
export default {
"chain": "Safe(AnWang)",
"chainId": 6666665,
"explorers": [
{
"name": "Safe(AnWang) Explorer",
"url": "http://safe4.anwang.com",
"standard": "EIP3091",
"icon": {
"url": "ipfs://QmahJhdaLfGwBStQ9q9K4Mc73vLNqFV1otWCsT2ZKsMavv",
"width": 768,
"height": 768,
"format": "png"
}
}
],
"faucets": [],
"icon": {
"url": "ipfs://QmahJhdaLfGwBStQ9q9K4Mc73vLNqFV1otWCsT2ZKsMavv",
"width": 768,
"height": 768,
"format": "png"
},
"infoURL": "https://www.anwang.com",
"name": "Safe(AnWang) Mainnet",
"nativeCurrency": {
"name": "SAFE(AnWang)",
"symbol": "SAFE",
"decimals": 18
},
"networkId": 6666665,
"rpc": [
"https://6666665.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc.anwang.com"
],
"shortName": "SafeMainnet",
"slug": "safe-anwang",
"testnet": false
} as const satisfies Chain;
+40
View File
@@ -0,0 +1,40 @@
import type { Chain } from "../src/types";
export default {
"chain": "Safe(AnWang)",
"chainId": 6666666,
"explorers": [
{
"name": "Safe(AnWang) Testnet Explorer",
"url": "http://safe4-testnet.anwang.com",
"standard": "EIP3091",
"icon": {
"url": "ipfs://QmahJhdaLfGwBStQ9q9K4Mc73vLNqFV1otWCsT2ZKsMavv",
"width": 768,
"height": 768,
"format": "png"
}
}
],
"faucets": [],
"icon": {
"url": "ipfs://QmahJhdaLfGwBStQ9q9K4Mc73vLNqFV1otWCsT2ZKsMavv",
"width": 768,
"height": 768,
"format": "png"
},
"infoURL": "https://www.anwang.com",
"name": "Safe(AnWang) Testnet",
"nativeCurrency": {
"name": "SAFE(AnWang)",
"symbol": "SAFE",
"decimals": 18
},
"networkId": 6666666,
"rpc": [
"https://6666666.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc-testnet.anwang.com"
],
"shortName": "SafeTestnet",
"slug": "safe-anwang-testnet",
"testnet": true
} as const satisfies Chain;
+30
View File
@@ -0,0 +1,30 @@
import type { Chain } from "../src/types";
export default {
"chain": "Avalanche",
"chainId": 68688,
"explorers": [],
"faucets": [],
"features": [],
"icon": {
"url": "https://images.ctfassets.net/9bazykntljf6/62CceHSYsRS4D9fgDSkLRB/877cb8f26954e1743ff535fd7fdaf78f/avacloud-placeholder.svg",
"width": 256,
"height": 256,
"format": "svg"
},
"infoURL": "https://avacloud.io",
"name": "Haku Chain Testnet",
"nativeCurrency": {
"name": "Haku Chain Testnet Token",
"symbol": "HAKU",
"decimals": 18
},
"networkId": 68688,
"redFlags": [],
"rpc": [
"https://68688.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://subnets.avax.network/hakuchain/testnet/rpc"
],
"shortName": "Haku Chain Testnet",
"slug": "haku-chain-testnet",
"testnet": true
} as const satisfies Chain;
+6
View File
@@ -10,6 +10,12 @@ export default {
}
],
"faucets": [],
"icon": {
"url": "ipfs://QmPko9BJhR5FWTsThcwUFnnnjgLjrXVDm1n98dCuaQNW59",
"width": 506,
"height": 652,
"format": "png"
},
"infoURL": "https://bstchain.io",
"name": "BST Chain",
"nativeCurrency": {
+13 -1
View File
@@ -6,10 +6,22 @@ export default {
{
"name": "GuapcoinX Explorer",
"url": "http://explorer.guapcoinx.com",
"standard": "none"
"standard": "none",
"icon": {
"url": "ipfs://QmcDTR7982VQKDDz2Mh4fZbnE9hn67MuFPWQv1MimCqPvB",
"width": 800,
"height": 800,
"format": "png"
}
}
],
"faucets": [],
"icon": {
"url": "ipfs://QmcDTR7982VQKDDz2Mh4fZbnE9hn67MuFPWQv1MimCqPvB",
"width": 800,
"height": 800,
"format": "png"
},
"infoURL": "https://guapcoin.org/",
"name": "GuapcoinX",
"nativeCurrency": {
+30
View File
@@ -0,0 +1,30 @@
import type { Chain } from "../src/types";
export default {
"chain": "Avalanche",
"chainId": 73277,
"explorers": [],
"faucets": [],
"features": [],
"icon": {
"url": "https://images.ctfassets.net/9bazykntljf6/62CceHSYsRS4D9fgDSkLRB/877cb8f26954e1743ff535fd7fdaf78f/avacloud-placeholder.svg",
"width": 256,
"height": 256,
"format": "svg"
},
"infoURL": "https://avacloud.io",
"name": "QaUser9250 Testnet",
"nativeCurrency": {
"name": "QaUser9250 Testnet Token",
"symbol": "UDU",
"decimals": 18
},
"networkId": 73277,
"redFlags": [],
"rpc": [
"https://73277.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://subnets.avax.network/defi-kingdoms/dfk-chain/rpc"
],
"shortName": "QaUser9250 Testnet",
"slug": "qauser9250-testnet",
"testnet": true
} as const satisfies Chain;
+6
View File
@@ -10,6 +10,12 @@ export default {
}
],
"faucets": [],
"icon": {
"url": "ipfs://bafkreic6tcc6swh5kzljwqnswj6rlemcm7n6ra7xkgttwv5v3fv7ozj5zu",
"width": 1500,
"height": 1500,
"format": "png"
},
"infoURL": "https://miexs.com",
"name": "Miexs Smartchain",
"nativeCurrency": {
+30
View File
@@ -0,0 +1,30 @@
import type { Chain } from "../src/types";
export default {
"chain": "Avalanche",
"chainId": 77572,
"explorers": [],
"faucets": [],
"features": [],
"icon": {
"url": "https://images.ctfassets.net/9bazykntljf6/62CceHSYsRS4D9fgDSkLRB/877cb8f26954e1743ff535fd7fdaf78f/avacloud-placeholder.svg",
"width": 256,
"height": 256,
"format": "svg"
},
"infoURL": "https://avacloud.io",
"name": "QaUser0993 Testnet",
"nativeCurrency": {
"name": "QaUser0993 Testnet Token",
"symbol": "JOE",
"decimals": 18
},
"networkId": 77572,
"redFlags": [],
"rpc": [
"https://77572.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://subnets.avax.network/defi-kingdoms/dfk-chain/rpc"
],
"shortName": "QaUser0993 Testnet",
"slug": "qauser0993-testnet",
"testnet": true
} as const satisfies Chain;
+6
View File
@@ -12,6 +12,12 @@ export default {
"faucets": [
"https://faucet.vention.network"
],
"icon": {
"url": "ipfs://QmcNepHmbmHW1BZYM3MFqJW4awwhmDqhUPRXXmRnXwg1U4",
"width": 250,
"height": 250,
"format": "png"
},
"infoURL": "https://ventionscan.io",
"name": "Vention Smart Chain Mainnet",
"nativeCurrency": {
+1 -1
View File
@@ -33,7 +33,7 @@ export default {
"name": "Vanguard",
"nativeCurrency": {
"name": "Vanguard Vanry",
"symbol": "VG",
"symbol": "VANRY",
"decimals": 18
},
"networkId": 78600,
-1
View File
@@ -31,7 +31,6 @@ export default {
"rpc": [
"https://80002.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://rpc-amoy.polygon.technology",
"https://https://rpc-amoy.polygon.technology",
"https://polygon-amoy-bor-rpc.publicnode.com",
"wss://polygon-amoy-bor-rpc.publicnode.com"
],
+2 -1
View File
@@ -34,5 +34,6 @@ export default {
],
"shortName": "karak-sepolia",
"slug": "karak-sepolia",
"testnet": false
"testnet": true,
"title": "Karak Testnet Sepolia"
} as const satisfies Chain;
+30
View File
@@ -0,0 +1,30 @@
import type { Chain } from "../src/types";
export default {
"chain": "Avalanche",
"chainId": 90663,
"explorers": [],
"faucets": [],
"features": [],
"icon": {
"url": "https://images.ctfassets.net/9bazykntljf6/62CceHSYsRS4D9fgDSkLRB/877cb8f26954e1743ff535fd7fdaf78f/avacloud-placeholder.svg",
"width": 256,
"height": 256,
"format": "svg"
},
"infoURL": "https://avacloud.io",
"name": "QI0416s1 Testnet",
"nativeCurrency": {
"name": "QI0416s1 Testnet Token",
"symbol": "ZKE",
"decimals": 18
},
"networkId": 90663,
"redFlags": [],
"rpc": [
"https://90663.rpc.thirdweb.com/${THIRDWEB_API_KEY}",
"https://subnets.avax.network/defi-kingdoms/dfk-chain/rpc"
],
"shortName": "QI0416s1 Testnet",
"slug": "qi0416s1-testnet",
"testnet": true
} as const satisfies Chain;
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/chains",
"version": "0.1.94",
"version": "0.1.95",
"main": "dist/thirdweb-dev-chains.cjs.js",
"module": "dist/thirdweb-dev-chains.esm.js",
"exports": {
File diff suppressed because one or more lines are too long
+12
View File
@@ -1,5 +1,17 @@
# thirdweb
## 0.13.70
### Patch Changes
- [#2785](https://github.com/thirdweb-dev/js/pull/2785) [`4c7153c`](https://github.com/thirdweb-dev/js/commit/4c7153c95df1962d1e530a3d8227960cd87f6a61) Thanks [@jnsdls](https://github.com/jnsdls)! - update dependencies
- Updated dependencies [[`4c7153c`](https://github.com/thirdweb-dev/js/commit/4c7153c95df1962d1e530a3d8227960cd87f6a61), [`76f93a4`](https://github.com/thirdweb-dev/js/commit/76f93a4346bc7627a6b0e4e49d212e245ad91be0)]:
- @thirdweb-dev/sdk@4.0.64
- @thirdweb-dev/chains@0.1.95
- @thirdweb-dev/wallets@2.5.4
- @thirdweb-dev/auth@4.1.62
## 0.13.69
### Patch Changes
+2 -2
View File
@@ -1,7 +1,7 @@
{
"name": "@thirdweb-dev/cli",
"main": "dist/cli/index.js",
"version": "0.13.69",
"version": "0.13.70",
"repository": "https://github.com/thirdweb-dev/js/tree/main/legacy_packages/cli",
"author": "thirdweb eng <[email protected]>",
"license": "Apache-2.0",
@@ -16,7 +16,7 @@
"@types/cross-spawn": "^6.0.6",
"@types/inquirer": "^8.2.10",
"@types/js-yaml": "^4.0.9",
"@types/node": "20.12.5",
"@types/node": "20.12.7",
"@types/prompts": "^2.4.9",
"@types/tar": "^6.1.12",
"@types/update-notifier": "^6.0.8",
@@ -6,7 +6,7 @@
"dependencies": {
"@typescript-eslint/eslint-plugin": "7.5.0",
"@typescript-eslint/parser": "7.5.0",
"eslint-config-next": "13.4.12",
"eslint-config-next": "14.2.1",
"eslint-config-prettier": "9.1.0",
"eslint-config-turbo": "1.13.2",
"eslint-plugin-react": "7.34.1"
+10
View File
@@ -1,5 +1,15 @@
# @thirdweb-dev/react-core
## 4.6.3
### Patch Changes
- Updated dependencies [[`4c7153c`](https://github.com/thirdweb-dev/js/commit/4c7153c95df1962d1e530a3d8227960cd87f6a61), [`76f93a4`](https://github.com/thirdweb-dev/js/commit/76f93a4346bc7627a6b0e4e49d212e245ad91be0)]:
- @thirdweb-dev/sdk@4.0.64
- @thirdweb-dev/chains@0.1.95
- @thirdweb-dev/wallets@2.5.4
- @thirdweb-dev/auth@4.1.62
## 4.6.2
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/react-core",
"version": "4.6.2",
"version": "4.6.3",
"repository": "https://github.com/thirdweb-dev/js/tree/main/legacy_packages/react-core",
"author": "thirdweb eng <[email protected]>",
"license": "Apache-2.0",
@@ -1,5 +1,11 @@
# @thirdweb-dev/react-native-compat
## 0.7.35
### Patch Changes
- [#2785](https://github.com/thirdweb-dev/js/pull/2785) [`4c7153c`](https://github.com/thirdweb-dev/js/commit/4c7153c95df1962d1e530a3d8227960cd87f6a61) Thanks [@jnsdls](https://github.com/jnsdls)! - update dependencies
## 0.7.34
## 0.7.33
@@ -1,7 +1,7 @@
{
"name": "@thirdweb-dev/react-native-compat",
"description": "Shims for Thirdweb in React Native Projects",
"version": "0.7.34",
"version": "0.7.35",
"author": "thirdweb eng <[email protected]>",
"repository": "https://github.com/thirdweb-dev/js/tree/main/legacy_packages/react-native-compat",
"license": "Apache-2.0",
@@ -35,7 +35,7 @@
},
"devDependencies": {
"@thirdweb-dev/tsconfig": "workspace:*",
"@types/node": "20.12.5",
"@types/node": "20.12.7",
"babel-plugin-module-resolver": "^5.0.0",
"eslint-config-thirdweb": "workspace:*",
"ethers": "^5.7.2",
+10
View File
@@ -1,5 +1,15 @@
# @thirdweb-dev/react-native
## 0.7.35
### Patch Changes
- Updated dependencies [[`4c7153c`](https://github.com/thirdweb-dev/js/commit/4c7153c95df1962d1e530a3d8227960cd87f6a61), [`76f93a4`](https://github.com/thirdweb-dev/js/commit/76f93a4346bc7627a6b0e4e49d212e245ad91be0)]:
- @thirdweb-dev/sdk@4.0.64
- @thirdweb-dev/chains@0.1.95
- @thirdweb-dev/react-core@4.6.3
- @thirdweb-dev/wallets@2.5.4
## 0.7.34
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/react-native",
"version": "0.7.34",
"version": "0.7.35",
"repository": "https://github.com/thirdweb-dev/js/tree/main/legacy_packages/react-native",
"author": "thirdweb eng <[email protected]>",
"license": "Apache-2.0",
+12
View File
@@ -1,5 +1,17 @@
# @thirdweb-dev/react
## 4.6.3
### Patch Changes
- [#2790](https://github.com/thirdweb-dev/js/pull/2790) [`dc7ea82`](https://github.com/thirdweb-dev/js/commit/dc7ea82f8ab3d19dc66675e3df3de4cf0901229b) Thanks [@MananTank](https://github.com/MananTank)! - Show email by default and not phone number selection UI for in-app wallet in Connect UI
- Updated dependencies [[`4c7153c`](https://github.com/thirdweb-dev/js/commit/4c7153c95df1962d1e530a3d8227960cd87f6a61), [`76f93a4`](https://github.com/thirdweb-dev/js/commit/76f93a4346bc7627a6b0e4e49d212e245ad91be0)]:
- @thirdweb-dev/sdk@4.0.64
- @thirdweb-dev/chains@0.1.95
- @thirdweb-dev/react-core@4.6.3
- @thirdweb-dev/wallets@2.5.4
## 4.6.2
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/react",
"version": "4.6.2",
"version": "4.6.3",
"repository": "https://github.com/thirdweb-dev/js/tree/main/legacy_packages/react",
"author": "thirdweb eng <[email protected]>",
"license": "Apache-2.0",
@@ -23,8 +23,8 @@ import {
} from "./types";
const DEFAULT_AUTH_OPTIONS: AuthOption[] = [
"phone",
"email",
"phone",
"google",
"apple",
"facebook",
+10
View File
@@ -1,5 +1,15 @@
# @thirdweb-dev/sdk
## 4.0.64
### Patch Changes
- [#2785](https://github.com/thirdweb-dev/js/pull/2785) [`4c7153c`](https://github.com/thirdweb-dev/js/commit/4c7153c95df1962d1e530a3d8227960cd87f6a61) Thanks [@jnsdls](https://github.com/jnsdls)! - update dependencies
- Updated dependencies [[`7c17892`](https://github.com/thirdweb-dev/js/commit/7c178923f9072d8f43b0d23f3888fdedae540005), [`a54c745`](https://github.com/thirdweb-dev/js/commit/a54c745977e7806c0339633486eef55f92b02832), [`300e4c8`](https://github.com/thirdweb-dev/js/commit/300e4c8a51581156acdfac431655510f0cdbca21), [`f5abbe8`](https://github.com/thirdweb-dev/js/commit/f5abbe8b54fbd68188c40268ae5707c72f39441f), [`4c7153c`](https://github.com/thirdweb-dev/js/commit/4c7153c95df1962d1e530a3d8227960cd87f6a61), [`37bd0e4`](https://github.com/thirdweb-dev/js/commit/37bd0e42a58cdbe5b04a9871b5fd413ec293d96c), [`76f93a4`](https://github.com/thirdweb-dev/js/commit/76f93a4346bc7627a6b0e4e49d212e245ad91be0)]:
- thirdweb@5.7.0
- @thirdweb-dev/chains@0.1.95
## 4.0.63
### Patch Changes
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/sdk",
"version": "4.0.63",
"version": "4.0.64",
"description": "The main thirdweb SDK.",
"repository": "https://github.com/thirdweb-dev/js/tree/main/legacy_packages/sdk",
"license": "Apache-2.0",
@@ -89,7 +89,7 @@
"@types/chai": "^4.3.14",
"@types/deep-equal-in-any-order": "^1.0.3",
"@types/mocha": "^10.0.6",
"@types/node": "20.12.5",
"@types/node": "20.12.7",
"@types/uuid": "^9.0.8",
"chai": "^4.4.1",
"deep-equal-in-any-order": "^1.1.20",
@@ -1,5 +1,17 @@
# @thirdweb-dev/unity-js-bridge
## 0.6.13
### Patch Changes
- [#2792](https://github.com/thirdweb-dev/js/pull/2792) [`bf0509e`](https://github.com/thirdweb-dev/js/commit/bf0509e7466ab41bdcfe3acffee3ed3af38cb71e) Thanks [@0xFirekeeper](https://github.com/0xFirekeeper)! - Unity 4.12 - Engine Relayer Support
- Updated dependencies [[`4c7153c`](https://github.com/thirdweb-dev/js/commit/4c7153c95df1962d1e530a3d8227960cd87f6a61), [`76f93a4`](https://github.com/thirdweb-dev/js/commit/76f93a4346bc7627a6b0e4e49d212e245ad91be0)]:
- @thirdweb-dev/sdk@4.0.64
- @thirdweb-dev/chains@0.1.95
- @thirdweb-dev/wallets@2.5.4
- @thirdweb-dev/auth@4.1.62
## 0.6.12
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/unity-js-bridge",
"version": "0.6.12",
"version": "0.6.13",
"main": "dist/thirdweb-unity-bridge.js",
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/unity-js-bridge",
"license": "Apache-2.0",
@@ -171,7 +171,7 @@ class ThirdwebBridge implements TWBridge {
// biome-ignore lint/suspicious/noExplicitAny: TODO: fix use of any
(globalThis as any).X_SDK_PLATFORM = "unity";
// biome-ignore lint/suspicious/noExplicitAny: TODO: fix use of any
(globalThis as any).X_SDK_VERSION = "unity-4.11.0";
(globalThis as any).X_SDK_VERSION = "4.12.0";
// biome-ignore lint/suspicious/noExplicitAny: TODO: fix use of any
(globalThis as any).X_SDK_OS = browser?.os ?? "unknown";
}
+8
View File
@@ -1,5 +1,13 @@
# @thirdweb-dev/wallets
## 2.5.4
### Patch Changes
- Updated dependencies [[`4c7153c`](https://github.com/thirdweb-dev/js/commit/4c7153c95df1962d1e530a3d8227960cd87f6a61), [`76f93a4`](https://github.com/thirdweb-dev/js/commit/76f93a4346bc7627a6b0e4e49d212e245ad91be0)]:
- @thirdweb-dev/sdk@4.0.64
- @thirdweb-dev/chains@0.1.95
## 2.5.3
### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/wallets",
"version": "2.5.3",
"version": "2.5.4",
"main": "dist/thirdweb-dev-wallets.cjs.js",
"module": "dist/thirdweb-dev-wallets.esm.js",
"browser": {
+2 -2
View File
@@ -44,13 +44,13 @@
"@manypkg/cli": "0.21.3",
"@manypkg/get-packages": "2.2.1",
"@playwright/test": "1.31.2",
"@types/node": "20.12.5",
"@types/node": "20.12.7",
"turbo": "1.13.2",
"yalc": "1.0.0-pre.53"
},
"_______ALL_PACKAGE_DEV_DEPENDENCIES_GO_IN_HERE_SO_CONSUMERS_DONT_END_UP_INSTALLING_THEM______": "_______ALL_PACKAGE_DEV_DEPENDENCIES_GO_IN_HERE_SO_CONSUMERS_DONT_END_UP_INSTALLING_THEM______",
"devDependencies": {
"@biomejs/biome": "1.6.4",
"@biomejs/biome": "1.7.0",
"@codspeed/vitest-plugin": "3.1.0",
"@size-limit/preset-big-lib": "11.1.2",
"@types/bun": "1.0.12",
+6
View File
@@ -1,5 +1,11 @@
# @thirdweb-dev/service-utils
## 0.4.27
### Patch Changes
- [#2785](https://github.com/thirdweb-dev/js/pull/2785) [`4c7153c`](https://github.com/thirdweb-dev/js/commit/4c7153c95df1962d1e530a3d8227960cd87f6a61) Thanks [@jnsdls](https://github.com/jnsdls)! - update dependencies
## 0.4.26
### Patch Changes
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@thirdweb-dev/service-utils",
"version": "0.4.26",
"version": "0.4.27",
"main": "dist/thirdweb-dev-service-utils.cjs.js",
"module": "dist/thirdweb-dev-service-utils.esm.js",
"exports": {
@@ -46,7 +46,7 @@
"@cloudflare/workers-types": "4.20240405.0",
"@preconstruct/cli": "2.7.0",
"@thirdweb-dev/tsconfig": "workspace:*",
"@types/node": "20.12.5",
"@types/node": "20.12.7",
"typescript": "5.4.4"
},
"scripts": {
+44
View File
@@ -1,5 +1,49 @@
# thirdweb
## 5.7.0
### Minor Changes
- [#2803](https://github.com/thirdweb-dev/js/pull/2803) [`a54c745`](https://github.com/thirdweb-dev/js/commit/a54c745977e7806c0339633486eef55f92b02832) Thanks [@jnsdls](https://github.com/jnsdls)! - Added new extensions for "English Auctions" in `thirdweb/extensions/marketplace` module:
- `bidInAuction`
- `cancelAuction`
- `buyoutAuction`
- `collectAuctionPayout`
- `collectAuctionTokens`
- `executeSale`
- [#2767](https://github.com/thirdweb-dev/js/pull/2767) [`300e4c8`](https://github.com/thirdweb-dev/js/commit/300e4c8a51581156acdfac431655510f0cdbca21) Thanks [@MananTank](https://github.com/MananTank)! - Open "Pay Modal" UI when sending transaction using the `useSendTransaction` hook if the user does not have enough funds to execute the transaction to prompt the user to buy tokens
`useSendTransaction` now takes an optional `config` option to customize the "Pay Modal" UI
```tsx
const sendTransaction = useSendTransaction({
payModal: {
locale: "en_US",
theme: "light",
},
});
```
You may also explicitly disable the "Pay Modal" UI by setting the `payModal` option to `false`
```tsx
const sendTransaction = useSendTransaction({
payModal: false,
});
```
- [#2788](https://github.com/thirdweb-dev/js/pull/2788) [`f5abbe8`](https://github.com/thirdweb-dev/js/commit/f5abbe8b54fbd68188c40268ae5707c72f39441f) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Added `deployPublishedContract`
### Patch Changes
- [#2795](https://github.com/thirdweb-dev/js/pull/2795) [`7c17892`](https://github.com/thirdweb-dev/js/commit/7c178923f9072d8f43b0d23f3888fdedae540005) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Fix claiming drops with prices and no allowlists
- [#2785](https://github.com/thirdweb-dev/js/pull/2785) [`4c7153c`](https://github.com/thirdweb-dev/js/commit/4c7153c95df1962d1e530a3d8227960cd87f6a61) Thanks [@jnsdls](https://github.com/jnsdls)! - update dependencies
- [#2799](https://github.com/thirdweb-dev/js/pull/2799) [`37bd0e4`](https://github.com/thirdweb-dev/js/commit/37bd0e42a58cdbe5b04a9871b5fd413ec293d96c) Thanks [@jnsdls](https://github.com/jnsdls)! - fix `npx thirdweb` on windows when `thirdweb` is installed locally
## 5.6.0
### Minor Changes
@@ -1,15 +1,15 @@
import { run, bench, group } from "mitata";
import { bench, group, run } from "mitata";
import { prepareTransaction } from "../src/transaction/prepare-transaction";
import { createThirdwebClient } from "../src/client/client";
import { defineChain } from "../src/chains/utils";
import { privateKeyAccount } from "../src/wallets/private-key";
import { createThirdwebClient } from "../src/client/client";
import { sendTransaction } from "../src/transaction/actions/send-transaction";
import { prepareTransaction } from "../src/transaction/prepare-transaction";
import { privateKeyToAccount } from "../src/wallets/private-key";
import * as viem from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { mainnet } from "viem/chains";
import * as ethers from "ethers6";
import * as viem from "viem";
import { privateKeyToAccount as viemPrivateKeyToAccount } from "viem/accounts";
import { mainnet } from "viem/chains";
const LOCAL_RPC = "http://127.0.0.1:8545";
const VITALIK_WALLET = "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B";
@@ -27,13 +27,13 @@ const TEST_CHAIN = defineChain({
const PKEY =
"0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80";
const account = privateKeyAccount({
const account = privateKeyToAccount({
privateKey: PKEY,
client,
});
// viem setup
const privateKeyAccountViem = privateKeyToAccount(PKEY);
const privateKeyAccountViem = viemPrivateKeyToAccount(PKEY);
const walletClient = viem.createWalletClient({
account: privateKeyAccountViem,
transport: viem.http(LOCAL_RPC),
+6 -2
View File
@@ -1,6 +1,6 @@
{
"name": "thirdweb",
"version": "5.6.0",
"version": "5.7.0",
"repository": {
"type": "git",
"url": "git+https://github.com/thirdweb-dev/js.git#main"
@@ -192,7 +192,7 @@
"mipd": "0.0.7",
"node-libs-browser": "2.2.1",
"uqr": "0.1.2",
"viem": "2.9.16"
"viem": "2.9.18"
},
"peerDependencies": {
"ethers": "^5 || ^6",
@@ -234,5 +234,9 @@
},
"engines": {
"node": ">=18"
},
"devDependencies": {
"@types/cross-spawn": "^6.0.6",
"cross-spawn": "7.0.3"
}
}
@@ -3,10 +3,10 @@ import { describe, expect, test } from "vitest";
import { ANVIL_CHAIN } from "../../test/src/chains.js";
import { TEST_CLIENT } from "../../test/src/test-clients.js";
import { ANVIL_PKEY_A, TEST_ACCOUNT_B } from "../../test/src/test-wallets.js";
import { privateKeyAccount } from "../wallets/private-key.js";
import { privateKeyToAccount } from "../wallets/private-key.js";
import { toEthersSigner } from "./ethers5.js";
const account = privateKeyAccount({
const account = privateKeyToAccount({
privateKey: ANVIL_PKEY_A,
client: TEST_CLIENT,
});
@@ -2,10 +2,10 @@ import { describe, expect, test } from "vitest";
import { ANVIL_CHAIN } from "../../test/src/chains.js";
import { TEST_CLIENT } from "../../test/src/test-clients.js";
import { ANVIL_PKEY_A, TEST_ACCOUNT_B } from "../../test/src/test-wallets.js";
import { privateKeyAccount } from "../wallets/private-key.js";
import { privateKeyToAccount } from "../wallets/private-key.js";
import { ethers6Adapter } from "./ethers6.js";
const account = privateKeyAccount({
const account = privateKeyToAccount({
privateKey: ANVIL_PKEY_A,
client: TEST_CLIENT,
});
+2 -2
View File
@@ -4,10 +4,10 @@ import { ANVIL_PKEY_A } from "~test/test-wallets.js";
import { typedData } from "~test/typed-data.js";
import { ANVIL_CHAIN, FORKED_ETHEREUM_CHAIN } from "../../test/src/chains.js";
import { TEST_CLIENT } from "../../test/src/test-clients.js";
import { privateKeyAccount } from "../wallets/private-key.js";
import { privateKeyToAccount } from "../wallets/private-key.js";
import { viemAdapter } from "./viem.js";
const account = privateKeyAccount({
const account = privateKeyToAccount({
privateKey: ANVIL_PKEY_A,
client: TEST_CLIENT,
});
@@ -5,4 +5,9 @@ export const anvil = /* @__PURE__ */ defineChain({
name: "Anvil",
rpc: "http://localhost:8545",
testnet: true,
nativeCurrency: {
name: "Anvil Ether",
symbol: "ETH",
decimals: 18,
},
});
+10 -10
View File
@@ -1,6 +1,7 @@
#!/usr/bin/env node
import { execSync, spawn } from "node:child_process";
import { execSync } from "node:child_process";
import { spawn } from "cross-spawn";
import {
generate,
isValidChainIdAndContractAddress,
@@ -24,25 +25,24 @@ async function main() {
default: {
const isWindows = /^win/.test(process.platform);
let bunAvailable = false;
// bun has no windows support yet anyways
if (!isWindows) {
const isBunAvailable = (() => {
try {
const res = execSync("bun --version", {
stdio: "ignore",
encoding: "utf-8",
});
if (typeof res === "string" && res.indexOf(".") > -1) {
bunAvailable = true;
return true;
}
} catch {
bunAvailable = false;
}
}
} catch {}
return false;
})();
let runner = "npx";
switch (true) {
case bunAvailable:
case isBunAvailable:
runner = "bun";
break;
case isWindows:
@@ -185,10 +185,10 @@ export type ${uppercaseFirstLetter(f.name)}Params = {
* const transaction = ${f.name}(${
f.inputs.length > 0
? `{\n * ${f.inputs
.map(
(x, i) => ` ${removeLeadingUnderscore(x.name || `arg_${i}`)}: ...,`,
)
.join("\n * ")}\n * }`
.map(
(x, i) => ` ${removeLeadingUnderscore(x.name || `arg_${i}`)}: ...,`,
)
.join("\n * ")}\n * }`
: ""
});
*
@@ -243,10 +243,10 @@ export type ${uppercaseFirstLetter(f.name)}Params = {
* const result = await ${f.name}(${
f.inputs.length > 0
? `{\n * ${f.inputs
.map(
(x, i) => ` ${removeLeadingUnderscore(x.name || `arg_${i}`)}: ...,`,
)
.join("\n * ")}\n * }`
.map(
(x, i) => ` ${removeLeadingUnderscore(x.name || `arg_${i}`)}: ...,`,
)
.join("\n * ")}\n * }`
: ""
});
*
@@ -302,8 +302,8 @@ export type ${uppercaseFirstLetter(e.name)}EventFilters = Partial<{
* ${eventNameToPreparedEventName(e.name)}(${
indexedInputs.length > 0
? `{\n * ${indexedInputs
.map((x) => ` ${x.name}: ...,`)
.join("\n * ")}\n * }`
.map((x) => ` ${x.name}: ...,`)
.join("\n * ")}\n * }`
: ""
})
* ],
@@ -3,6 +3,7 @@ import type {
AbiParameter,
AbiParametersToPrimitiveTypes,
} from "abitype";
import { sendAndConfirmTransaction } from "../../transaction/actions/send-and-confirm-transaction.js";
import { prepareTransaction } from "../../transaction/prepare-transaction.js";
import { encodeAbiParameters } from "../../utils/abi/encodeAbiParameters.js";
import { ensureBytecodePrefix } from "../../utils/bytecode/prefix.js";
@@ -10,6 +11,7 @@ import { concatHex } from "../../utils/encoding/helpers/concat-hex.js";
import { type Hex, isHex } from "../../utils/encoding/hex.js";
import type { Prettify } from "../../utils/type-utils.js";
import type { ClientAndChain } from "../../utils/types.js";
import type { Account } from "../../wallets/interfaces/wallet.js";
export type PrepareDirectDeployTransactionOptions<
TConstructor extends AbiConstructor,
@@ -67,3 +69,42 @@ export function prepareDirectDeployTransaction<
]),
});
}
/**
* Deploy a contract on a given chain
* @param options - the deploy options
* @returns - a promise that resolves to the deployed contract address
* @example
* ```ts
* import { deployContract } from "thirdweb/deployContract";
*
* const address = await deployContract({
* client,
* chain,
* bytecode: "0x...",
* constructorAbi: {
* inputs: [{ type: "uint256", name: "value" }],
* type: "constructor",
* },
* constructorParams: [123],
* });
* ```
* @extension DEPLOY
*/
export async function deployContract<const TConstructor extends AbiConstructor>(
options: PrepareDirectDeployTransactionOptions<TConstructor> & {
account: Account;
},
) {
const deployTx = prepareDirectDeployTransaction(options);
const receipt = await sendAndConfirmTransaction({
account: options.account,
transaction: deployTx,
});
if (!receipt.contractAddress) {
throw new Error(
`Could not find deployed contract address in transaction: ${receipt.transactionHash}`,
);
}
return receipt.contractAddress;
}
+10
View File
@@ -19,5 +19,15 @@ export {
deployERC1155Contract,
} from "../extensions/prebuilts/deploy-erc1155.js";
export {
deployPublishedContract,
type DeployPublishedContractOptions,
} from "../extensions/prebuilts/deploy-published.js";
export { prepareDirectDeployTransaction } from "../contract/deployment/deploy-with-abi.js";
export { prepareAutoFactoryDeployTransaction } from "../contract/deployment/deploy-via-autofactory.js";
export { deployViaAutoFactory } from "../contract/deployment/deploy-via-autofactory.js";
export {
deployContract,
type PrepareDirectDeployTransactionOptions,
} from "../contract/deployment/deploy-with-abi.js";
@@ -108,12 +108,44 @@ export {
getAllValidAuctions,
type GetAllValidAuctionParams,
} from "../../extensions/marketplace/read/english-auction/getAllValidAuctions.js";
export {
getWinningBid,
type GetWinningBidParams,
} from "../../extensions/marketplace/read/english-auction/getWinningBid.js";
export {
isNewWinningBid,
type IsNewWinningBidParams,
} from "../../extensions/marketplace/__generated__/IEnglishAuctions/read/isNewWinningBid.js";
// WRITE
export {
createAuction,
type CreateAuctionParams,
} from "../../extensions/marketplace/write/english-auction/createAuction.js";
export {
bidInAuction,
type BidInAuctionParams,
} from "../../extensions/marketplace/write/english-auction/bidInAuction.js";
export {
cancelAuction,
type CancelAuctionParams,
} from "../../extensions/marketplace/__generated__/IEnglishAuctions/write/cancelAuction.js";
export {
buyoutAuction,
type BuyoutAuctionParams,
} from "../../extensions/marketplace/write/english-auction/buyoutAuction.js";
export {
collectAuctionPayout,
type CollectAuctionPayoutParams,
} from "../../extensions/marketplace/__generated__/IEnglishAuctions/write/collectAuctionPayout.js";
export {
collectAuctionTokens,
type CollectAuctionTokensParams,
} from "../../extensions/marketplace/__generated__/IEnglishAuctions/write/collectAuctionTokens.js";
export {
executeSale,
type ExecuteSaleParams,
} from "../../extensions/marketplace/write/english-auction/executeSale.js";
// EVENTS
export {
+18 -1
View File
@@ -17,7 +17,7 @@ export {
// contract related
export { useReadContract } from "../react/core/hooks/contract/useReadContract.js";
export { useSendTransaction } from "../react/core/hooks/contract/useSendTransaction.js";
export { useEstimateGas } from "../react/core/hooks/contract/useEstimateGas.js";
export { useWaitForReceipt } from "../react/core/hooks/contract/useWaitForReceipt.js";
export { useContractEvents } from "../react/core/hooks/contract/useContractEvents.js";
@@ -45,3 +45,20 @@ export {
useBuyWithCryptoHistory,
type BuyWithCryptoHistoryQueryParams,
} from "../react/core/hooks/pay/useBuyWithCryptoHistory.js";
import { useSendTransactionCore } from "../react/core/hooks/contract/useSendTransaction.js";
/**
* A hook to send a transaction.
* @returns A mutation object to send a transaction.
* @example
* ```jsx
* import { useSendTransaction } from "thirdweb/react-native";
* const { mutate: sendTx, data: transactionResult } = useSendTransaction();
*
* // later
* sendTx(tx);
* ```
* @transaction
*/
export const useSendTransaction = useSendTransactionCore;
+8 -2
View File
@@ -29,7 +29,10 @@ export {
export { ThirdwebProvider } from "../react/core/providers/thirdweb-provider.js";
// tokens
export type { SupportedTokens } from "../react/web/ui/ConnectWallet/defaultTokens.js";
export type {
SupportedTokens,
TokenInfo,
} from "../react/web/ui/ConnectWallet/defaultTokens.js";
export { defaultTokens } from "../react/web/ui/ConnectWallet/defaultTokens.js";
// Media Renderer
@@ -53,7 +56,10 @@ export {
// contract related
export { useReadContract } from "../react/core/hooks/contract/useReadContract.js";
export { useSendTransaction } from "../react/core/hooks/contract/useSendTransaction.js";
export {
useSendTransaction,
type SendTransactionConfig,
} from "../react/web/hooks/useSendTransaction.js";
export { useSendBatchTransaction } from "../react/core/hooks/contract/useSendBatchTransaction.js";
export { useSendAndConfirmTransaction } from "../react/core/hooks/contract/useSendAndConfirmTransaction.js";
export { useEstimateGas } from "../react/core/hooks/contract/useEstimateGas.js";
+11 -2
View File
@@ -24,9 +24,18 @@ export {
// private-key
export {
privateKeyAccount,
privateKeyToAccount,
type PrivateKeyAccountOptions,
/**
* @internal
* @deprecated - use {@link privateKeyToAccount} instead
*/
privateKeyToAccount as privateKeyAccount,
type PrivateKeyToAccountOptions,
/**
* @internal
* @deprecated - use {@link PrivateKeyToAccountOptions} instead
*/
type PrivateKeyToAccountOptions as PrivateKeyAccountOptions,
} from "../wallets/private-key.js";
// injected
@@ -1,4 +1,14 @@
export {
privateKeyAccount,
type PrivateKeyAccountOptions,
privateKeyToAccount,
/**
* @internal
* @deprecated - use {@link privateKeyToAccount} instead
*/
privateKeyToAccount as privateKeyAccount,
type PrivateKeyToAccountOptions,
/**
* @internal
* @deprecated - use {@link PrivateKeyToAccountOptions} instead
*/
type PrivateKeyToAccountOptions as PrivateKeyAccountOptions,
} from "../../wallets/private-key.js";
@@ -113,6 +113,37 @@ describe.runIf(process.env.TW_SECRET_KEY)(
).resolves.toBe(1n);
});
it("should allow to claim tokens with price", async () => {
await expect(
balanceOf({ contract, owner: TEST_ACCOUNT_A.address, tokenId: 0n }),
).resolves.toBe(1n);
await sendAndConfirmTransaction({
transaction: setClaimConditions({
contract,
phases: [
{
price: "0.001",
},
],
tokenId: 0n,
}),
account: TEST_ACCOUNT_A,
});
const claimTx = claimTo({
contract,
to: TEST_ACCOUNT_A.address,
tokenId: 0n,
quantity: 1n,
});
await sendAndConfirmTransaction({
transaction: claimTx,
account: TEST_ACCOUNT_A,
});
await expect(
balanceOf({ contract, owner: TEST_ACCOUNT_A.address, tokenId: 0n }),
).resolves.toBe(2n);
});
describe("Allowlists", () => {
it("should allow to claim tokens with an allowlist", async () => {
const tokenId = 1n;
@@ -16,7 +16,7 @@ export type MintAdditionalSupplyToParams = {
* @example
* ```ts
* import { mintAdditionalSupplyTo } from "thirdweb/extensions/erc1155";
* const transaction = mintTo({
* const transaction = mintAdditionalSupplyTo({
* contract,
* to: "0x...",
* tokenId: 1n,
@@ -21,7 +21,7 @@ import { generateMintSignature, mintWithSignature } from "./sigMint.js";
describe.runIf(process.env.TW_SECRET_KEY)(
"generateMintSignature",
{
timeout: 60000,
timeout: 120000,
},
() => {
let erc721Contract: ThirdwebContract;
@@ -42,7 +42,7 @@ describe.runIf(process.env.TW_SECRET_KEY)(
chain: ANVIL_CHAIN,
client: TEST_CLIENT,
});
});
}, 60000);
it("should generate a mint signature and mint an NFT", async () => {
const { payload, signature } = await generateMintSignature({
@@ -25,165 +25,174 @@ import { getListing } from "./read/direct/getListing.js";
import { getAllAuctions } from "./read/english-auction/getAllAuctions.js";
import { getAllValidAuctions } from "./read/english-auction/getAllValidAuctions.js";
import { getAuction } from "./read/english-auction/getAuction.js";
import { getWinningBid } from "./read/english-auction/getWinningBid.js";
import { isListingValid } from "./utils.js";
import { buyFromListing } from "./write/direct/buyFromListing.js";
import { createListing } from "./write/direct/createListing.js";
import { bidInAuction } from "./write/english-auction/bidInAuction.js";
import { buyoutAuction } from "./write/english-auction/buyoutAuction.js";
import { createAuction } from "./write/english-auction/createAuction.js";
// import { executeSale } from "./write/english-auction/executeSale.js";
describe.runIf(process.env.TW_SECRET_KEY)("Marketplace", () => {
let marketplaceContract: ThirdwebContract;
let erc721Contract: ThirdwebContract;
describe.runIf(process.env.TW_SECRET_KEY)(
"Marketplace",
{
timeout: 120000,
},
() => {
let marketplaceContract: ThirdwebContract;
let erc721Contract: ThirdwebContract;
beforeAll(async () => {
const marketplaceAddress = await deployMarketplaceContract({
account: TEST_ACCOUNT_A,
chain: ANVIL_CHAIN,
client: TEST_CLIENT,
params: {
name: "TestMarketPlace",
},
});
marketplaceContract = getContract({
address: marketplaceAddress,
client: TEST_CLIENT,
chain: ANVIL_CHAIN,
});
// also deploy an ERC721 contract
const erc721Address = await deployERC721Contract({
type: "TokenERC721",
account: TEST_ACCOUNT_A,
chain: ANVIL_CHAIN,
client: TEST_CLIENT,
params: {
name: "TestERC721",
},
});
erc721Contract = getContract({
address: erc721Address,
client: TEST_CLIENT,
chain: ANVIL_CHAIN,
});
// does a lot of stuff, this may take a while
}, 60_000);
describe("Deployment", () => {
it("should deploy marketplace contract", () => {
expect(marketplaceContract).toBeDefined();
});
it("should have the correct name", async () => {
const metadata = await getContractMetadata({
contract: marketplaceContract,
});
expect(metadata.name).toBe("TestMarketPlace");
});
});
describe("Direct Listings", () => {
let nftTokenId: bigint;
beforeAll(async () => {
const mintTransaction = mintTo({
contract: erc721Contract,
to: TEST_ACCOUNT_A.address,
nft: { name: "Test:ERC721:DirectListing" },
});
const receipt = await sendAndConfirmTransaction({
transaction: mintTransaction,
const marketplaceAddress = await deployMarketplaceContract({
account: TEST_ACCOUNT_A,
chain: ANVIL_CHAIN,
client: TEST_CLIENT,
params: {
name: "TestMarketPlace",
},
});
marketplaceContract = getContract({
address: marketplaceAddress,
client: TEST_CLIENT,
chain: ANVIL_CHAIN,
});
const mintEvents = parseEventLogs({
events: [tokensMintedEvent()],
logs: receipt.logs,
});
expect(mintEvents.length).toBe(1);
expect(mintEvents[0]?.args.tokenIdMinted).toBeDefined();
nftTokenId = mintEvents[0]?.args.tokenIdMinted as bigint;
}, 30_000);
it("should work for basic listings (Native Currency)", async () => {
// listings should be 0 length to start
const listings = await getAllListings({
contract: marketplaceContract,
});
expect(listings.length).toBe(0);
// oh and so should totalListings
expect(await totalListings({ contract: marketplaceContract })).toBe(0n);
// approve first
const approveTx = approve({
contract: erc721Contract,
to: marketplaceContract.address,
tokenId: nftTokenId,
});
await sendAndConfirmTransaction({
transaction: approveTx,
// also deploy an ERC721 contract
const erc721Address = await deployERC721Contract({
type: "TokenERC721",
account: TEST_ACCOUNT_A,
chain: ANVIL_CHAIN,
client: TEST_CLIENT,
params: {
name: "TestERC721",
},
});
const transaction = createListing({
contract: marketplaceContract,
assetContractAddress: erc721Contract.address,
tokenId: nftTokenId,
pricePerToken: "1",
});
const receipt = await sendAndConfirmTransaction({
transaction,
account: TEST_ACCOUNT_A,
erc721Contract = getContract({
address: erc721Address,
client: TEST_CLIENT,
chain: ANVIL_CHAIN,
});
const listingEvents = parseEventLogs({
events: [newListingEvent()],
logs: receipt.logs,
// does a lot of stuff, this may take a while
}, 60_000);
describe("Deployment", () => {
it("should deploy marketplace contract", () => {
expect(marketplaceContract).toBeDefined();
});
expect(listingEvents.length).toBe(1);
// biome-ignore lint/style/noNonNullAssertion: OK in tests
const listingEvent = listingEvents[0]!;
expect(listingEvent.args.listingCreator).toBe(TEST_ACCOUNT_A.address);
expect(listingEvent.args.assetContract).toBe(erc721Contract.address);
// at this point listings should be 1
const listingsAfter = await getAllListings({
contract: marketplaceContract,
it("should have the correct name", async () => {
const metadata = await getContractMetadata({
contract: marketplaceContract,
});
expect(metadata.name).toBe("TestMarketPlace");
});
expect(listingsAfter.length).toBe(1);
// valid listings should also be 1!
const validListings = await getAllValidListings({
contract: marketplaceContract,
});
expect(validListings.length).toBe(1);
// and totalListings should be 1
expect(await totalListings({ contract: marketplaceContract })).toBe(1n);
});
// explicitly retrieve the listing!
const listing = await getListing({
contract: marketplaceContract,
listingId: listingEvent.args.listingId,
});
describe("Direct Listings", () => {
let nftTokenId: bigint;
beforeAll(async () => {
const mintTransaction = mintTo({
contract: erc721Contract,
to: TEST_ACCOUNT_A.address,
nft: { name: "Test:ERC721:DirectListing" },
});
const receipt = await sendAndConfirmTransaction({
transaction: mintTransaction,
account: TEST_ACCOUNT_A,
});
expect(listing).toBeDefined();
expect(listing.status).toBe("ACTIVE");
expect(listing.creatorAddress).toBe(TEST_ACCOUNT_A.address);
expect(listing.assetContractAddress).toBe(erc721Contract.address);
expect(listing.tokenId).toBe(nftTokenId);
expect(listing.currencyValuePerToken).toMatchInlineSnapshot(`
const mintEvents = parseEventLogs({
events: [tokensMintedEvent()],
logs: receipt.logs,
});
expect(mintEvents.length).toBe(1);
expect(mintEvents[0]?.args.tokenIdMinted).toBeDefined();
nftTokenId = mintEvents[0]?.args.tokenIdMinted as bigint;
}, 30_000);
it("should work for basic listings (Native Currency)", async () => {
// listings should be 0 length to start
const listings = await getAllListings({
contract: marketplaceContract,
});
expect(listings.length).toBe(0);
// oh and so should totalListings
expect(await totalListings({ contract: marketplaceContract })).toBe(0n);
// approve first
const approveTx = approve({
contract: erc721Contract,
to: marketplaceContract.address,
tokenId: nftTokenId,
});
await sendAndConfirmTransaction({
transaction: approveTx,
account: TEST_ACCOUNT_A,
});
const transaction = createListing({
contract: marketplaceContract,
assetContractAddress: erc721Contract.address,
tokenId: nftTokenId,
pricePerToken: "1",
});
const receipt = await sendAndConfirmTransaction({
transaction,
account: TEST_ACCOUNT_A,
});
const listingEvents = parseEventLogs({
events: [newListingEvent()],
logs: receipt.logs,
});
expect(listingEvents.length).toBe(1);
// biome-ignore lint/style/noNonNullAssertion: OK in tests
const listingEvent = listingEvents[0]!;
expect(listingEvent.args.listingCreator).toBe(TEST_ACCOUNT_A.address);
expect(listingEvent.args.assetContract).toBe(erc721Contract.address);
// at this point listings should be 1
const listingsAfter = await getAllListings({
contract: marketplaceContract,
});
expect(listingsAfter.length).toBe(1);
// valid listings should also be 1!
const validListings = await getAllValidListings({
contract: marketplaceContract,
});
expect(validListings.length).toBe(1);
// and totalListings should be 1
expect(await totalListings({ contract: marketplaceContract })).toBe(1n);
// explicitly retrieve the listing!
const listing = await getListing({
contract: marketplaceContract,
listingId: listingEvent.args.listingId,
});
expect(listing).toBeDefined();
expect(listing.status).toBe("ACTIVE");
expect(listing.creatorAddress).toBe(TEST_ACCOUNT_A.address);
expect(listing.assetContractAddress).toBe(erc721Contract.address);
expect(listing.tokenId).toBe(nftTokenId);
expect(listing.currencyValuePerToken).toMatchInlineSnapshot(`
{
"decimals": 18,
"displayValue": "1",
"name": "Ether",
"name": "Anvil Ether",
"symbol": "ETH",
"value": 1000000000000000000n,
}
`);
expect(listing.asset).toMatchInlineSnapshot(`
expect(listing.asset).toMatchInlineSnapshot(`
{
"id": 0n,
"metadata": {
@@ -195,169 +204,169 @@ describe.runIf(process.env.TW_SECRET_KEY)("Marketplace", () => {
}
`);
// check the listing is valid
const listingValidity = await isListingValid({
listing,
contract: marketplaceContract,
quantity: 1n,
});
// check the listing is valid
const listingValidity = await isListingValid({
listing,
contract: marketplaceContract,
quantity: 1n,
});
expect(listingValidity).toMatchInlineSnapshot(`
expect(listingValidity).toMatchInlineSnapshot(`
{
"valid": true,
}
`);
// expect the buyer to have an initial balance of 0
await expect(
balanceOf({
contract: erc721Contract,
owner: TEST_ACCOUNT_B.address,
}),
).resolves.toBe(0n);
// expect the buyer to have an initial balance of 0
await expect(
balanceOf({
contract: erc721Contract,
owner: TEST_ACCOUNT_B.address,
}),
).resolves.toBe(0n);
const buyTx = buyFromListing({
contract: marketplaceContract,
listingId: listingEvent.args.listingId,
recipient: TEST_ACCOUNT_B.address,
quantity: 1n,
const buyTx = buyFromListing({
contract: marketplaceContract,
listingId: listingEvent.args.listingId,
recipient: TEST_ACCOUNT_B.address,
quantity: 1n,
});
await sendAndConfirmTransaction({
transaction: buyTx,
account: TEST_ACCOUNT_B,
});
// expect the buyer to have a new balance of 1
await expect(
balanceOf({
contract: erc721Contract,
owner: TEST_ACCOUNT_B.address,
}),
).resolves.toBe(1n);
// expect the seller to no longer have the token
await expect(
balanceOf({
contract: erc721Contract,
owner: TEST_ACCOUNT_A.address,
}),
).resolves.toBe(0n);
});
await sendAndConfirmTransaction({
transaction: buyTx,
account: TEST_ACCOUNT_B,
});
// expect the buyer to have a new balance of 1
await expect(
balanceOf({
contract: erc721Contract,
owner: TEST_ACCOUNT_B.address,
}),
).resolves.toBe(1n);
// expect the seller to no longer have the token
await expect(
balanceOf({
contract: erc721Contract,
owner: TEST_ACCOUNT_A.address,
}),
).resolves.toBe(0n);
});
});
describe("English Auctions", () => {
let nftTokenId: bigint;
beforeAll(async () => {
const mintTransaction = mintTo({
contract: erc721Contract,
to: TEST_ACCOUNT_A.address,
nft: { name: "Test:ERC721:EnglishAuction" },
});
const receipt = await sendAndConfirmTransaction({
transaction: mintTransaction,
account: TEST_ACCOUNT_A,
});
describe("English Auctions", () => {
let nftTokenId: bigint;
beforeAll(async () => {
const mintTransaction = mintTo({
contract: erc721Contract,
to: TEST_ACCOUNT_A.address,
nft: { name: "Test:ERC721:EnglishAuction" },
});
const receipt = await sendAndConfirmTransaction({
transaction: mintTransaction,
account: TEST_ACCOUNT_A,
});
const mintEvents = parseEventLogs({
events: [tokensMintedEvent()],
logs: receipt.logs,
});
const mintEvents = parseEventLogs({
events: [tokensMintedEvent()],
logs: receipt.logs,
});
expect(mintEvents.length).toBe(1);
expect(mintEvents[0]?.args.tokenIdMinted).toBeDefined();
expect(mintEvents.length).toBe(1);
expect(mintEvents[0]?.args.tokenIdMinted).toBeDefined();
nftTokenId = mintEvents[0]?.args.tokenIdMinted as bigint;
}, 30_000);
nftTokenId = mintEvents[0]?.args.tokenIdMinted as bigint;
}, 30_000);
it("should work for basic auctions (Native Currency)", async () => {
// auctions should be 0 length to start
const auctions = await getAllAuctions({
contract: marketplaceContract,
});
expect(auctions.length).toBe(0);
// oh and so should totalAuctions
expect(await totalAuctions({ contract: marketplaceContract })).toBe(0n);
it("should work for basic auctions (Native Currency)", async () => {
// auctions should be 0 length to start
const auctions = await getAllAuctions({
contract: marketplaceContract,
});
expect(auctions.length).toBe(0);
// oh and so should totalAuctions
expect(await totalAuctions({ contract: marketplaceContract })).toBe(0n);
// approve first
const approveTx = approve({
contract: erc721Contract,
to: marketplaceContract.address,
tokenId: nftTokenId,
});
// approve first
const approveTx = approve({
contract: erc721Contract,
to: marketplaceContract.address,
tokenId: nftTokenId,
});
await sendAndConfirmTransaction({
transaction: approveTx,
account: TEST_ACCOUNT_A,
});
await sendAndConfirmTransaction({
transaction: approveTx,
account: TEST_ACCOUNT_A,
});
const transaction = createAuction({
contract: marketplaceContract,
assetContractAddress: erc721Contract.address,
tokenId: nftTokenId,
minimumBidAmount: "1",
buyoutBidAmount: "10",
});
const receipt = await sendAndConfirmTransaction({
transaction,
account: TEST_ACCOUNT_A,
});
const transaction = createAuction({
contract: marketplaceContract,
assetContractAddress: erc721Contract.address,
tokenId: nftTokenId,
minimumBidAmount: "1",
buyoutBidAmount: "10",
});
const receipt = await sendAndConfirmTransaction({
transaction,
account: TEST_ACCOUNT_A,
});
const listingEvents = parseEventLogs({
events: [newAuctionEvent()],
logs: receipt.logs,
});
const listingEvents = parseEventLogs({
events: [newAuctionEvent()],
logs: receipt.logs,
});
expect(listingEvents.length).toBe(1);
expect(listingEvents.length).toBe(1);
// biome-ignore lint/style/noNonNullAssertion: OK in tests
const listingEvent = listingEvents[0]!;
// biome-ignore lint/style/noNonNullAssertion: OK in tests
const listingEvent = listingEvents[0]!;
expect(listingEvent.args.auctionCreator).toBe(TEST_ACCOUNT_A.address);
expect(listingEvent.args.assetContract).toBe(erc721Contract.address);
expect(listingEvent.args.auctionCreator).toBe(TEST_ACCOUNT_A.address);
expect(listingEvent.args.assetContract).toBe(erc721Contract.address);
// at this point auctions should be 1
const auctionsAfter = await getAllAuctions({
contract: marketplaceContract,
});
expect(auctionsAfter.length).toBe(1);
// valid auctions should also be 1!
const validAuctions = await getAllValidAuctions({
contract: marketplaceContract,
});
expect(validAuctions.length).toBe(1);
// and totalauctions should be 1
expect(await totalAuctions({ contract: marketplaceContract })).toBe(1n);
// at this point auctions should be 1
const auctionsAfter = await getAllAuctions({
contract: marketplaceContract,
});
expect(auctionsAfter.length).toBe(1);
// valid auctions should also be 1!
const validAuctions = await getAllValidAuctions({
contract: marketplaceContract,
});
expect(validAuctions.length).toBe(1);
// and totalauctions should be 1
expect(await totalAuctions({ contract: marketplaceContract })).toBe(1n);
// explicitly retrieve the listing!
const listing = await getAuction({
contract: marketplaceContract,
auctionId: listingEvent.args.auctionId,
});
// explicitly retrieve the listing!
const listing = await getAuction({
contract: marketplaceContract,
auctionId: listingEvent.args.auctionId,
});
expect(listing).toBeDefined();
expect(listing.status).toBe("ACTIVE");
expect(listing.creatorAddress).toBe(TEST_ACCOUNT_A.address);
expect(listing.assetContractAddress).toBe(erc721Contract.address);
expect(listing.tokenId).toBe(nftTokenId);
expect(listing.minimumBidCurrencyValue).toMatchInlineSnapshot(`
expect(listing).toBeDefined();
expect(listing.status).toBe("ACTIVE");
expect(listing.creatorAddress).toBe(TEST_ACCOUNT_A.address);
expect(listing.assetContractAddress).toBe(erc721Contract.address);
expect(listing.tokenId).toBe(nftTokenId);
expect(listing.minimumBidCurrencyValue).toMatchInlineSnapshot(`
{
"decimals": 18,
"displayValue": "1",
"name": "Ether",
"name": "Anvil Ether",
"symbol": "ETH",
"value": 1000000000000000000n,
}
`);
expect(listing.buyoutCurrencyValue).toMatchInlineSnapshot(`
expect(listing.buyoutCurrencyValue).toMatchInlineSnapshot(`
{
"decimals": 18,
"displayValue": "10",
"name": "Ether",
"name": "Anvil Ether",
"symbol": "ETH",
"value": 10000000000000000000n,
}
`);
expect(listing.asset).toMatchInlineSnapshot(`
expect(listing.asset).toMatchInlineSnapshot(`
{
"id": 1n,
"metadata": {
@@ -368,6 +377,193 @@ describe.runIf(process.env.TW_SECRET_KEY)("Marketplace", () => {
"type": "ERC721",
}
`);
// check for a winning bid
await expect(
getWinningBid({
contract: marketplaceContract,
auctionId: listing.id,
}),
).resolves.toBeUndefined();
// invalid bid amount 1: 0 bid (0 is not allowed)
await expect(
sendAndConfirmTransaction({
account: TEST_ACCOUNT_B,
transaction: bidInAuction({
auctionId: listing.id,
contract: marketplaceContract,
bidAmount: "0",
}),
}),
).rejects.toThrowErrorMatchingInlineSnapshot(
"[Error: Bid amount is zero]",
);
// invalid bid amount 2: 11 bid (over buyout)
await expect(
sendAndConfirmTransaction({
account: TEST_ACCOUNT_B,
transaction: bidInAuction({
auctionId: listing.id,
contract: marketplaceContract,
bidAmount: "11",
}),
}),
).rejects.toThrowErrorMatchingInlineSnapshot(
"[Error: Bid amount is above the buyout amount]",
);
// invalid bid amount 3: below minimum bid (but not 0)
await expect(
sendAndConfirmTransaction({
account: TEST_ACCOUNT_B,
transaction: bidInAuction({
auctionId: listing.id,
contract: marketplaceContract,
bidAmount: "0.5",
}),
}),
).rejects.toThrowErrorMatchingInlineSnapshot(
"[Error: Bid amount is below the minimum bid amount]",
);
// valid bid amount: "2"
await expect(
sendAndConfirmTransaction({
account: TEST_ACCOUNT_B,
transaction: bidInAuction({
auctionId: listing.id,
contract: marketplaceContract,
bidAmount: "2",
}),
}),
).resolves.toBeDefined();
// check for a new winning bid
await expect(
getWinningBid({
contract: marketplaceContract,
auctionId: listing.id,
}),
).resolves.toMatchInlineSnapshot(`
{
"bidAmountWei": 2000000000000000000n,
"bidderAddress": "0x70997970C51812dc3A010C7d01b50e0d17dc79C8",
"currencyAddress": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
"currencyValue": {
"decimals": 18,
"displayValue": "2",
"name": "Anvil Ether",
"symbol": "ETH",
"value": 2000000000000000000n,
},
}
`);
// invalid bid amount, above minimum but below existing winning bid
await expect(
sendAndConfirmTransaction({
account: TEST_ACCOUNT_B,
transaction: bidInAuction({
auctionId: listing.id,
contract: marketplaceContract,
bidAmount: "1.5",
}),
}),
).rejects.toThrowErrorMatchingInlineSnapshot(
"[Error: Bid amount is too low to outbid the existing winning bid]",
);
// invalid bid amount, above winning bit but below bid + bidBuffer (default 500bps)
await expect(
sendAndConfirmTransaction({
account: TEST_ACCOUNT_B,
transaction: bidInAuction({
auctionId: listing.id,
contract: marketplaceContract,
// 2 * 1.05 = 2.1, so 2.05 is invalid
bidAmount: "2.05",
}),
}),
).rejects.toThrowErrorMatchingInlineSnapshot(
"[Error: Bid amount is too low to outbid the existing winning bid]",
);
// actually outbid the winning bid
await expect(
sendAndConfirmTransaction({
account: TEST_ACCOUNT_B,
transaction: bidInAuction({
auctionId: listing.id,
contract: marketplaceContract,
bidAmount: "3",
}),
}),
).resolves.toBeDefined();
// check for a new winning bid
await expect(
getWinningBid({
contract: marketplaceContract,
auctionId: listing.id,
}),
).resolves.toMatchInlineSnapshot(`
{
"bidAmountWei": 3000000000000000000n,
"bidderAddress": "0x70997970C51812dc3A010C7d01b50e0d17dc79C8",
"currencyAddress": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
"currencyValue": {
"decimals": 18,
"displayValue": "3",
"name": "Anvil Ether",
"symbol": "ETH",
"value": 3000000000000000000n,
},
}
`);
// buyout auction
await expect(
sendAndConfirmTransaction({
account: TEST_ACCOUNT_B,
transaction: buyoutAuction({
contract: marketplaceContract,
auctionId: listing.id,
}),
}),
).resolves.toBeDefined();
// check for a new winning bid
await expect(
getWinningBid({
contract: marketplaceContract,
auctionId: listing.id,
}),
).resolves.toMatchInlineSnapshot(`
{
"bidAmountWei": 10000000000000000000n,
"bidderAddress": "0x70997970C51812dc3A010C7d01b50e0d17dc79C8",
"currencyAddress": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
"currencyValue": {
"decimals": 18,
"displayValue": "10",
"name": "Anvil Ether",
"symbol": "ETH",
"value": 10000000000000000000n,
},
}
`);
// // execute the sale
// await expect(
// sendAndConfirmTransaction({
// account: TEST_ACCOUNT_A,
// transaction: executeSale({
// contract: marketplaceContract,
// auctionId: listing.id,
// }),
// }),
// ).resolves.toBeDefined();
});
});
});
});
},
);
@@ -0,0 +1,48 @@
import { ADDRESS_ZERO } from "../../../../constants/addresses.js";
import type { BaseTransactionOptions } from "../../../../transaction/types.js";
import { resolveCurrencyValue } from "../../../../utils/extensions/resolve-currency-value.js";
import {
type GetWinningBidParams as GeneratedWinningBidParams,
getWinningBid as getWinningBidGenerated,
} from "../../__generated__/IEnglishAuctions/read/getWinningBid.js";
export type GetWinningBidParams = GeneratedWinningBidParams;
/**
* Retrieves the winning bid information for a given auction.
*
* @param options - The options for retrieving the winning bid.
* @returns The winning bid information, or undefined if there is no winning bid.
* @extension MARKETPLACE
* @example
* ```ts
* import { getWinningBid } from "thirdweb/extensions/marketplace";
*
* const winningBid = await getWinningBid({
* contract,
* auctionId: 0n,
* });
* ```
*/
export async function getWinningBid(
options: BaseTransactionOptions<GetWinningBidParams>,
) {
const [bidderAddress, currencyAddress, bidAmountWei] =
await getWinningBidGenerated(options);
if (bidderAddress === ADDRESS_ZERO) {
return undefined;
}
return {
bidderAddress,
currencyAddress,
bidAmountWei,
currencyValue: await resolveCurrencyValue({
chain: options.contract.chain,
client: options.contract.client,
currencyAddress,
wei: bidAmountWei,
}),
};
}
@@ -0,0 +1,101 @@
import { isNativeTokenAddress } from "../../../../constants/addresses.js";
import type { BaseTransactionOptions } from "../../../../transaction/types.js";
import { isNewWinningBid } from "../../__generated__/IEnglishAuctions/read/isNewWinningBid.js";
import { bidInAuction as generatedBidInAuction } from "../../__generated__/IEnglishAuctions/write/bidInAuction.js";
import { getAuction } from "../../read/english-auction/getAuction.js";
import { getWinningBid } from "../../read/english-auction/getWinningBid.js";
export type BidInAuctionParams = {
auctionId: bigint;
} & (
| {
bidAmountWei: bigint;
}
| { bidAmount: string }
);
/**
* Places a bid in an English auction.
* @param options - The options for placing the bid.
* @returns A transaction that can be sent to place the bid.
* @extension MARKETPLACE
* @example
* ```ts
* import { bidInAuction } from "thirdweb/extensions/marketplace";
*
* const transaction = bidInAuction({
* contract,
* auctionId: 0n,
* bidAmount: "100",
* });
* ```
*/
export function bidInAuction(
options: BaseTransactionOptions<BidInAuctionParams>,
) {
return generatedBidInAuction({
contract: options.contract,
asyncParams: async () => {
const auction = await getAuction({
contract: options.contract,
auctionId: options.auctionId,
});
const resolvedBidAmountWei = await (async () => {
// if we already have the bid amount in wei, use that
if ("bidAmountWei" in options) {
return options.bidAmountWei;
}
// otherwise load the utility function and convert the amount
const { convertErc20Amount } = await import(
"../../../../utils/extensions/convert-erc20-amount.js"
);
return await convertErc20Amount({
amount: options.bidAmount,
chain: options.contract.chain,
erc20Address: auction.currencyContractAddress,
client: options.contract.client,
});
})();
if (resolvedBidAmountWei === 0n) {
throw new Error("Bid amount is zero");
}
if (resolvedBidAmountWei > auction.buyoutCurrencyValue.value) {
throw new Error("Bid amount is above the buyout amount");
}
const existingWinningBid = await getWinningBid({
auctionId: options.auctionId,
contract: options.contract,
});
if (existingWinningBid) {
// check if the bid amount is sufficient to outbid the existing winning bid
const isNewWinner = await isNewWinningBid({
contract: options.contract,
auctionId: options.auctionId,
bidAmount: resolvedBidAmountWei,
});
if (!isNewWinner) {
throw new Error(
"Bid amount is too low to outbid the existing winning bid",
);
}
} else {
// no existing winning bid, check if the bid amount is sufficient to outbid the minimum bid
if (resolvedBidAmountWei < auction.minimumBidCurrencyValue.value) {
throw new Error("Bid amount is below the minimum bid amount");
}
}
return {
auctionId: options.auctionId,
bidAmount: resolvedBidAmountWei,
overrides: {
value: isNativeTokenAddress(auction.currencyContractAddress)
? resolvedBidAmountWei
: undefined,
},
};
},
});
}
@@ -0,0 +1,47 @@
import { isNativeTokenAddress } from "../../../../constants/addresses.js";
import type { BaseTransactionOptions } from "../../../../transaction/types.js";
import { bidInAuction as generatedBidInAuction } from "../../__generated__/IEnglishAuctions/write/bidInAuction.js";
import { getAuction } from "../../read/english-auction/getAuction.js";
export type BuyoutAuctionParams = {
auctionId: bigint;
};
/**
* Buys out an English auction.
* @param options - The options for buying out the auction.
* @returns A transaction that can be sent to buy out the auction.
* @extension MARKETPLACE
* @example
* ```ts
* import { buyoutAuction } from "thirdweb/extensions/marketplace";
*
* const transaction = buyoutAuction({
* contract,
* auctionId: 0n
* });
* ```
*/
export function buyoutAuction(
options: BaseTransactionOptions<BuyoutAuctionParams>,
) {
return generatedBidInAuction({
contract: options.contract,
asyncParams: async () => {
const auction = await getAuction({
contract: options.contract,
auctionId: options.auctionId,
});
return {
auctionId: options.auctionId,
bidAmount: auction.buyoutBidAmount,
overrides: {
value: isNativeTokenAddress(auction.currencyContractAddress)
? auction.buyoutBidAmount
: undefined,
},
};
},
});
}
@@ -0,0 +1,44 @@
import type { BaseTransactionOptions } from "../../../../transaction/types.js";
import { cancelAuction as generatedCancelAuction } from "../../__generated__/IEnglishAuctions/write/cancelAuction.js";
import { getWinningBid } from "../../read/english-auction/getWinningBid.js";
export type CancelAuctionParams = {
auctionId: bigint;
};
/**
* Cancels an auction by providing the necessary options.
*
* @param options - The options for canceling the auction.
* @returns A transaction that can be sent to cancel the auction.
* @throws An error when sending the transaction if the auction has an existing bid and cannot be canceled.
* @extension MARKETPLACE
* @example
* ```ts
* import { cancelAuction } from "thirdweb/extensions/marketplace";
*
* const transaction = cancelAuction({
* contract,
* auctionId: 0n,
* });
* ```
*/
export function cancelAuction(
options: BaseTransactionOptions<CancelAuctionParams>,
) {
return generatedCancelAuction({
contract: options.contract,
asyncParams: async () => {
const winningBid = await getWinningBid({
contract: options.contract,
auctionId: options.auctionId,
});
if (winningBid) {
throw new Error("Cannot cancel an auction with an existing bid");
}
return {
auctionId: options.auctionId,
};
},
});
}
@@ -0,0 +1,51 @@
import type { BaseTransactionOptions } from "../../../../transaction/types.js";
import { multicall } from "../../../common/__generated__/IMulticall/write/multicall.js";
import { encodeCollectAuctionPayout } from "../../__generated__/IEnglishAuctions/write/collectAuctionPayout.js";
import { encodeCollectAuctionTokens } from "../../__generated__/IEnglishAuctions/write/collectAuctionTokens.js";
import { getWinningBid } from "../../read/english-auction/getWinningBid.js";
export type ExecuteSaleParams = {
auctionId: bigint;
};
/**
* Executes a sale for an English auction.
*
* @param options - The options for executing the sale.
* @returns A transaction that can be sent to execute the sale.
* @throws An error if the auction is still active and there is no winning bid.
* @extension MARKETPLACE
* @example
* ```ts
* import { executeSale } from "thirdweb/extensions/marketplace";
*
* const transaction = executeSale({
* contract,
* auctionId: 0n,
* });
* ```
*/
export function executeSale(
options: BaseTransactionOptions<ExecuteSaleParams>,
) {
return multicall({
contract: options.contract,
asyncParams: async () => {
const winningBid = await getWinningBid({
contract: options.contract,
auctionId: options.auctionId,
});
console.log("*** winning bid", winningBid);
if (!winningBid) {
throw new Error("Auction is still active");
}
return {
data: [
encodeCollectAuctionTokens({ auctionId: options.auctionId }),
encodeCollectAuctionPayout({ auctionId: options.auctionId }),
],
};
},
});
}
@@ -0,0 +1,38 @@
import { describe, expect, it } from "vitest";
import { ANVIL_CHAIN } from "../../../test/src/chains.js";
import { TEST_CLIENT } from "../../../test/src/test-clients.js";
import { TEST_ACCOUNT_A } from "../../../test/src/test-wallets.js";
import { ENTRYPOINT_ADDRESS } from "../../wallets/smart/lib/constants.js";
import { deployPublishedContract } from "./deploy-published.js";
describe.runIf(process.env.TW_SECRET_KEY)(
"deployPublished",
{
timeout: 120000,
},
() => {
it("should deploy a published direct deploy contract", async () => {
const address = await deployPublishedContract({
client: TEST_CLIENT,
chain: ANVIL_CHAIN,
account: TEST_ACCOUNT_A,
contractId: "AccountFactory",
contractParams: [TEST_ACCOUNT_A.address, ENTRYPOINT_ADDRESS],
});
expect(address).toBeDefined();
expect(address.length).toBe(42);
});
it("should deploy a published autofactory contract", async () => {
const address = await deployPublishedContract({
client: TEST_CLIENT,
chain: ANVIL_CHAIN,
account: TEST_ACCOUNT_A,
contractId: "Airdrop",
contractParams: [TEST_ACCOUNT_A.address],
});
expect(address).toBeDefined();
expect(address.length).toBe(42);
});
},
);
@@ -0,0 +1,156 @@
import type { AbiConstructor } from "abitype";
import type { Chain } from "../../chains/types.js";
import type { ThirdwebClient } from "../../client/client.js";
import { getContract } from "../../contract/contract.js";
import { fetchPublishedContractMetadata } from "../../contract/deployment/publisher.js";
import { sendAndConfirmTransaction } from "../../transaction/actions/send-and-confirm-transaction.js";
import { simulateTransaction } from "../../transaction/actions/simulate.js";
import { prepareContractCall } from "../../transaction/prepare-contract-call.js";
import { resolveMethod } from "../../transaction/resolve-method.js";
import type { Account } from "../../wallets/interfaces/wallet.js";
export type DeployPublishedContractOptions = {
client: ThirdwebClient;
chain: Chain;
account: Account;
contractId: string;
contractParams: unknown[];
publisher?: string;
version?: string;
implementationConstructorParams?: unknown[];
};
/**
* Deploy an instance of a published contract on a given chain
* @param options - the deploy options
* @returns a promise that resolves to the deployed contract address
* @example
* ```
* import { deployPublishedContract } from "thirdweb/deploys";
*
* const address = await deployedPublishedContract({
* client,
* chain,
* account,
* contractId: "MyPublishedContract",
* contractParams: [...],
* publisher: "0x...",
* });
* ```
* @extension DEPLOY
*/
export async function deployPublishedContract(
options: DeployPublishedContractOptions,
): Promise<string> {
const {
client,
account,
chain,
contractId,
contractParams,
publisher,
version,
implementationConstructorParams,
} = options;
const { compilerMetadata, extendedMetadata } =
await fetchPublishedContractMetadata({
client,
contractId,
publisher,
version,
});
switch (extendedMetadata?.deployType) {
case "standard": {
const { deployContract } = await import(
"../../contract/deployment/deploy-with-abi.js"
);
return deployContract({
account,
client,
chain,
bytecode: compilerMetadata.bytecode,
constructorAbi:
(compilerMetadata.abi.find(
(i) => i.type === "constructor",
) as AbiConstructor) || [],
constructorParams: contractParams,
});
}
case "autoFactory": {
const [
{ deployViaAutoFactory },
{ getOrDeployInfraForPublishedContract },
] = await Promise.all([
import("../../contract/deployment/deploy-via-autofactory.js"),
import("../../contract/deployment/utils/bootstrap.js"),
]);
const { cloneFactoryContract, implementationContract } =
await getOrDeployInfraForPublishedContract({
chain,
client,
account,
contractId,
constructorParams: implementationConstructorParams || [],
});
const initializeTransaction = prepareContractCall({
contract: getContract({
client,
chain,
address: implementationContract.address,
}),
method: resolveMethod(
extendedMetadata.factoryDeploymentData
?.implementationInitializerFunction || "initialize",
),
params: contractParams,
});
return deployViaAutoFactory({
client,
chain,
account,
cloneFactoryContract,
initializeTransaction,
});
}
case "customFactory": {
if (!extendedMetadata?.factoryDeploymentData?.customFactoryInput) {
throw new Error("No custom factory info found");
}
const factoryAddress =
extendedMetadata?.factoryDeploymentData?.customFactoryInput
?.customFactoryAddresses?.[chain.id];
const factoryFunction =
extendedMetadata.factoryDeploymentData?.customFactoryInput
?.factoryFunction;
if (!factoryAddress || !factoryFunction) {
throw new Error(`No factory address found on chain ${chain.id}`);
}
const factory = getContract({
client,
chain,
address: factoryAddress,
});
const deployTx = prepareContractCall({
contract: factory,
method: resolveMethod(factoryFunction),
params: contractParams,
});
// asumption here is that the factory address returns the deployed proxy address
const address = simulateTransaction({
transaction: deployTx,
});
await sendAndConfirmTransaction({
transaction: deployTx,
account,
});
return address;
}
default:
throw new Error(
`Unsupported deploy type: ${extendedMetadata?.deployType}`,
);
}
}
@@ -1,9 +1,22 @@
import { type UseMutationResult, useMutation } from "@tanstack/react-query";
import { estimateGasCost } from "../../../../exports/transaction.js";
import { resolvePromisedValue } from "../../../../exports/utils.js";
import { getWalletBalance } from "../../../../exports/wallets.js";
import { sendTransaction } from "../../../../transaction/actions/send-transaction.js";
import type { WaitForReceiptOptions } from "../../../../transaction/actions/wait-for-tx-receipt.js";
import type { PreparedTransaction } from "../../../../transaction/prepare-transaction.js";
import type { GetWalletBalanceResult } from "../../../../wallets/utils/getWalletBalance.js";
import { fetchSwapSupportedChains } from "../../../web/ui/ConnectWallet/screens/Buy/swap/useSwapSupportedChains.js";
import { useActiveAccount } from "../wallets/wallet-hooks.js";
type ShowModalData = {
tx: PreparedTransaction;
sendTx: () => void;
rejectTx: () => void;
totalCostWei: bigint;
walletBalance: GetWalletBalanceResult;
};
/**
* A hook to send a transaction.
* @returns A mutation object to send a transaction.
@@ -15,24 +28,107 @@ import { useActiveAccount } from "../wallets/wallet-hooks.js";
* // later
* sendTx(tx);
* ```
* @transaction
* @internal
*/
export function useSendTransaction(): UseMutationResult<
WaitForReceiptOptions,
Error,
PreparedTransaction
> {
export function useSendTransactionCore(
showPayModal?: (data: ShowModalData) => void,
): UseMutationResult<WaitForReceiptOptions, Error, PreparedTransaction> {
const account = useActiveAccount();
return useMutation({
mutationFn: async (transaction) => {
mutationFn: async (tx) => {
if (!account) {
throw new Error("No active account");
}
return await sendTransaction({
transaction,
account,
if (!showPayModal) {
return sendTransaction({
transaction: tx,
account,
});
}
return new Promise<WaitForReceiptOptions>((resolve, reject) => {
const sendTx = async () => {
try {
const res = await sendTransaction({
transaction: tx,
account,
});
resolve(res);
} catch (e) {
reject(e);
}
};
(async () => {
try {
const swapSupportedChains = await fetchSwapSupportedChains(
tx.client,
);
const isBuySupported = swapSupportedChains.find(
(c) => c.id === tx.chain.id,
);
// buy not supported, can't show modal - send tx directly
if (!isBuySupported) {
sendTx();
return;
}
// buy supported, check if there is enouch balance - if not show modal to buy tokens
const [walletBalance, totalCostWei] = await Promise.all([
getWalletBalance({
address: account.address,
chain: tx.chain,
client: tx.client,
}),
getTotalTxCostForBuy(tx),
]);
const walletBalanceWei = walletBalance.value;
// if enough balance, send tx
if (totalCostWei < walletBalanceWei) {
sendTx();
return;
}
// if not enough balance - show modal
showPayModal({
tx,
sendTx,
rejectTx: () => {
reject(new Error("Not enough balance"));
},
totalCostWei,
walletBalance,
});
} catch (e) {
console.error("Failed to estimate cost", e);
// send it anyway?
sendTx();
}
})();
});
},
});
}
export async function getTotalTxCostForBuy(tx: PreparedTransaction) {
// Must pass 0 otherwise it will throw on some chains
const gasCost = await estimateGasCost({
transaction: { ...tx, value: 0n },
});
const bufferCost = gasCost.wei / 10n;
// Note: get tx.value AFTER estimateGasCost
const txValue = await resolvePromisedValue(tx.value);
// add 10% extra gas cost to the estimate to ensure user buys enough to cover the tx cost
return gasCost.wei + bufferCost + (txValue || 0n);
}
@@ -3,7 +3,8 @@ import {
type GetWalletBalanceOptions,
getWalletBalance,
} from "../../../../wallets/utils/getWalletBalance.js";
import { useConnectUI } from "./useWalletConnectionCtx.js";
// NOTE: Do not use useConnectUI here - because this hook is also used outside of Connect UI context
/**
* Custom hook to fetch the balance of a wallet for a specific token.
@@ -11,11 +12,8 @@ import { useConnectUI } from "./useWalletConnectionCtx.js";
* @returns The result of the query.
* @internal
*/
export function useWalletBalance(
options: Omit<Partial<GetWalletBalanceOptions>, "client">,
) {
const { chain, address, tokenAddress } = options;
const { client } = useConnectUI();
export function useWalletBalance(options: Partial<GetWalletBalanceOptions>) {
const { chain, address, tokenAddress, client } = options;
const query = queryOptions({
queryKey: [
"walletBalance",
@@ -0,0 +1,5 @@
import { createContext } from "react";
export const SetRootElementContext = createContext<
(el: React.ReactNode) => void
>(() => {});
@@ -6,6 +6,7 @@ import {
} from "../../../transaction/actions/wait-for-tx-receipt.js";
import { isBaseTransactionOptions } from "../../../transaction/types.js";
import { isObjectWithKeys } from "../../../utils/type-guards.js";
import { SetRootElementContext } from "./RootElementContext.js";
/**
* The ThirdwebProvider is component is a provider component that sets up the React Query client.
@@ -25,6 +26,7 @@ import { isObjectWithKeys } from "../../../utils/type-guards.js";
* @component
*/
export function ThirdwebProvider(props: React.PropsWithChildren) {
const [el, setEl] = useState<React.ReactNode>(null);
const [queryClient] = useState(
() =>
new QueryClient({
@@ -77,7 +79,10 @@ export function ThirdwebProvider(props: React.PropsWithChildren) {
return (
<QueryClientProvider client={queryClient}>
{props.children}
<SetRootElementContext.Provider value={setEl}>
{props.children}
</SetRootElementContext.Provider>
{el}
</QueryClientProvider>
);
}
@@ -0,0 +1,166 @@
import { useContext, useState } from "react";
import type { ThirdwebClient } from "../../../client/client.js";
import type { PreparedTransaction } from "../../../transaction/prepare-transaction.js";
import { useSendTransactionCore } from "../../core/hooks/contract/useSendTransaction.js";
import { SetRootElementContext } from "../../core/providers/RootElementContext.js";
import {
type SupportedTokens,
defaultTokens,
} from "../ui/ConnectWallet/defaultTokens.js";
import { useConnectLocale } from "../ui/ConnectWallet/locale/getConnectLocale.js";
import { BuyScreen } from "../ui/ConnectWallet/screens/Buy/SwapScreen.js";
import { SwapTransactionsScreen } from "../ui/ConnectWallet/screens/SwapTransactionsScreen.js";
import { Modal } from "../ui/components/Modal.js";
import { CustomThemeProvider } from "../ui/design-system/CustomThemeProvider.js";
import type { Theme } from "../ui/design-system/index.js";
import type { LocaleId } from "../ui/types.js";
import { LoadingScreen } from "../wallets/shared/LoadingScreen.js";
/**
* Configuration for the `useSendTransaction` hook.
*/
export type SendTransactionConfig = {
/**
* Configuration for the "Pay Modal" that opens when the user doesn't have enough funds to send a transaction.
* Set `payModal: false` to disable the "Pay Modal" popup
*
* This configuration object includes the following properties to configure the "Pay Modal" UI:
*
* ### `locale`
* The language to use for the "Pay Modal" UI. Defaults to `"en_US"`.
*
* ### `supportedTokens`
* An object of type [`SupportedTokens`](https://portal.thirdweb.com/references/typescript/v5/SupportedTokens) to configure the tokens to show for a chain.
*
* ### `theme`
* The theme to use for the "Pay Modal" UI. Defaults to `"dark"`.
*
* It can be set to `"light"` or `"dark"` or an object of type [`Theme`](https://portal.thirdweb.com/references/typescript/v5/Theme) for a custom theme.
*
* Refer to [`lightTheme`](https://portal.thirdweb.com/references/typescript/v5/lightTheme)
* or [`darkTheme`](https://portal.thirdweb.com/references/typescript/v5/darkTheme) helper functions to use the default light or dark theme and customize it.
*/
payModal?:
| {
locale?: LocaleId;
supportedTokens?: SupportedTokens;
theme?: Theme | "light" | "dark";
}
| false;
};
/**
* A hook to send a transaction.
* @returns A mutation object to send a transaction.
* @param config Configuration for the `useSendTransaction` hook.
* Refer to [`SendTransactionConfig`](https://portal.thirdweb.com/references/typescript/v5/SendTransactionConfig) for more details.
* @example
* ```tsx
* import { useSendTransaction } from "thirdweb/react";
* const { mutate: sendTx, data: transactionResult } = useSendTransaction();
*
* // later
* sendTx(tx);
* ```
*
* @transaction
*/
export function useSendTransaction(config: SendTransactionConfig = {}) {
const payModal = config.payModal;
const setRootEl = useContext(SetRootElementContext);
return useSendTransactionCore(
typeof payModal === "object"
? (data) => {
setRootEl(
<TxModal
tx={data.tx}
onComplete={data.sendTx}
onClose={() => {
setRootEl(null);
data.rejectTx();
}}
client={data.tx.client}
localeId={payModal?.locale || "en_US"}
supportedTokens={payModal?.supportedTokens || defaultTokens}
theme={payModal?.theme || "dark"}
txCostWei={data.totalCostWei}
walletBalanceWei={data.walletBalance.value}
nativeTokenSymbol={data.walletBalance.symbol}
/>,
);
}
: undefined,
);
}
type ModalProps = {
onComplete: () => void;
onClose: () => void;
client: ThirdwebClient;
localeId: LocaleId;
supportedTokens: SupportedTokens;
theme: Theme | "light" | "dark";
txCostWei: bigint;
walletBalanceWei: bigint;
nativeTokenSymbol: string;
tx: PreparedTransaction;
};
function TxModal(props: ModalProps) {
return (
<CustomThemeProvider theme={props.theme}>
<Modal
open={true}
size="compact"
setOpen={(_open) => {
if (!_open) {
props.onClose();
}
}}
>
<ModalContent {...props} />
</Modal>
</CustomThemeProvider>
);
}
function ModalContent(props: ModalProps) {
const localeQuery = useConnectLocale(props.localeId);
const [screen, setScreen] = useState<"buy" | "tx-history">("buy");
if (!localeQuery.data) {
return <LoadingScreen />;
}
if (screen === "tx-history") {
return (
<SwapTransactionsScreen
client={props.client}
onBack={() => {
props.onClose();
}}
/>
);
}
return (
<BuyScreen
client={props.client}
onBack={() => {
props.onClose();
}}
onViewPendingTx={() => {
setScreen("tx-history");
}}
supportedTokens={props.supportedTokens}
connectLocale={localeQuery.data}
buyForTx={{
balance: props.walletBalanceWei,
cost: props.txCostWei,
tx: props.tx,
tokenSymbol: props.nativeTokenSymbol,
}}
/>
);
}
@@ -1,5 +1,5 @@
import styled from "@emotion/styled";
import { useEffect, useMemo, useState } from "react";
import { useMemo } from "react";
import { AutoConnect } from "../../../core/hooks/connection/useAutoConnect.js";
import {
useActiveAccount,
@@ -19,7 +19,7 @@ import type { ConnectButtonProps } from "./ConnectWalletProps.js";
import { ConnectedWalletDetails } from "./Details.js";
import ConnectModal from "./Modal/ConnectModal.js";
import { defaultTokens } from "./defaultTokens.js";
import { getConnectLocale } from "./locale/getConnectLocale.js";
import { useConnectLocale } from "./locale/getConnectLocale.js";
import type { ConnectLocale } from "./locale/types.js";
const TW_CONNECT_WALLET = "tw-connect-wallet";
@@ -41,12 +41,7 @@ const TW_CONNECT_WALLET = "tw-connect-wallet";
*/
export function ConnectButton(props: ConnectButtonProps) {
const wallets = props.wallets || getDefaultWallets();
const localeId = props.locale || "en_US";
const [locale, setLocale] = useState<ConnectLocale | undefined>();
useEffect(() => {
getConnectLocale(localeId).then(setLocale);
}, [localeId]);
const localeQuery = useConnectLocale(props.locale || "en_US");
const autoConnectComp = props.autoConnect !== false && (
<AutoConnect
@@ -62,7 +57,7 @@ export function ConnectButton(props: ConnectButtonProps) {
/>
);
if (!locale) {
if (!localeQuery.data) {
return (
<AnimatedButton
disabled={true}
@@ -89,7 +84,7 @@ export function ConnectButton(props: ConnectButtonProps) {
client: props.client,
wallets: wallets,
locale: props.locale || "en_US",
connectLocale: locale,
connectLocale: localeQuery.data,
chain: props.chain,
chains: props.chains,
walletConnect: props.walletConnect,
@@ -108,7 +103,7 @@ export function ConnectButton(props: ConnectButtonProps) {
}}
>
<WalletUIStatesProvider theme={props.theme}>
<ConnectButtonInner {...props} connectLocale={locale} />
<ConnectButtonInner {...props} connectLocale={localeQuery.data} />
<ConnectModal />
{autoConnectComp}
</WalletUIStatesProvider>

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