Compare commits
20
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b4df56f40f | ||
|
|
4a6eed5d99 | ||
|
|
a54c745977 | ||
|
|
0c95e80665 | ||
|
|
31b6a4ffe1 | ||
|
|
4f2a3fb1f1 | ||
|
|
37bd0e42a5 | ||
|
|
f5abbe8b54 | ||
|
|
b1d9e4aa97 | ||
|
|
5398d6813e | ||
|
|
bf0509e746 | ||
|
|
7c178923f9 | ||
|
|
300e4c8a51 | ||
|
|
8cb8a74002 | ||
|
|
dc7ea82f8a | ||
|
|
8541709359 | ||
|
|
76f93a4346 | ||
|
|
4c7153c95d | ||
|
|
2fd9c92c49 | ||
|
|
2de2b69934 |
@@ -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
|
||||
|
||||
@@ -20,7 +20,7 @@ env:
|
||||
|
||||
jobs:
|
||||
release-artifacts:
|
||||
timeout-minutes: 15
|
||||
timeout-minutes: 60
|
||||
runs-on: ubuntu-latest-16
|
||||
steps:
|
||||
- name: Checkout branch
|
||||
|
||||
@@ -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,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": {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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,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,
|
||||
|
||||
@@ -26,6 +26,6 @@ export default {
|
||||
],
|
||||
"shortName": "okb",
|
||||
"slug": "x-layer",
|
||||
"status": "incubating",
|
||||
"status": "active",
|
||||
"testnet": false
|
||||
} as const satisfies Chain;
|
||||
@@ -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;
|
||||
@@ -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",
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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": {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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": {
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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": {
|
||||
|
||||
@@ -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": {
|
||||
|
||||
@@ -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;
|
||||
@@ -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": {
|
||||
|
||||
@@ -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;
|
||||
@@ -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": {
|
||||
|
||||
@@ -33,7 +33,7 @@ export default {
|
||||
"name": "Vanguard",
|
||||
"nativeCurrency": {
|
||||
"name": "Vanguard Vanry",
|
||||
"symbol": "VG",
|
||||
"symbol": "VANRY",
|
||||
"decimals": 18
|
||||
},
|
||||
"networkId": 78600,
|
||||
|
||||
@@ -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"
|
||||
],
|
||||
|
||||
@@ -34,5 +34,6 @@ export default {
|
||||
],
|
||||
"shortName": "karak-sepolia",
|
||||
"slug": "karak-sepolia",
|
||||
"testnet": false
|
||||
"testnet": true,
|
||||
"title": "Karak Testnet Sepolia"
|
||||
} as const satisfies Chain;
|
||||
@@ -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,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
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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,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",
|
||||
|
||||
@@ -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,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",
|
||||
|
||||
@@ -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,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",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,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";
|
||||
}
|
||||
|
||||
@@ -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,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
@@ -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",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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": {
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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,
|
||||
});
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user