Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7ff46a50d2 | ||
|
|
0c97d7965e | ||
|
|
4a87109289 | ||
|
|
dddf95daca | ||
|
|
06cd6a62d9 |
@@ -93,4 +93,7 @@ UNTHREAD_GROWTH_TIER_ID=""
|
||||
UNTHREAD_PRO_TIER_ID=""
|
||||
|
||||
# Demo Engine
|
||||
NEXT_PUBLIC_DEMO_ENGINE_URL=""
|
||||
NEXT_PUBLIC_DEMO_ENGINE_URL=""
|
||||
|
||||
# API server secret (required for thirdweb.com SIWE login)
|
||||
API_SERVER_SECRET=""
|
||||
@@ -13,34 +13,46 @@ import type {
|
||||
const THIRDWEB_API_HOST =
|
||||
process.env.NEXT_PUBLIC_THIRDWEB_API_HOST || "https://api.thirdweb.com";
|
||||
|
||||
const THIRDWEB_API_SECRET = process.env.API_SERVER_SECRET || "";
|
||||
|
||||
export async function getLoginPayload(
|
||||
params: GenerateLoginPayloadParams,
|
||||
): Promise<LoginPayload> {
|
||||
const res = await fetch(`${THIRDWEB_API_HOST}/v1/auth/payload`, {
|
||||
if (!THIRDWEB_API_SECRET) {
|
||||
throw new Error("API_SERVER_SECRET is not set");
|
||||
}
|
||||
const res = await fetch(`${THIRDWEB_API_HOST}/v2/siwe/payload`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"x-service-api-key": THIRDWEB_API_SECRET,
|
||||
},
|
||||
body: JSON.stringify({
|
||||
address: params.address,
|
||||
chainId: params.chainId?.toString(),
|
||||
}),
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
console.error("Failed to fetch login payload", res.status, res.statusText);
|
||||
throw new Error("Failed to fetch login payload");
|
||||
}
|
||||
return (await res.json()).payload;
|
||||
return (await res.json()).data.payload;
|
||||
}
|
||||
|
||||
export async function doLogin(payload: VerifyLoginPayloadParams) {
|
||||
if (!THIRDWEB_API_SECRET) {
|
||||
throw new Error("API_SERVER_SECRET is not set");
|
||||
}
|
||||
|
||||
// forward the request to the API server
|
||||
const res = await fetch(`${THIRDWEB_API_HOST}/v1/auth/login`, {
|
||||
const res = await fetch(`${THIRDWEB_API_HOST}/v2/siwe/login`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"x-service-api-key": THIRDWEB_API_SECRET,
|
||||
},
|
||||
body: JSON.stringify({ payload }),
|
||||
body: JSON.stringify(payload),
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
@@ -67,7 +79,9 @@ export async function doLogin(payload: VerifyLoginPayloadParams) {
|
||||
|
||||
const json = await res.json();
|
||||
|
||||
if (!json.token) {
|
||||
const jwt = json.data.jwt;
|
||||
|
||||
if (!jwt) {
|
||||
console.error("Failed to login - invalid json", json);
|
||||
throw new Error("Failed to login - invalid json");
|
||||
}
|
||||
@@ -77,7 +91,7 @@ export async function doLogin(payload: VerifyLoginPayloadParams) {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: `Bearer ${json.token}`,
|
||||
Authorization: `Bearer ${jwt}`,
|
||||
},
|
||||
});
|
||||
// if we do not have a user, create one
|
||||
@@ -85,7 +99,7 @@ export async function doLogin(payload: VerifyLoginPayloadParams) {
|
||||
const newUserRes = await fetch(`${THIRDWEB_API_HOST}/v1/account/create`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${json.token}`,
|
||||
Authorization: `Bearer ${jwt}`,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -104,7 +118,7 @@ export async function doLogin(payload: VerifyLoginPayloadParams) {
|
||||
// set the token cookie
|
||||
cookieStore.set(
|
||||
COOKIE_PREFIX_TOKEN + getAddress(payload.payload.address),
|
||||
json.token,
|
||||
jwt,
|
||||
{
|
||||
httpOnly: true,
|
||||
secure: true,
|
||||
|
||||
+12
@@ -394,6 +394,16 @@ export const CustomContractForm: React.FC<CustomContractFormProps> = ({
|
||||
});
|
||||
}
|
||||
|
||||
// handle split things
|
||||
const payees: string[] = [];
|
||||
const shares: string[] = [];
|
||||
if (isSplit && params.recipients?.length) {
|
||||
for (const recipient of params.recipients) {
|
||||
payees.push(recipient.address);
|
||||
shares.push(recipient.sharesBps.toString());
|
||||
}
|
||||
}
|
||||
|
||||
if (metadata.name === "MarketplaceV3") {
|
||||
// special case for marketplace
|
||||
return await deployMarketplaceContract({
|
||||
@@ -416,6 +426,8 @@ export const CustomContractForm: React.FC<CustomContractFormProps> = ({
|
||||
const initializeParams = {
|
||||
...params.contractMetadata,
|
||||
...params.deployParams,
|
||||
payees,
|
||||
shares,
|
||||
_contractURI,
|
||||
};
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ import ThirdwebProvider from "@/components/thirdweb-provider";
|
||||
import { metadataBase } from "@/lib/constants";
|
||||
import type { Metadata } from "next";
|
||||
import { APIHeader } from "../../../components/blocks/APIHeader";
|
||||
import { SponsoredInAppTxPreview } from "../../../components/in-app-wallet/sponsored-tx";
|
||||
import { StyledConnectEmbed } from "../../../components/styled-connect-embed";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
@@ -35,9 +34,10 @@ export default function Page() {
|
||||
|
||||
<div className="h-14" />
|
||||
|
||||
<section className="space-y-8">
|
||||
{/* TODO: put this in its own section with inapp smart wallet enabled
|
||||
<section className="space-y-8">
|
||||
<SponsoredInAppTx />
|
||||
</section>
|
||||
</section> */}
|
||||
</main>
|
||||
</ThirdwebProvider>
|
||||
);
|
||||
@@ -85,44 +85,43 @@ function AnyAuth() {
|
||||
);
|
||||
}
|
||||
|
||||
function SponsoredInAppTx() {
|
||||
return (
|
||||
<>
|
||||
<div className="space-y-2">
|
||||
<h2 className="text-2xl sm:text-3xl font-semibold tracking-tight">
|
||||
Signless Sponsored Transactions
|
||||
</h2>
|
||||
<p className="max-w-[600px]">
|
||||
With in-app wallets, users don't need to confirm every
|
||||
transaction.
|
||||
<br />
|
||||
Combine it with smart account flag to cover gas costs for the best UX.
|
||||
</p>
|
||||
</div>
|
||||
<CodeExample
|
||||
preview={<SponsoredInAppTxPreview />}
|
||||
code={`import { inAppWallet } from "thirdweb/wallets";
|
||||
import { claimTo } from "thirdweb/extensions/erc1155";
|
||||
import { ConnectButton, TransactionButton } from "thirdweb/react";
|
||||
// function SponsoredInAppTx() {
|
||||
// return (
|
||||
// <>
|
||||
// <div className="space-y-2">
|
||||
// <h2 className="text-2xl sm:text-3xl font-semibold tracking-tight">
|
||||
// Signless Sponsored Transactions
|
||||
// </h2>
|
||||
// <p className="max-w-[600px]">
|
||||
// With in-app wallets, users don't need to confirm every
|
||||
// transaction.
|
||||
// <br />
|
||||
// Combine it with smart account flag to cover gas costs for the best UX.
|
||||
// </p>
|
||||
// </div>
|
||||
// <CodeExample
|
||||
// preview={<SponsoredInAppTxPreview />}
|
||||
// code={`import { inAppWallet } from "thirdweb/wallets";
|
||||
// import { claimTo } from "thirdweb/extensions/erc1155";
|
||||
// import { ConnectButton, TransactionButton } from "thirdweb/react";
|
||||
|
||||
// const wallets = [
|
||||
// inAppWallet(
|
||||
// // turn on gas sponsorship for in-app wallets
|
||||
// { smartAccount: { chain, sponsorGas: true }}
|
||||
// )
|
||||
// ];
|
||||
|
||||
const wallets = [
|
||||
inAppWallet(
|
||||
// turn on gas sponsorship for in-app wallets
|
||||
{ smartAccount: { chain, sponsorGas: true }}
|
||||
)
|
||||
];
|
||||
// function App(){
|
||||
// return (<>
|
||||
// <ConnectButton client={client} wallets={wallets} />
|
||||
|
||||
function App(){
|
||||
return (<>
|
||||
<ConnectButton client={client} wallets={wallets} />
|
||||
|
||||
{/* signless, sponsored transactions */}
|
||||
<TransactionButton transaction={() => claimTo({ contract, to: "0x123...", tokenId: 0n, quantity: 1n })}>Mint</TransactionButton>
|
||||
</>);
|
||||
};`}
|
||||
lang="tsx"
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
// {/* signless, sponsored transactions */}
|
||||
// <TransactionButton transaction={() => claimTo({ contract, to: "0x123...", tokenId: 0n, quantity: 1n })}>Mint</TransactionButton>
|
||||
// </>);
|
||||
// };`}
|
||||
// lang="tsx"
|
||||
// />
|
||||
// </>
|
||||
// );
|
||||
// }
|
||||
|
||||
@@ -2,6 +2,13 @@
|
||||
|
||||
import { THIRDWEB_CLIENT } from "@/lib/client";
|
||||
import { useTheme } from "next-themes";
|
||||
import {
|
||||
arbitrumSepolia,
|
||||
baseSepolia,
|
||||
optimismSepolia,
|
||||
polygonAmoy,
|
||||
sepolia,
|
||||
} from "thirdweb/chains";
|
||||
import { ConnectButton } from "thirdweb/react";
|
||||
import type { ConnectButtonProps } from "thirdweb/react";
|
||||
import { WALLETS } from "../lib/constants";
|
||||
@@ -13,6 +20,13 @@ export function StyledConnectButton(
|
||||
|
||||
return (
|
||||
<ConnectButton
|
||||
chains={[
|
||||
sepolia,
|
||||
baseSepolia,
|
||||
optimismSepolia,
|
||||
polygonAmoy,
|
||||
arbitrumSepolia,
|
||||
]}
|
||||
wallets={WALLETS}
|
||||
supportedNFTs={{
|
||||
"84532": ["0x638263e3eAa3917a53630e61B1fBa685308024fa"],
|
||||
|
||||
@@ -2,6 +2,13 @@
|
||||
|
||||
import { THIRDWEB_CLIENT } from "@/lib/client";
|
||||
import { useTheme } from "next-themes";
|
||||
import {
|
||||
arbitrumSepolia,
|
||||
baseSepolia,
|
||||
optimismSepolia,
|
||||
polygonAmoy,
|
||||
sepolia,
|
||||
} from "thirdweb/chains";
|
||||
import {
|
||||
ConnectEmbed,
|
||||
type ConnectEmbedProps,
|
||||
@@ -22,6 +29,13 @@ export function StyledConnectEmbed(
|
||||
</div>
|
||||
) : (
|
||||
<ConnectEmbed
|
||||
chains={[
|
||||
sepolia,
|
||||
baseSepolia,
|
||||
optimismSepolia,
|
||||
polygonAmoy,
|
||||
arbitrumSepolia,
|
||||
]}
|
||||
wallets={WALLETS}
|
||||
client={THIRDWEB_CLIENT}
|
||||
theme={theme === "light" ? "light" : "dark"}
|
||||
|
||||
@@ -14,6 +14,15 @@ const getDomain = () => {
|
||||
return undefined;
|
||||
};
|
||||
|
||||
// const getEcosystem = () => {
|
||||
// if (process.env.NEXT_PUBLIC_IN_APP_WALLET_URL?.endsWith(".thirdweb.com")) {
|
||||
// // prod ecosystem
|
||||
// return "ecosystem.new-age";
|
||||
// }
|
||||
// // dev ecosystem
|
||||
// return "ecosystem.bonfire-development";
|
||||
// };
|
||||
|
||||
export const WALLETS = [
|
||||
createWallet("inApp", {
|
||||
auth: {
|
||||
@@ -31,6 +40,7 @@ export const WALLETS = [
|
||||
passkeyDomain: getDomain(),
|
||||
},
|
||||
}),
|
||||
// ecosystemWallet(getEcosystem()), TODO put this in its own section
|
||||
createWallet("io.metamask"),
|
||||
createWallet("com.coinbase.wallet"),
|
||||
createWallet("io.rabby"),
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
# thirdweb
|
||||
|
||||
## 5.57.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#4696](https://github.com/thirdweb-dev/js/pull/4696) [`0c97d79`](https://github.com/thirdweb-dev/js/commit/0c97d7965e3f681cd1fe2e1c79ecc6897ad52b9c) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Fix default chain when using redirect mode + default to first passed chains if available
|
||||
|
||||
- [#4693](https://github.com/thirdweb-dev/js/pull/4693) [`4a87109`](https://github.com/thirdweb-dev/js/commit/4a87109289e6ece5f6f08c55160e5d4e11e034e4) Thanks [@jnsdls](https://github.com/jnsdls)! - fix `getClaimConditions` extension for erc20, erc721 and erc1155
|
||||
|
||||
## 5.57.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "thirdweb",
|
||||
"version": "5.57.2",
|
||||
"version": "5.57.3",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/thirdweb-dev/js.git#main"
|
||||
|
||||
@@ -27,7 +27,7 @@ export async function getClaimConditions(
|
||||
const conditionPromises: Array<
|
||||
ReturnType<typeof MultiById.getClaimConditionById>
|
||||
> = [];
|
||||
for (let i = startId; i < count; i++) {
|
||||
for (let i = startId; i < startId + count; i++) {
|
||||
conditionPromises.push(
|
||||
MultiById.getClaimConditionById({
|
||||
...options,
|
||||
|
||||
@@ -24,7 +24,7 @@ export async function getClaimConditions(
|
||||
const conditionPromises: Array<
|
||||
ReturnType<typeof MultiById.getClaimConditionById>
|
||||
> = [];
|
||||
for (let i = startId; i < count; i++) {
|
||||
for (let i = startId; i < startId + count; i++) {
|
||||
conditionPromises.push(
|
||||
MultiById.getClaimConditionById({
|
||||
...options,
|
||||
|
||||
@@ -24,7 +24,7 @@ export async function getClaimConditions(
|
||||
const conditionPromises: Array<
|
||||
ReturnType<typeof MultiById.getClaimConditionById>
|
||||
> = [];
|
||||
for (let i = startId; i < count; i++) {
|
||||
for (let i = startId; i < startId + count; i++) {
|
||||
conditionPromises.push(
|
||||
MultiById.getClaimConditionById({
|
||||
...options,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { Chain } from "../../../../chains/types.js";
|
||||
import type { ThirdwebClient } from "../../../../client/client.js";
|
||||
import type { Wallet } from "../../../../wallets/interfaces/wallet.js";
|
||||
import type { SmartWalletOptions } from "../../../../wallets/smart/types.js";
|
||||
@@ -107,4 +108,9 @@ export type AutoConnectProps = {
|
||||
* ```
|
||||
*/
|
||||
onConnect?: (wallet: Wallet) => void;
|
||||
|
||||
/**
|
||||
* Optional chain to autoconnect to
|
||||
*/
|
||||
chain?: Chain;
|
||||
};
|
||||
|
||||
@@ -56,7 +56,10 @@ export function useAutoConnectCore(
|
||||
return autoConnected;
|
||||
}
|
||||
|
||||
const lastConnectedChain = await getLastConnectedChain(storage);
|
||||
// this flow can actually be used for a first connection in the case of a redirect
|
||||
// in that case, we default to the passed chain to connect to
|
||||
const lastConnectedChain =
|
||||
(await getLastConnectedChain(storage)) || props.chain;
|
||||
|
||||
async function handleWalletConnection(wallet: Wallet) {
|
||||
return wallet.autoConnect({
|
||||
|
||||
@@ -293,8 +293,12 @@ export function ConnectButton(props: ConnectButtonProps) {
|
||||
: props.connectModal?.size || "compact";
|
||||
}, [wallets.length, props.connectModal?.size]);
|
||||
|
||||
const preferredChain =
|
||||
props.accountAbstraction?.chain || props.chain || props.chains?.[0];
|
||||
|
||||
const autoConnectComp = props.autoConnect !== false && (
|
||||
<AutoConnect
|
||||
chain={preferredChain}
|
||||
appMetadata={props.appMetadata}
|
||||
client={props.client}
|
||||
wallets={wallets}
|
||||
@@ -336,7 +340,7 @@ export function ConnectButton(props: ConnectButtonProps) {
|
||||
shouldSetActive={true}
|
||||
accountAbstraction={props.accountAbstraction}
|
||||
auth={props.auth}
|
||||
chain={props.chain || props.accountAbstraction?.chain}
|
||||
chain={preferredChain}
|
||||
chains={props.chains}
|
||||
client={props.client}
|
||||
connectLocale={localeQuery.data}
|
||||
|
||||
@@ -1073,7 +1073,7 @@ function InAppWalletUserInfo(props: {
|
||||
}
|
||||
return walletInfo?.name;
|
||||
},
|
||||
enabled: !!activeWallet?.id,
|
||||
enabled: !!activeWallet?.id && !!walletInfo,
|
||||
});
|
||||
|
||||
const userInfoQuery = useQuery({
|
||||
|
||||
@@ -238,8 +238,12 @@ export function ConnectEmbed(props: ConnectEmbedProps) {
|
||||
props.requireApproval,
|
||||
]);
|
||||
|
||||
const preferredChain =
|
||||
props.accountAbstraction?.chain || props.chain || props.chains?.[0];
|
||||
|
||||
const autoConnectComp = props.autoConnect !== false && (
|
||||
<AutoConnect
|
||||
chain={preferredChain}
|
||||
appMetadata={props.appMetadata}
|
||||
client={props.client}
|
||||
wallets={wallets}
|
||||
@@ -272,7 +276,7 @@ export function ConnectEmbed(props: ConnectEmbedProps) {
|
||||
<ConnectEmbedContent
|
||||
auth={props.auth}
|
||||
accountAbstraction={props.accountAbstraction}
|
||||
chain={props.chain || props.accountAbstraction?.chain}
|
||||
chain={preferredChain}
|
||||
chains={props.chains}
|
||||
client={props.client}
|
||||
connectLocale={localeQuery.data}
|
||||
|
||||
@@ -104,6 +104,7 @@ export function createInAppWallet(args: {
|
||||
createOptions,
|
||||
connector,
|
||||
);
|
||||
|
||||
// set the states
|
||||
client = options.client;
|
||||
account = connectedAccount;
|
||||
|
||||
Reference in New Issue
Block a user