Compare commits

...
Author SHA1 Message Date
Jonas DanielsGitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>GitHub Action
4dea4ba3c0 Version Packages (#3900)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: GitHub Action <[email protected]>
2024-08-02 08:02:39 +12:00
Jonas DanielsandGitHub a66071b2c2 [Fix] Correct integer check logic in middleware function (#3905) 2024-08-01 12:20:15 -07:00
gregfromstl 306f3da606 fix(thirdweb): resolve occasional iframe error during OAuth login (#3903)
### TL;DR
Fix occasional iframe error when logging in with oauth

### What changed?
Removed error throwing for invalid event type in OAuth login flow.

### How to test?
Attempt OAuth login and ensure no errors occur related to iframes.

### Why make this change?
To prevent unnecessary exceptions which impede the OAuth login user experience.

---
2024-08-01 18:56:12 +00:00
Manan TankandGitHub e6495c1541 Remove ja_JP locale set in playground for ConnectButton (#3904) 2024-08-02 06:23:16 +12:00
Joaquim VergesandGitHub 825ef239a0 fix(gas): handle gas free chains where baseFeePerGas is 0 (#3901) 2024-08-01 21:30:09 +12:00
joaquim-verges 13d9741f77 feat(localization): Add Korean and French locale support (#3895)
## Problem solved

Short description of the bug fixed or feature added

<!-- start pr-codex -->

---

## PR-Codex overview
This PR adds Korean and French locales, updates wallet connection screens, and adds smart wallet content.

### Detailed summary
- Added Korean and French locales
- Updated wallet connection screens with new locales
- Added smart wallet content for Korean locale

> The following files were skipped due to too many changes: `packages/thirdweb/src/react/web/wallets/local/locale/kr.ts`, `packages/thirdweb/src/react/web/wallets/shared/locale/kr.ts`, `packages/thirdweb/src/react/web/wallets/local/locale/fr.ts`, `packages/thirdweb/src/react/web/wallets/local/locale/ja.ts`, `packages/thirdweb/src/react/web/wallets/shared/locale/ja.ts`, `packages/thirdweb/src/react/web/wallets/shared/locale/fr.ts`, `packages/thirdweb/src/react/web/ui/ConnectWallet/locale/kr.ts`, `packages/thirdweb/src/react/web/ui/ConnectWallet/locale/fr.ts`

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->
2024-08-01 08:07:23 +00:00
Jonas DanielsGitHubgithub-actions[bot] <github-actions[bot]@users.noreply.github.com>
94f5ed601d Version Packages (#3898)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-07-31 23:24:25 -07:00
Jonas DanielsandGitHub 4463848671 [Fix] Remove 'create' command from key-requiring CLI commands (#3897) 2024-07-31 23:10:54 -07:00
gregandGitHub 3b49b18f4d fix(react): OTP validation in React Native Connect UI (#3896) 2024-07-31 23:10:43 -07:00
Joaquim VergesandGitHub 2e0ca0ecee feat(webGL): Update CB wallet v4 for webGL (#3893) 2024-08-01 13:25:05 +12:00
MananTank ff6a319caf Map generic inputs to prebuilt components for Modular Contract install params fiedsets (#3887)
<!-- start pr-codex -->

## PR-Codex overview
The focus of this PR is to update contract form components with improved form handling and modular extension support.

### Detailed summary
- Added `isBeta` prop to `ContractCard` and `publishedContractToShow` check
- Updated `PrimarySaleFieldset` and `RoyaltyFieldset` with improved form handling
- Enhanced modular extension support in `ModularContractDefaultExtensionsFieldset`

> The following files were skipped due to too many changes: `apps/dashboard/src/components/contract-components/contract-deploy-form/modular-contract-default-extensions-fieldset.tsx`

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->
2024-07-31 23:23:41 +00:00
MananTank 744c570ed1 [dashboard] Use dark default Theme for first time users (#3890)
<!-- start pr-codex -->

## PR-Codex overview
This PR introduces a new `defaultTheme` prop set to "dark" in the `_app.tsx` file.

### Detailed summary
- Added `defaultTheme` prop with value "dark" in the `_app.tsx` file.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->
2024-07-31 22:08:51 +00:00
MananTank fff9550c8f [dashboard] Fix Spinner size in Add to wallet button in chain page (#3888)
## Problem solved

Short description of the bug fixed or feature added

<!-- start pr-codex -->

---

## PR-Codex overview
The focus of this PR is to update the styling of the "Add to wallet" button in the `add-chain-to-wallet.tsx` component.

### Detailed summary
- Updated the `className` of the button to include `gap-2` for spacing
- Adjusted the Spinner size with the class `size-3`

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->
2024-07-31 19:16:32 +00:00
63 changed files with 1067 additions and 470 deletions
@@ -41,13 +41,13 @@ export const AddChainToWallet: React.FC<AddChainToWalletProps> = (props) => {
!address || debouncedLoading || activeWalletChainId === props.chain?.id
}
className={cn(
"w-full md:min-w-40",
"w-full md:min-w-40 gap-2",
props.hasBackground && "invert dark:invert-0",
)}
onClick={() => switchChainMutation.mutate()}
>
{debouncedLoading && <Spinner />}
<span>Add to wallet</span>
{debouncedLoading && <Spinner className="size-3" />}
</Button>
);
@@ -16,6 +16,7 @@ import { AiOutlineWarning } from "@react-icons/all-files/ai/AiOutlineWarning";
import { useSDK, useSDKChainId } from "@thirdweb-dev/react";
import { useTrack } from "hooks/analytics/useTrack";
import { useSupportedChain } from "hooks/chains/configureChains";
import { useRouter } from "next/navigation";
import { forwardRef, useCallback, useMemo, useRef } from "react";
import { VscDebugDisconnect } from "react-icons/vsc";
import { localhost } from "thirdweb/chains";
@@ -30,6 +31,11 @@ import {
import { Button, type ButtonProps, Card, Heading, Text } from "tw-components";
import { defineDashboardChain } from "../../lib/v5-adapter";
const GAS_FREE_CHAINS = [
75513, // Geek verse testnet
75512, // Geek verse mainnet
];
function useNetworkMismatchAdapter() {
const walletChainId = useActiveWalletChain()?.id;
const v4SDKChainId = useSDKChainId();
@@ -56,7 +62,7 @@ export const MismatchButton = forwardRef<HTMLButtonElement, ButtonProps>(
const { isOpen, onOpen, onClose } = useDisclosure();
const trackEvent = useTrack();
const chainId = useActiveWalletChain()?.id;
const chainId = activeWalletChain?.id;
const chainInfo = useSupportedChain(chainId || -1);
const eventRef = useRef<React.MouseEvent<HTMLButtonElement, MouseEvent>>();
@@ -69,7 +75,10 @@ export const MismatchButton = forwardRef<HTMLButtonElement, ButtonProps>(
/>
);
}
const shouldShowEVMFaucet = (evmBalance.data?.value || 0n) === 0n;
const shouldShowEVMFaucet =
chainId &&
(evmBalance.data?.value || 0n) === 0n &&
!GAS_FREE_CHAINS.includes(chainId);
return (
<Popover
initialFocusRef={initialFocusRef}
@@ -239,11 +248,10 @@ const NoFundsNotice: React.FC<NoFundsNoticeProps> = ({ symbol }) => {
const sdk = useSDK();
const chainId = useActiveWalletChain()?.id;
const chainInfo = useSupportedChain(chainId || -1);
const router = useRouter();
const hasFaucet =
chainInfo &&
(chainInfo.chainId === localhost.id ||
(chainInfo.faucets && chainInfo.faucets.length > 0));
chainInfo && (chainInfo.chainId === localhost.id || chainInfo.testnet);
const requestFunds = async () => {
if (sdk && hasFaucet) {
@@ -254,9 +262,8 @@ const NoFundsNotice: React.FC<NoFundsNoticeProps> = ({ symbol }) => {
});
if (chainInfo.chainId === localhost.id) {
await sdk.wallet.requestFunds(10);
} else if (chainInfo?.faucets && chainInfo.faucets.length > 0) {
const faucet = chainInfo.faucets[0];
window.open(faucet, "_blank");
} else if (chainInfo?.testnet) {
router.push(`/${chainInfo.chainId}/faucet`);
}
}
};
@@ -24,6 +24,7 @@ import { useRouter } from "next/router";
import { useMemo } from "react";
import { FormProvider, type UseFormReturn, useForm } from "react-hook-form";
import { FiHelpCircle } from "react-icons/fi";
import { useActiveAccount } from "thirdweb/react";
import { encodeAbiParameters } from "thirdweb/utils";
import invariant from "tiny-invariant";
import {
@@ -50,6 +51,8 @@ import {
import { ContractMetadataFieldset } from "./contract-metadata-fieldset";
import {
ModularContractDefaultExtensionsFieldset,
showPrimarySaleFiedset,
showRoyaltyFieldset,
useModularContractsDefaultExtensionsInstallParams,
} from "./modular-contract-default-extensions-fieldset";
import { Param } from "./param";
@@ -102,6 +105,7 @@ const CustomContractForm: React.FC<CustomContractFormProps> = ({
const ensQuery = useEns(walletAddress);
const connectedWallet = ensQuery.data?.address || walletAddress;
const trackEvent = useTrack();
const activeAccount = useActiveAccount();
const compilerMetadata = useContractPublishMetadataFromURI(ipfsHash);
const fullPublishMetadata = useContractFullPublishMetadata(ipfsHash);
@@ -119,6 +123,9 @@ const CustomContractForm: React.FC<CustomContractFormProps> = ({
Number(customFactoryNetwork),
);
const isTWPublisher =
fullPublishMetadata.data?.publisher === "deployer.thirdweb.eth";
const initializerParams = useFunctionParamsFromABI(
fullPublishMetadata.data?.deployType === "customFactory" &&
customFactoryAbi?.data
@@ -198,9 +205,36 @@ const CustomContractForm: React.FC<CustomContractFormProps> = ({
signerAsSalt: true,
deployParams: parsedDeployParams,
recipients: [{ address: connectedWallet || "", sharesBps: 10000 }],
modularContractDefaultExtensionsInstallParams: [],
// set default values for modular contract extensions with custom components
modularContractDefaultExtensionsInstallParams:
(activeAccount &&
isTWPublisher &&
modularContractDefaultExtensionsInstallParams.data?.map((ext) => {
const paramNames = ext.params.map((param) => param.name);
const returnVal: Record<string, string> = {};
// set connected wallet address as default "royaltyRecipient"
if (showRoyaltyFieldset(paramNames)) {
returnVal.royaltyRecipient = activeAccount.address;
}
// set connected wallet address as default "primarySaleRecipient"
else if (showPrimarySaleFiedset(paramNames)) {
returnVal.primarySaleRecipient = activeAccount.address;
}
return returnVal;
})) ||
[],
}),
[parsedDeployParams, isAccountFactory, connectedWallet],
[
parsedDeployParams,
isAccountFactory,
connectedWallet,
modularContractDefaultExtensionsInstallParams.data,
isTWPublisher,
activeAccount,
],
);
const form = useForm<CustomContractDeploymentFormData>({
@@ -439,8 +473,54 @@ const CustomContractForm: React.FC<CustomContractFormProps> = ({
metadata={compilerMetadata}
/>
)}
{hasRoyalty && <RoyaltyFieldset form={form} />}
{hasPrimarySale && <PrimarySaleFieldset form={form} />}
{hasRoyalty && (
<RoyaltyFieldset
royaltyRecipient={{
isInvalid: !!form.getFieldState(
"deployParams._royaltyRecipient",
form.formState,
).error,
register: form.register("deployParams._royaltyRecipient"),
errorMessage: form.getFieldState(
"deployParams._royaltyRecipient",
form.formState,
).error?.message,
}}
royaltyBps={{
value: form.watch("deployParams._royaltyBps"),
isInvalid: !!form.getFieldState(
"deployParams._royaltyBps",
form.formState,
).error,
setValue: (v) => {
form.setValue("deployParams._royaltyBps", v, {
shouldTouch: true,
});
},
errorMessage: form.getFieldState(
"deployParams._royaltyBps",
form.formState,
).error?.message,
}}
/>
)}
{hasPrimarySale && (
<PrimarySaleFieldset
isInvalid={
!!form.getFieldState(
"deployParams._saleRecipient",
form.formState,
).error
}
register={form.register("deployParams._saleRecipient")}
errorMessage={
form.getFieldState(
"deployParams._saleRecipient",
form.formState,
).error?.message
}
/>
)}
{isSplit && <SplitFieldset form={form} />}
{hasTrustedForwarders && (
<TrustedForwardersFieldset form={form} />
@@ -485,9 +565,10 @@ const CustomContractForm: React.FC<CustomContractFormProps> = ({
{modularContractDefaultExtensionsInstallParams.data ? (
<ModularContractDefaultExtensionsFieldset
form={form}
installParams={
extensions={
modularContractDefaultExtensionsInstallParams.data
}
isTWPublisher={isTWPublisher}
/>
) : (
<div className="min-h-[250px] flex justify-center items-center">
@@ -5,6 +5,8 @@ import { getExtensionInstalledParams } from "contract-ui/tabs/manage/components/
import invariant from "tiny-invariant";
import { FormErrorMessage, FormLabel } from "tw-components";
import type { CustomContractDeploymentForm } from "./custom-contract";
import { PrimarySaleFieldset } from "./primary-sale-fieldset";
import { RoyaltyFieldset } from "./royalty-fieldset";
type ExtensionMeta = {
extensionName: string;
@@ -38,16 +40,19 @@ export type UseModularContractsDefaultExtensionsInstallParams = ReturnType<
typeof useModularContractsDefaultExtensionsInstallParams
>;
export function ModularContractDefaultExtensionsFieldset(props: {
installParams: NonNullable<
UseModularContractsDefaultExtensionsInstallParams["data"]
>;
form: CustomContractDeploymentForm;
}) {
const { form } = props;
type Extensions = NonNullable<
UseModularContractsDefaultExtensionsInstallParams["data"]
>;
type ExtensionWithIndex = Extensions[number] & { extensionIndex: number };
export function ModularContractDefaultExtensionsFieldset(props: {
extensions: Extensions;
form: CustomContractDeploymentForm;
isTWPublisher: boolean;
}) {
// save the index of the extension before filtering out
const installParams = props.installParams
const extensionsWithIndex: ExtensionWithIndex[] = props.extensions
.map((v, i) => ({
...v,
extensionIndex: i,
@@ -56,45 +61,163 @@ export function ModularContractDefaultExtensionsFieldset(props: {
return (
<div className="py-4">
<div className="flex flex-col gap-6">
{installParams.map((ext) => {
<div className="flex flex-col gap-4">
{extensionsWithIndex.map((ext) => {
return (
<div key={ext.extensionName}>
<h3 className="text-lg mb-4">{ext.extensionName}</h3>
<div className="flex flex-col gap-3">
{ext.params.map((param) => {
const formFieldKey =
`modularContractDefaultExtensionsInstallParams.${ext.extensionIndex}.${param.name}` as const;
return (
<FormControl
key={formFieldKey}
isRequired
isInvalid={
!!form.getFieldState(formFieldKey, form.formState).error
}
>
<FormLabel> {param.name}</FormLabel>
<SolidityInput
solidityType={param.type}
solidityComponents={param.components}
variant="filled"
{...form.register(formFieldKey)}
/>
<FormErrorMessage>
{
form.getFieldState(formFieldKey, form.formState).error
?.message
}
</FormErrorMessage>
</FormControl>
);
})}
</div>
</div>
<RenderExtension
key={ext.extensionName}
extension={ext}
isTWPublisher={props.isTWPublisher}
form={props.form}
/>
);
})}
</div>
</div>
);
}
function RenderExtension(props: {
extension: ExtensionWithIndex;
form: CustomContractDeploymentForm;
isTWPublisher: boolean;
}) {
const { extension, form } = props;
// only consider mapping if published by thirdweb, else show the generic form
if (props.isTWPublisher) {
const paramNames = extension.params.map((param) => param.name);
if (showRoyaltyFieldset(paramNames)) {
return (
<RenderRoyaltyFieldset
extension={extension}
form={form}
isTWPublisher
/>
);
}
if (showPrimarySaleFiedset(paramNames)) {
return (
<RenderPrimarySaleFieldset
extension={extension}
form={form}
isTWPublisher
/>
);
}
}
return (
<div>
<h3 className="text-lg mb-2 text-secondary-foreground font-medium">
{extension.extensionName}
</h3>
<div className="flex flex-col gap-3">
{extension.params.map((param) => {
const formFieldKey =
`modularContractDefaultExtensionsInstallParams.${extension.extensionIndex}.${param.name}` as const;
return (
<FormControl
key={formFieldKey}
isRequired
isInvalid={
!!form.getFieldState(formFieldKey, form.formState).error
}
>
<FormLabel> {param.name}</FormLabel>
<SolidityInput
solidityType={param.type}
solidityComponents={param.components}
variant="filled"
{...form.register(formFieldKey)}
/>
<FormErrorMessage>
{
form.getFieldState(formFieldKey, form.formState).error
?.message
}
</FormErrorMessage>
</FormControl>
);
})}
</div>
</div>
);
}
function RenderPrimarySaleFieldset(prosp: {
extension: ExtensionWithIndex;
form: CustomContractDeploymentForm;
isTWPublisher: boolean;
}) {
const { extension, form } = prosp;
const primarySaleRecipientPath =
`modularContractDefaultExtensionsInstallParams.${extension.extensionIndex}.primarySaleRecipient` as const;
return (
<PrimarySaleFieldset
isInvalid={
!!form.getFieldState(primarySaleRecipientPath, form.formState).error
}
register={form.register(primarySaleRecipientPath)}
errorMessage={
form.getFieldState(primarySaleRecipientPath, form.formState).error
?.message
}
/>
);
}
function RenderRoyaltyFieldset(props: {
extension: ExtensionWithIndex;
form: CustomContractDeploymentForm;
isTWPublisher: boolean;
}) {
const { extension: ext, form } = props;
const royaltyRecipientPath =
`modularContractDefaultExtensionsInstallParams.${ext.extensionIndex}.royaltyRecipient` as const;
const royaltyBpsPath =
`modularContractDefaultExtensionsInstallParams.${ext.extensionIndex}.royaltyBps` as const;
return (
<RoyaltyFieldset
royaltyRecipient={{
isInvalid: !!form.getFieldState(royaltyRecipientPath, form.formState)
.error,
register: form.register(royaltyRecipientPath, {
required: "Required",
}),
errorMessage: form.getFieldState(royaltyRecipientPath, form.formState)
.error?.message,
}}
royaltyBps={{
isInvalid: !!form.getFieldState(royaltyBpsPath, form.formState).error,
value: form.watch(royaltyBpsPath) || "0",
setValue: (value) =>
form.setValue(royaltyBpsPath, value, {
shouldTouch: true,
}),
errorMessage: form.getFieldState(royaltyBpsPath, form.formState).error
?.message,
}}
/>
);
}
export function showRoyaltyFieldset(paramNames: string[]) {
return (
paramNames.length === 2 &&
paramNames.includes("royaltyRecipient") &&
paramNames.includes("royaltyBps")
);
}
export function showPrimarySaleFiedset(paramNames: string[]) {
return paramNames.length === 1 && paramNames.includes("primarySaleRecipient");
}
@@ -1,15 +1,17 @@
import { Flex, FormControl } from "@chakra-ui/react";
import { SolidityInput } from "contract-ui/components/solidity-inputs";
import type { UseFormRegisterReturn } from "react-hook-form";
import { FormErrorMessage, FormLabel, Heading, Text } from "tw-components";
import type { CustomContractDeploymentForm } from "./custom-contract";
interface PrimarySaleFieldsetProps {
form: CustomContractDeploymentForm;
isInvalid: boolean;
register: UseFormRegisterReturn;
errorMessage: string | undefined;
}
export const PrimarySaleFieldset: React.FC<PrimarySaleFieldsetProps> = ({
form,
}) => {
export const PrimarySaleFieldset: React.FC<PrimarySaleFieldsetProps> = (
props,
) => {
return (
<Flex pb={4} direction="column" gap={2}>
<Heading size="label.lg">Primary Sales</Heading>
@@ -18,25 +20,14 @@ export const PrimarySaleFieldset: React.FC<PrimarySaleFieldsetProps> = ({
of the assets.
</Text>
<Flex gap={4} direction={{ base: "column", md: "row" }}>
<FormControl
isRequired
isInvalid={
!!form.getFieldState("deployParams._saleRecipient", form.formState)
.error
}
>
<FormControl isRequired isInvalid={props.isInvalid}>
<FormLabel>Recipient Address</FormLabel>
<SolidityInput
solidityType="address"
variant="filled"
{...form.register("deployParams._saleRecipient")}
{...props.register}
/>
<FormErrorMessage>
{
form.getFieldState("deployParams._saleRecipient", form.formState)
.error?.message
}
</FormErrorMessage>
<FormErrorMessage>{props.errorMessage}</FormErrorMessage>
</FormControl>
</Flex>
</Flex>
@@ -1,14 +1,23 @@
import { Flex, FormControl } from "@chakra-ui/react";
import { BasisPointsInput } from "components/inputs/BasisPointsInput";
import { SolidityInput } from "contract-ui/components/solidity-inputs";
import type { UseFormRegisterReturn } from "react-hook-form";
import { FormErrorMessage, FormLabel, Heading, Text } from "tw-components";
import type { CustomContractDeploymentForm } from "./custom-contract";
interface RoyaltyFieldsetProps {
form: CustomContractDeploymentForm;
}
export const RoyaltyFieldset: React.FC<RoyaltyFieldsetProps> = ({ form }) => {
export function RoyaltyFieldset(props: {
royaltyRecipient: {
isInvalid: boolean;
register: UseFormRegisterReturn;
errorMessage: string | undefined;
};
royaltyBps: {
isInvalid: boolean;
errorMessage: string | undefined;
value: string;
setValue: (value: string) => void;
};
}) {
const bpsNumValue = Number.parseInt(props.royaltyBps.value);
return (
<Flex pb={4} direction="column" gap={2}>
<Heading size="label.lg">Royalties</Heading>
@@ -17,57 +26,32 @@ export const RoyaltyFieldset: React.FC<RoyaltyFieldsetProps> = ({ form }) => {
earned from secondary sales of the assets.
</Text>
<Flex gap={4} direction={{ base: "column", md: "row" }}>
<FormControl
isRequired
isInvalid={
!!form.getFieldState(
"deployParams._royaltyRecipient",
form.formState,
).error
}
>
<FormControl isRequired isInvalid={props.royaltyRecipient.isInvalid}>
<FormLabel>Recipient Address</FormLabel>
<SolidityInput
solidityType="address"
variant="filled"
{...form.register("deployParams._royaltyRecipient")}
{...props.royaltyRecipient.register}
/>
<FormErrorMessage>
{
form.getFieldState(
"deployParams._royaltyRecipient",
form.formState,
).error?.message
}
{props.royaltyRecipient.errorMessage}
</FormErrorMessage>
</FormControl>
<FormControl
isRequired
maxW={{ base: "100%", md: "150px" }}
isInvalid={
!!form.getFieldState("deployParams._royaltyBps", form.formState)
.error
}
isInvalid={props.royaltyBps.isInvalid}
defaultValue="0"
>
<FormLabel>Percentage</FormLabel>
<BasisPointsInput
variant="filled"
value={Number.parseInt(form.watch("deployParams._royaltyBps"))}
onChange={(value) =>
form.setValue("deployParams._royaltyBps", value.toString(), {
shouldTouch: true,
})
}
value={Number.isNaN(bpsNumValue) ? 0 : bpsNumValue}
onChange={(value) => props.royaltyBps.setValue(value.toString())}
/>
<FormErrorMessage>
{
form.getFieldState("deployParams._royaltyBps", form.formState)
.error?.message
}
</FormErrorMessage>
<FormErrorMessage>{props.royaltyBps.errorMessage}</FormErrorMessage>
</FormControl>
</Flex>
</Flex>
);
};
}
@@ -53,11 +53,16 @@ export const PublishedBy: React.FC<PublishedByProps> = ({
return null;
}
console.log("publishedContractToShow", publishedContractToShow);
return (
<ContractCard
contractId={publishedContractToShow.name}
publisher={publisherAddress}
version={publishedContractToShow.version}
isBeta={(publishedContractToShow.displayName || "")
.toLowerCase()
.includes("beta")}
/>
);
};
@@ -25,7 +25,7 @@ interface ContractCardProps {
source: string;
itemIndex: `${number}`;
};
isBeta?: boolean;
isBeta: boolean | undefined;
}
export const ContractCard: React.FC<ContractCardProps> = ({
+6 -1
View File
@@ -51,7 +51,12 @@ export async function middleware(request: NextRequest) {
// if the first section of the path is a number, check if it's a valid chain_id and re-write it to the slug
const possibleChainId = Number(paths[0]);
if (Number.isInteger(possibleChainId) && possibleChainId !== 404) {
if (
possibleChainId &&
Number.isInteger(possibleChainId) &&
possibleChainId !== 404
) {
const possibleChain = defineChain(possibleChainId);
try {
const chainMetadata = await getChainMetadata(possibleChain);
+1
View File
@@ -289,6 +289,7 @@ function TailwindTheme(props: { children: React.ReactNode }) {
attribute="class"
disableTransitionOnChange
enableSystem={false}
defaultTheme="dark"
>
{props.children}
</ThemeProvider>
@@ -103,6 +103,7 @@ const ExploreCategoryPage: ThirdwebNextPage = (
source: props.category.id,
itemIndex: `${idx}`,
}}
isBeta={props.category.isBeta}
/>
);
})}
Binary file not shown.
@@ -48,6 +48,11 @@ import { RPCConnectionHandler } from "./rpc-connection-handler";
import { isBrowser } from "../../../common/utils";
import { detectFeatures } from "../../../common/feature-detection/detectFeatures";
const GAS_FREE_CHAINS = [
75513, // Geek verse testnet
75512, // Geek verse mainnet
];
/**
* @internal
*/
@@ -155,6 +160,14 @@ export class ContractWrapper<
* @internal
*/
public async getCallOverrides(): Promise<CallOverrides> {
const chainId = await this.getChainID();
// avoid ethers5 defaulting to 1.5gwei -> https://github.com/oasysgames/verse-layer-opstack?tab=readme-ov-file#why-doesnt-metamask-automatically-set-gas-to-zero
if(GAS_FREE_CHAINS.includes(chainId)) {
return {
maxFeePerGas: 0,
maxPriorityFeePerGas: 0,
};
}
// If we're running in the browser, let users configure gas price in their wallet UI
if (isBrowser()) {
return {};
Binary file not shown.
@@ -174,7 +174,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 = "4.17.0";
(globalThis as any).X_SDK_VERSION = "4.18.0";
// biome-ignore lint/suspicious/noExplicitAny: TODO: fix use of any
(globalThis as any).X_SDK_OS = browser?.os ?? "unknown";
}
+1 -1
View File
@@ -521,7 +521,7 @@
"dependencies": {
"@account-abstraction/contracts": "^0.5.0",
"@blocto/sdk": "0.10.2",
"@coinbase/wallet-sdk": "^3.9.0",
"@coinbase/wallet-sdk": "^4.0.4",
"@google-cloud/kms": "^4.4.0",
"@magic-ext/connect": "^6.7.2",
"@magic-ext/oauth": "^7.6.2",
@@ -11,11 +11,11 @@ declare global {
* @internal
*/
export function getInjectedCoin98Provider(): Ethereum | undefined {
const window = globalThis.window;
if (typeof window === "undefined") {
return;
}
if (assertWindowEthereum(globalThis.window)) {
if (assertWindowEthereum(window)) {
if (window.coin98) {
return window.ethereum;
}
@@ -6,18 +6,49 @@ import {
SwitchChainError,
ProviderRpcError,
} from "../../../lib/wagmi-core/errors";
import type {
CoinbaseWalletProvider,
CoinbaseWalletSDK,
import CoinbaseWalletSDK, {
ProviderInterface,
type Preference,
AppMetadata,
} from "@coinbase/wallet-sdk";
import type { CoinbaseWalletSDKOptions } from "@coinbase/wallet-sdk/dist/CoinbaseWalletSDK";
import type { Chain } from "@thirdweb-dev/chains";
import { providers, utils } from "ethers";
import { walletIds } from "../../constants/walletIds";
import { getValidPublicRPCUrl } from "../../utils/url";
import { normalizeChainId } from "../../../lib/wagmi-core/normalizeChainId";
type Options = CoinbaseWalletSDKOptions & {
type Options = {
/**
* Metadata of the dApp that will be passed to connected wallet.
*
* Some wallets may display this information to the user.
*
* Setting this property is highly recommended. If this is not set, Below default metadata will be used:
*
* ```ts
* {
* name: "thirdweb powered dApp",
* url: "https://thirdweb.com",
* description: "thirdweb powered dApp",
* logoUrl: "https://thirdweb.com/favicon.ico",
* };
* ```
*/
appMetadata?: AppMetadata;
/**
* Wallet configuration, choices are 'all' | 'smartWalletOnly' | 'eoaOnly'
* default is 'all'
* @example
* ```ts
* {
* walletConfig: {
* options: 'all',
* }
* }
* ```
*/
walletConfig?: Preference;
/**
* Fallback Ethereum JSON RPC URL
*
@@ -33,7 +64,7 @@ type Options = CoinbaseWalletSDKOptions & {
};
export class CoinbaseWalletConnector extends WagmiConnector<
CoinbaseWalletProvider,
ProviderInterface,
Options,
providers.JsonRpcSigner
> {
@@ -42,15 +73,12 @@ export class CoinbaseWalletConnector extends WagmiConnector<
readonly ready = true;
private _client?: CoinbaseWalletSDK;
private _provider?: CoinbaseWalletProvider;
private _provider?: ProviderInterface;
constructor({ chains, options }: { chains?: Chain[]; options: Options }) {
super({
chains,
options: {
reloadOnDisconnect: false,
...options,
},
options,
});
}
@@ -62,7 +90,9 @@ export class CoinbaseWalletConnector extends WagmiConnector<
this.emit("message", { type: "connecting" });
const accounts = await provider.enable();
const accounts = (await provider.request({
method: "eth_requestAccounts",
})) as string[];
const account = utils.getAddress(accounts[0] as string);
// Switch to chain if provided
let id = await this.getChainId();
@@ -108,8 +138,7 @@ export class CoinbaseWalletConnector extends WagmiConnector<
provider.removeListener("accountsChanged", this.onAccountsChanged);
provider.removeListener("chainChanged", this.onChainChanged);
provider.removeListener("disconnect", this.onDisconnect);
provider.disconnect();
provider.close();
await provider.disconnect();
}
async getAccount() {
@@ -127,52 +156,17 @@ export class CoinbaseWalletConnector extends WagmiConnector<
async getChainId() {
const provider = await this.getProvider();
const chainId = normalizeChainId(provider.chainId);
const connectedChainId = (await provider.request({
method: "eth_chainId",
})) as string | number;
const chainId = normalizeChainId(connectedChainId);
return chainId;
}
async getProvider() {
if (!this._provider) {
let CoinbaseWalletSDK = (await import("@coinbase/wallet-sdk")).default;
// Workaround for Vite dev import errors
// https://github.com/vitejs/vite/issues/7112
if (
typeof CoinbaseWalletSDK !== "function" &&
// @ts-expect-error This import error is not visible to TypeScript
typeof CoinbaseWalletSDK.default === "function"
) {
CoinbaseWalletSDK = (
CoinbaseWalletSDK as unknown as { default: typeof CoinbaseWalletSDK }
).default;
}
this._client = new CoinbaseWalletSDK(this.options);
/**
* Mock implementations to retrieve private `walletExtension` method
* from the Coinbase Wallet SDK.
*/
abstract class WalletProvider {
// https://github.com/coinbase/coinbase-wallet-sdk/blob/b4cca90022ffeb46b7bbaaab9389a33133fe0844/packages/wallet-sdk/src/provider/CoinbaseWalletProvider.ts#L927-L936
abstract getChainId(): number;
}
abstract class Client {
// https://github.com/coinbase/coinbase-wallet-sdk/blob/b4cca90022ffeb46b7bbaaab9389a33133fe0844/packages/wallet-sdk/src/CoinbaseWalletSDK.ts#L233-L235
abstract get walletExtension(): WalletProvider | undefined;
}
const walletExtensionChainId = (
this._client as unknown as Client
).walletExtension?.getChainId();
const chain =
this.chains.find((chain_) =>
this.options.chainId
? chain_.chainId === this.options.chainId
: chain_.chainId === walletExtensionChainId,
) || this.chains[0];
const chainId = this.options.chainId || chain?.chainId;
const jsonRpcUrl = this.options.jsonRpcUrl || chain?.rpc[0];
this._provider = this._client.makeWeb3Provider(jsonRpcUrl, chainId);
const client = new CoinbaseWalletSDK({ ...this.options.appMetadata });
this._provider = client.makeWeb3Provider(this.options?.walletConfig)
}
return this._provider;
}
@@ -290,6 +284,6 @@ export class CoinbaseWalletConnector extends WagmiConnector<
if (!this._client) {
throw new Error("Coinbase Wallet SDK not initialized");
}
return this._client.getQrUrl();
return ""; // TODO: implement in connect SDK
}
}
@@ -345,7 +345,7 @@ export class FrameConnector extends WagmiConnector<
}
private injectedProvider() {
return window?.ethereum as FrameInjectedProvider;
return (window as any)?.ethereum as FrameInjectedProvider;
}
private isInjected() {
@@ -148,10 +148,11 @@ export class CoinbaseWallet extends AbstractClientWallet {
const cbConnector = new CoinbaseWalletConnector({
chains: this.chains,
options: {
appName: this.dappMetadata.name,
reloadOnDisconnect: false,
darkMode: this.theme === "dark",
headlessMode: this.headlessMode,
appMetadata: {
appName: this.dappMetadata.name,
appLogoUrl: this.dappMetadata.logoUrl ?? null,
appChainIds: this.options?.chains?.map((c) => c.chainId) || [1],
},
},
});
+18
View File
@@ -1,5 +1,23 @@
# thirdweb
## 5.43.2
### Patch Changes
- [#3895](https://github.com/thirdweb-dev/js/pull/3895) [`13d9741`](https://github.com/thirdweb-dev/js/commit/13d9741f77df6e8e3d53dbffe6671d0852ac6a06) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Add Korean and French Locale
- [#3901](https://github.com/thirdweb-dev/js/pull/3901) [`825ef23`](https://github.com/thirdweb-dev/js/commit/825ef239a0552295a218e61f4dcbb5f32eb19632) Thanks [@joaquim-verges](https://github.com/joaquim-verges)! - Handle gas free chains where baseFeePerGas is 0
- [#3903](https://github.com/thirdweb-dev/js/pull/3903) [`306f3da`](https://github.com/thirdweb-dev/js/commit/306f3da606b83d7030d6a2d0b1771e1b3f9edb8b) Thanks [@gregfromstl](https://github.com/gregfromstl)! - Fix occasional iframe error when logging in with oauth
## 5.43.1
### Patch Changes
- [#3896](https://github.com/thirdweb-dev/js/pull/3896) [`3b49b18`](https://github.com/thirdweb-dev/js/commit/3b49b18f4da60ae27c540a8957e81c55df787609) Thanks [@gregfromstl](https://github.com/gregfromstl)! - Fix OTP validation in React Native Connect UI
- [#3897](https://github.com/thirdweb-dev/js/pull/3897) [`4463848`](https://github.com/thirdweb-dev/js/commit/446384867180e5441fd361de979457ff93818d59) Thanks [@jnsdls](https://github.com/jnsdls)! - fix "create" command requiring login
## 5.43.0
### Minor Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "thirdweb",
"version": "5.43.0",
"version": "5.43.2",
"repository": {
"type": "git",
"url": "git+https://github.com/thirdweb-dev/js.git#main"
+1 -1
View File
@@ -33,7 +33,7 @@ async function main() {
default: {
// check several commands for missing -k flag
const commands = ["create", "deploy", "publish", "generate", "upload"];
const commands = ["deploy", "publish", "generate", "upload"];
if (commands.includes(command) && !rest.includes("-k")) {
console.info(
"Please include the -k flag with your secret key, learn more: https://support.thirdweb.com/troubleshooting-errors/7Y1BqKNvtLdBv5fZkRZZB3/issue-linking-device-on-the-authorization-page-via-thirdweb-cli/cn9LRA3ax7XCP6uxwRYdvx",
+1 -1
View File
@@ -143,7 +143,7 @@ async function getDynamicFeeData(
eth_maxPriorityFeePerGas(rpcRequest).catch(() => null),
]);
const baseBlockFee = block?.baseFeePerGas ? block.baseFeePerGas : 100n;
const baseBlockFee = block?.baseFeePerGas ?? 0n;
const chainId = chain.id;
// flag chain testnet & flag chain
@@ -159,6 +159,11 @@ function PreOtpLogin(
}) => {
const { auth, phoneOrEmail } = options;
if (auth === "phone") {
if (phoneOrEmail.slice(0, 1) !== "+") {
throw new Error(
"Invalid phone number. Please include a country code.",
);
}
await preAuthenticate({
client,
strategy: auth,
@@ -639,7 +639,7 @@ function DetailsModal(props: {
if (screen === "transactions") {
content = (
<TransactionsScreen
title="Buy"
title={locale.buy}
onBack={() => setScreen("main")}
closeModal={closeModal}
locale={locale}
@@ -812,7 +812,7 @@ function DetailsModal(props: {
else if (screen === "buy") {
content = (
<LazyBuyScreen
title="Buy"
title={locale.buy}
isEmbed={false}
client={client}
onBack={() => setScreen("main")}
@@ -17,7 +17,7 @@ const connectWalletLocalEs: ConnectLocale = {
guest: "Invitado",
send: "Enviar",
receive: "Recibir",
buy: "Buy", // TODO
buy: "Comprar",
transactions: "Transactions",
payTransactions: "Fiat Transactions",
walletTransactions: "Wallet Transactions",
@@ -103,15 +103,15 @@ const connectWalletLocalEs: ConnectLocale = {
},
},
manageWallet: {
title: "Manage Wallet",
connectAnApp: "Connect an App",
exportPrivateKey: "Export Private Key",
title: "Gestionar Cartera",
connectAnApp: "Conectar una Aplicación",
exportPrivateKey: "Exportar Clave Privada",
},
viewFunds: {
title: "View Funds",
viewNFTs: "View NFTs",
viewTokens: "View Tokens",
viewAssets: "View Assets",
title: "Ver Fondos",
viewNFTs: "Ver NFTs",
viewTokens: "Ver Tokens",
viewAssets: "Ver Activos",
},
};
@@ -0,0 +1,118 @@
import type { ConnectLocale } from "./types.js";
const connectLocaleFr: ConnectLocale = {
id: "fr_FR",
signIn: "S'authentifier",
defaultButtonTitle: "Se Connecter",
connecting: "Connexion",
switchNetwork: "Changer de réseau",
switchingNetwork: "Changement de réseau",
defaultModalTitle: "Se connecter",
recommended: "Recommandé",
installed: "Installé",
buy: "Acheter",
continueAsGuest: "Continuer en tant qu'invité",
connectAWallet: "Connecter un portefeuille",
newToWallets: "En savoir plus sur les portefeuilles",
getStarted: "Commencer",
guest: "Invité",
send: "Envoyer",
receive: "Recevoir",
currentNetwork: "Réseau actuel",
switchAccount: "Changer de compte",
requestTestnetFunds: "Demander des fonds Testnet",
transactions: "Transactions",
payTransactions: "Transactions en Euros",
walletTransactions: "Transactions du portefeuille",
viewAllTransactions: "Voir toutes les transactions",
backupWallet: "Sauvegarder le portefeuille",
guestWalletWarning:
"Ceci est un portefeuille invité temporaire. Sauvegardez le portefeuille si vous ne voulez pas perdre l'accès",
switchTo: "Passer à", // Used in "Switch to <Wallet-Name>"
connectedToSmartWallet: "Compte intelligent",
confirmInWallet: "Confirmer dans le portefeuille",
disconnectWallet: "Déconnecter le portefeuille",
copyAddress: "Copier l'adresse",
personalWallet: "Portefeuille personnel",
smartWallet: "Portefeuille intelligent",
or: "OU",
goBackButton: "Retour",
welcomeScreen: {
defaultTitle: "Votre porte d'entrée vers le monde décentralisé",
defaultSubtitle: "Connectez un portefeuille pour commencer",
},
agreement: {
prefix: "En vous connectant, vous acceptez les",
termsOfService: "Conditions d'utilisation",
and: "&",
privacyPolicy: "Politique de confidentialité",
},
networkSelector: {
title: "Sélectionner un réseau",
mainnets: "Mainnets",
testnets: "Testnets",
allNetworks: "Tous",
addCustomNetwork: "Ajouter un réseau personnalisé",
inputPlaceholder: "Rechercher un réseau ou un ID de chaîne",
categoryLabel: {
recentlyUsed: "Récemment utilisé",
popular: "Populaire",
others: "Tous les réseaux",
},
loading: "Chargement",
failedToSwitch: "Échec du changement de réseau",
},
receiveFundsScreen: {
title: "Recevoir des fonds",
instruction:
"Copiez l'adresse du portefeuille pour envoyer des fonds à ce portefeuille",
},
sendFundsScreen: {
title: "Envoyer des fonds",
submitButton: "Envoyer",
token: "Token",
sendTo: "Envoyer à",
amount: "Montant",
successMessage: "Transaction réussie",
invalidAddress: "Adresse invalide",
noTokensFound: "Aucun token trouvé",
searchToken: "Rechercher ou coller l'adresse du token",
transactionFailed: "Échec de la transaction",
transactionRejected: "Transaction rejetée",
insufficientFunds: "Fonds insuffisants",
selectTokenTitle: "Sélectionner un token",
sending: "Envoi en cours",
},
signatureScreen: {
instructionScreen: {
title: "Se connecter",
instruction:
"Veuillez signer la demande de message dans votre portefeuille pour continuer",
signInButton: "Se connecter",
disconnectWallet: "Déconnecter le portefeuille",
},
signingScreen: {
title: "Connexion en cours",
prompt: "Signez la demande de signature dans votre portefeuille",
promptForSafe:
"Signez la demande de signature dans votre portefeuille et approuvez la transaction dans Safe",
approveTransactionInSafe: "Approuvez la transaction dans Safe",
tryAgain: "Réessayer",
failedToSignIn: "Échec de la connexion",
inProgress: "En attente de confirmation",
},
},
manageWallet: {
title: "Gérer le portefeuille",
connectAnApp: "Connecter une application",
exportPrivateKey: "Exporter la clé privée",
},
viewFunds: {
title: "Voir les fonds",
viewNFTs: "Voir les NFT",
viewTokens: "Voir les tokens",
viewAssets: "Voir les actifs",
},
};
export default connectLocaleFr;
@@ -18,6 +18,12 @@ export async function getConnectLocale(localeId: LocaleId) {
case "de_DE": {
return (await import("./de.js")).default;
}
case "ko_KR": {
return (await import("./kr.js")).default;
}
case "fr_FR": {
return (await import("./fr.js")).default;
}
default: {
return (await import("./en.js")).default;
}
@@ -20,11 +20,11 @@ const connectWalletLocalJa: ConnectLocale = {
currentNetwork: "現在のネットワーク",
switchAccount: "アカウントを切り替える",
requestTestnetFunds: "テストネットの資金をリクエストする",
buy: "Buy", // TODO
transactions: "Transactions",
payTransactions: "Fiat Transactions",
walletTransactions: "Wallet Transactions",
viewAllTransactions: "View All Transactions", // TODO
buy: "購入",
transactions: "取引",
payTransactions: "支払い取引",
walletTransactions: "ウォレット取引",
viewAllTransactions: "全ての取引を表示",
backupWallet: "ウォレットのバックアップ",
guestWalletWarning:
"これは一時的なゲストウォレットです。アクセスできなくなることを防ぐため、バックアップをしてください",
@@ -103,15 +103,15 @@ const connectWalletLocalJa: ConnectLocale = {
},
},
manageWallet: {
title: "Manage Wallet",
connectAnApp: "Connect an App",
exportPrivateKey: "Export Private Key",
title: "ウォレットを管理",
connectAnApp: "アプリを接続",
exportPrivateKey: "秘密鍵をエクスポート",
},
viewFunds: {
title: "View Funds",
viewNFTs: "View NFTs",
viewTokens: "View Tokens",
viewAssets: "View Assets",
title: "資金を表示",
viewNFTs: "NFTを表示",
viewTokens: "トークンを表示",
viewAssets: "資産を表示",
},
};
@@ -0,0 +1,114 @@
import type { ConnectLocale } from "./types.js";
const connectLocaleKr: ConnectLocale = {
id: "ko_KR",
signIn: "로그인",
defaultButtonTitle: "지갑 연결",
connecting: "연결 중",
switchNetwork: "네트워크 전환",
switchingNetwork: "네트워크 전환 중",
defaultModalTitle: "로그인",
recommended: "추천",
installed: "설치됨",
buy: "구매",
continueAsGuest: "게스트로 계속",
connectAWallet: "지갑 연결",
newToWallets: "지갑 사용이 처음이신가요?",
getStarted: "시작하기",
guest: "게스트",
send: "보내기",
receive: "받기",
currentNetwork: "현재 네트워크",
switchAccount: "계정 전환",
requestTestnetFunds: "테스트넷 자금 요청",
transactions: "거래",
payTransactions: "법정화폐 거래",
walletTransactions: "지갑 거래",
viewAllTransactions: "모든 거래 보기",
backupWallet: "지갑 백업",
guestWalletWarning:
"이것은 임시 게스트 지갑입니다. 접근을 잃지 않으려면 지갑을 백업하십시오",
switchTo: "전환", // Used in "<Wallet-Name> 으로 전환"
connectedToSmartWallet: "스마트 계정",
confirmInWallet: "지갑에서 확인",
disconnectWallet: "지갑 연결 해제",
copyAddress: "주소 복사",
personalWallet: "개인 지갑",
smartWallet: "스마트 지갑",
or: "또는",
goBackButton: "뒤로",
welcomeScreen: {
defaultTitle: "분산된 세계로의 게이트웨이",
defaultSubtitle: "시작하려면 지갑을 연결하십시오",
},
agreement: {
prefix: "연결함으로써 귀하는 다음에 동의하게 됩니다",
termsOfService: "서비스 약관",
and: "&",
privacyPolicy: "개인정보 보호정책",
},
networkSelector: {
title: "네트워크 선택",
mainnets: "메인넷",
testnets: "테스트넷",
allNetworks: "모두",
addCustomNetwork: "맞춤 네트워크 추가",
inputPlaceholder: "네트워크 또는 체인 ID 검색",
categoryLabel: {
recentlyUsed: "최근 사용",
popular: "인기",
others: "모든 네트워크",
},
loading: "로딩 중",
failedToSwitch: "네트워크 전환 실패",
},
receiveFundsScreen: {
title: "자금 수신",
instruction: "자금을 이 지갑으로 보내려면 지갑 주소를 복사하십시오",
},
sendFundsScreen: {
title: "자금 송금",
submitButton: "보내기",
token: "토큰",
sendTo: "보낼 곳",
amount: "금액",
successMessage: "거래 성공",
invalidAddress: "유효하지 않은 주소",
noTokensFound: "토큰을 찾을 수 없음",
searchToken: "토큰 주소 검색 또는 붙여넣기",
transactionFailed: "거래 실패",
transactionRejected: "거래 거부됨",
insufficientFunds: "자금 부족",
selectTokenTitle: "토큰 선택",
sending: "보내는 중",
},
signatureScreen: {
instructionScreen: {
title: "로그인",
instruction: "계속하려면 지갑에서 메시지 요청에 서명하십시오",
signInButton: "로그인",
disconnectWallet: "지갑 연결 해제",
},
signingScreen: {
title: "로그인 중",
prompt: "지갑에서 서명 요청에 서명하십시오",
promptForSafe:
"지갑에서 서명 요청에 서명하고 Safe에서 거래를 승인하십시오",
approveTransactionInSafe: "Safe에서 거래 승인",
tryAgain: "다시 시도",
failedToSignIn: "로그인 실패",
inProgress: "확인 대기 중",
},
},
manageWallet: {
title: "지갑 관리",
connectAnApp: "앱 연결",
exportPrivateKey: "개인 키 내보내기",
},
viewFunds: {
title: "자금 보기",
viewNFTs: "NFT 보기",
viewTokens: "토큰 보기",
viewAssets: "자산 보기",
},
};
export default connectLocaleKr;
@@ -15,11 +15,11 @@ const connectWalletLocalTl: ConnectLocale = {
newToWallets: "Bago sa mga wallet?",
getStarted: "Simulan",
guest: "Guest",
buy: "Buy", // TODO
transactions: "Transactions",
payTransactions: "Fiat Transactions",
walletTransactions: "Wallet Transactions",
viewAllTransactions: "View All Transactions", // TODO
buy: "Bumili",
transactions: "Mga Transaksyon",
payTransactions: "Mga Transaksyong Fiat",
walletTransactions: "Mga Transaksyon sa Wallet",
viewAllTransactions: "Tingnan ang Lahat ng Transaksyon",
send: "Ipadala",
receive: "Matanggap",
currentNetwork: "Kasalukuyang network",
@@ -103,15 +103,15 @@ const connectWalletLocalTl: ConnectLocale = {
},
},
manageWallet: {
title: "Manage Wallet",
connectAnApp: "Connect an App",
exportPrivateKey: "Export Private Key",
title: "Pamahalaan ang Wallet",
connectAnApp: "Ikonekta ang isang App",
exportPrivateKey: "I-export ang Pribadong Susi",
},
viewFunds: {
title: "View Funds",
viewNFTs: "View NFTs",
viewTokens: "View Tokens",
viewAssets: "View Assets",
title: "Tingnan ang Pondo",
viewNFTs: "Tingnan ang mga NFT",
viewTokens: "Tingnan ang mga Token",
viewAssets: "Tingnan ang mga Asset",
},
};
+3 -1
View File
@@ -3,6 +3,8 @@ export type LocaleId =
| "en_US"
| "es_ES"
| "ja_JP"
| "ko_KR"
| "tl_PH"
| "vi_VN"
| "de_DE";
| "de_DE"
| "fr_FR";
@@ -0,0 +1,27 @@
import type { InjectedWalletLocale } from "./types.js";
/**
* @internal
*/
const injectedWalletLocaleEn = (wallet: string): InjectedWalletLocale => ({
connectionScreen: {
inProgress: "En attente de confirmation",
failed: "Connexion échouée",
instruction: `Acceptez la demande de connexion dans ${wallet}`,
retry: "Réessayer",
},
getStartedScreen: {
instruction: `Scannez le code QR pour télécharger l'application ${wallet}`,
},
scanScreen: {
instruction: `Scannez le code QR avec l'application ${wallet} pour vous connecter`,
},
getStartedLink: `Vous n'avez pas ${wallet} ?`,
download: {
chrome: "Télécharger l'extension Chrome",
android: "Télécharger sur Google Play",
iOS: "Télécharger sur l'App Store",
},
});
export default injectedWalletLocaleEn;
@@ -18,6 +18,10 @@ export async function getInjectedWalletLocale(
return (await import("./vi.js")).default;
case "de_DE":
return (await import("./de.js")).default;
case "ko_KR":
return (await import("./kr.js")).default;
case "fr_FR":
return (await import("./fr.js")).default;
default:
return (await import("./en.js")).default;
}
@@ -1,27 +1,25 @@
import type { InjectedWalletLocale } from "./types.js";
/**
* @internal
*/
const injectedWalletLocaleJa = (walletName: string): InjectedWalletLocale => ({
const injectedWalletLocale = (wallet: string): InjectedWalletLocale => ({
connectionScreen: {
inProgress: "確認待ち",
inProgress: "確認を待っています",
failed: "接続に失敗しました",
instruction: `${walletName}のウォレットで接続リクエストを承認してください`,
instruction: `${wallet}で接続リクエストを承認してください`,
retry: "再試行",
},
getStartedScreen: {
instruction: `QRコードをスキャンして${walletName}アプリをダウンロードしてください`,
instruction: `QRコードをスキャンして${wallet}アプリをダウンロードしてください`,
},
scanScreen: {
instruction: `${walletName}のウォレットアプリでQRコードをスキャンして接続してください`,
instruction: `${wallet}アプリでQRコードをスキャンして接続してください`,
},
getStartedLink: `${walletName}のウォレットを持っていませんか?`,
getStartedLink: `${wallet}をお持ちではありませんか?`,
download: {
chrome: "Chrome拡張をダウンロード",
chrome: "Chrome拡張機能をダウンロード",
android: "Google Playでダウンロード",
iOS: "App Storeでダウンロード",
},
});
export default injectedWalletLocaleJa;
export default injectedWalletLocale;
@@ -0,0 +1,25 @@
import type { InjectedWalletLocale } from "./types.js";
/**
* @internal
*/
const injectedWalletLocale = (wallet: string): InjectedWalletLocale => ({
connectionScreen: {
inProgress: "확인 대기 중",
failed: "연결 실패",
instruction: `${wallet}에서 연결 요청을 수락하세요`,
retry: "다시 시도하세요",
},
getStartedScreen: {
instruction: `Scan the QR code to download the ${wallet} app`,
},
scanScreen: {
instruction: `Scan the QR code with the ${wallet} app to connect`,
},
getStartedLink: `Don't have ${wallet}?`,
download: {
chrome: "Chrome 확장 프로그램 다운로드",
android: "Google Play에서 다운로드",
iOS: "App Store에서 다운로드",
},
});
export default injectedWalletLocale;
@@ -0,0 +1,51 @@
import type { LocalWalletLocale } from "./types.js";
const localWalletLocaleEn: LocalWalletLocale = {
passwordLabel: "Mot de passe",
confirmPasswordLabel: "Confirmer le mot de passe",
enterYourPassword: "Entrez votre mot de passe",
warningScreen: {
title: "Avertissement",
warning:
"Votre portefeuille actuel sera supprimé si vous créez un nouveau portefeuille. Sauvegardez le portefeuille sur votre appareil avant de créer un nouveau portefeuille",
backupWallet: "Sauvegarder le portefeuille",
skip: "Passer",
},
reconnectScreen: {
title: "Connecter au portefeuille enregistré",
savedWallet: "Portefeuille enregistré",
continue: "Continuer",
createNewWallet: "Créer un nouveau portefeuille",
},
createScreen: {
instruction:
"Choisissez un mot de passe pour votre portefeuille. Vous pourrez accéder et exporter ce portefeuille avec le même mot de passe",
importWallet: "Importer le portefeuille",
createNewWallet: "Créer un nouveau portefeuille",
connecting: "Connexion",
},
exportScreen: {
downloadMessage:
"Cela téléchargera un fichier texte contenant la clé privée du portefeuille sur votre appareil",
decryptMessage:
"Entrez le mot de passe de ce portefeuille pour déchiffrer la clé privée",
walletAddress: "Adresse du portefeuille",
download: "Télécharger",
title: "Sauvegarder le portefeuille",
},
importScreen: {
title: "Importer le portefeuille",
description1:
"L'application peut autoriser toute transaction au nom du portefeuille sans aucune approbation",
description2:
"Nous recommandons de ne se connecter qu'à des applications de confiance",
passwordDescription:
"Choisissez un mot de passe pour chiffrer la clé privée. La clé privée chiffrée sera stockée dans le navigateur",
import: "Importer",
uploadJSON: "Veuillez télécharger un fichier JSON",
uploadedSuccessfully: "Téléchargé avec succès",
invalidPrivateKey: "Clé privée invalide",
},
};
export default localWalletLocaleEn;
@@ -16,6 +16,8 @@ export async function getLocalWalletLocale(
return (await import("./tl.js")).default;
case "vi_VN":
return (await import("./vi.js")).default;
case "fr_FR":
return (await import("./fr.js")).default;
default:
return (await import("./en.js")).default;
}
@@ -1,54 +1,48 @@
import type { LocalWalletLocale } from "./types.js";
const localWalletLocaleJa: LocalWalletLocale = {
const localWalletLocaleEn: LocalWalletLocale = {
passwordLabel: "パスワード",
confirmPasswordLabel: "パスワードを確認",
enterYourPassword: "パスワードを入力してください",
warningScreen: {
title: "警告",
warning:
"新しいウォレットを作成すると、現在のウォレットは削除されます。新しいウォレットを作成する前に、ウォレットのバックアップをデバイスに保存してください",
backupWallet: "ウォレットのバックアップ",
// TODO: translate
skip: "Skip",
"新しいウォレットを作成すると、現在のウォレットが削除されます。新しいウォレットを作成する前に、ウォレットをデバイスにバックアップしてください",
backupWallet: "ウォレットをバックアップ",
skip: "スキップ",
},
reconnectScreen: {
title: "保存されたウォレットへの接続",
title: "保存されたウォレットに接続",
savedWallet: "保存されたウォレット",
continue: "続ける",
continue: "続行",
createNewWallet: "新しいウォレットを作成",
},
createScreen: {
instruction:
"ウォレットのパスワードを選択してください。このパスワードで、このウォレットにアクセスしたり、同じパスワードでエクスポートすることができます",
"ウォレットのパスワードを選択してください。同じパスワードでこのウォレットにアクセスしてエクスポートできます",
importWallet: "ウォレットをインポート",
createNewWallet: "新しいウォレットを作成",
connecting: "接続中",
},
exportScreen: {
// TODO: translate
downloadMessage:
"This will download a text file containing the wallet private key onto your device",
"これにより、ウォレットの秘密鍵を含むテキストファイルがデバイスにダウンロードされます",
decryptMessage:
"Enter the password of this wallet to decrypt the private key",
"秘密鍵を復号するために、このウォレットのパスワードを入力してください",
walletAddress: "ウォレットアドレス",
download: "ダウンロード",
title: "ウォレットのバックアップ",
title: "ウォレットをバックアップ",
},
importScreen: {
title: "ウォレットをインポート",
description1:
"アプリケーションは、ウォレットの代わりに任意の取引を承認なしで認証することができます",
"アプリケーションは、ウォレットの代理として任意のトランザクションを承認できます",
description2: "信頼できるアプリケーションにのみ接続することをお勧めします",
// TODO: translate
passwordDescription:
"Choose a password to encrypt the private key. Encrypted private key will be stored in browser",
"秘密鍵を暗号化するためのパスワードを選択してください。暗号化された秘密鍵はブラウザに保存されます",
import: "インポート",
uploadJSON: "JSONファイルをアップロードしてください",
uploadedSuccessfully: "正常にアップロードされました",
// TODO
invalidPrivateKey: "Invalid Private Key",
invalidPrivateKey: "無効な秘密鍵",
},
};
export default localWalletLocaleJa;
export default localWalletLocaleEn;
@@ -0,0 +1,47 @@
import type { LocalWalletLocale } from "./types.js";
const localWalletLocaleEn: LocalWalletLocale = {
passwordLabel: "비밀번호",
confirmPasswordLabel: "비밀번호 확인",
enterYourPassword: "비밀번호를 입력하세요",
warningScreen: {
title: "경고",
warning:
"새 지갑을 생성하면 현재 지갑이 삭제됩니다. 새 지갑을 생성하기 전에 지갑을 기기에 백업하세요",
backupWallet: "지갑 백업",
skip: "건너뛰기",
},
reconnectScreen: {
title: "저장된 지갑에 연결",
savedWallet: "저장된 지갑",
continue: "계속하기",
createNewWallet: "새 지갑 생성",
},
createScreen: {
instruction:
"지갑의 비밀번호를 선택하세요. 동일한 비밀번호로 이 지갑에 접근하고 내보낼 수 있습니다",
importWallet: "지갑 가져오기",
createNewWallet: "새 지갑 생성",
connecting: "연결 중",
},
exportScreen: {
downloadMessage:
"이 작업은 지갑 개인 키가 포함된 텍스트 파일을 기기에 다운로드합니다.",
decryptMessage: "개인 키를 복호화하려면 이 지갑의 비밀번호를 입력하세요.",
walletAddress: "지갑 주소",
download: "다운로드",
title: "지갑 백업",
},
importScreen: {
title: "지갑 가져오기",
description1:
"애플리케이션은 지갑 소유자의 승인 없이 모든 거래를 승인할 수 있습니다.",
description2: "신뢰할 수 있는 애플리케이션에만 연결할 것을 권장합니다",
passwordDescription:
"개인 키를 암호화할 비밀번호를 선택하세요. 암호화된 개인 키는 브라우저에 저장됩니다",
import: "가져오기",
uploadJSON: "JSON 파일을 업로드하세요",
uploadedSuccessfully: "업로드 성공",
invalidPrivateKey: "잘못된 개인 키",
},
};
export default localWalletLocaleEn;
@@ -325,8 +325,7 @@ export const ConnectWalletSocialOptions = (
onClick={() => {
setManualInputMode("email");
}}
// TODO locale
title={"Email address"}
title={locale.emailPlaceholder}
/>
)}
</>
@@ -365,8 +364,7 @@ export const ConnectWalletSocialOptions = (
onClick={() => {
setManualInputMode("phone");
}}
// TODO locale
title={"Phone number"}
title={locale.phonePlaceholder}
/>
)}
</>
@@ -380,8 +378,7 @@ export const ConnectWalletSocialOptions = (
onClick={() => {
handlePassKeyLogin();
}}
// TODO locale
title="Passkey"
title={locale.passkey}
/>
</>
)}
@@ -55,4 +55,5 @@ export default {
phonePlaceholder: "Telefonnummer",
signInWithPhone: "Mit Telefonnummer anmelden",
phoneRequired: "Telefonnummer ist erforderlich",
passkey: "Passkey",
} satisfies InAppWalletLocale;
@@ -54,4 +54,5 @@ export default {
phonePlaceholder: "Phone number",
signInWithPhone: "Sign in with phone number",
phoneRequired: "phone number is required",
passkey: "Passkey",
} satisfies InAppWalletLocale;
@@ -54,4 +54,5 @@ export default {
signInWithPhone: "Iniciar sesión con número de teléfono",
phoneRequired: "Se requiere número de teléfono",
signInWithEmail: "Iniciar sesión con correo electrónico",
passkey: "Clave de acceso",
} satisfies InAppWalletLocale;
@@ -0,0 +1,59 @@
import type { InAppWalletLocale } from "./types.js";
export default {
signInWithGoogle: "Google",
signInWithFacebook: "Facebook",
signInWithApple: "Apple",
signInWithDiscord: "Discord",
emailPlaceholder: "E-mail",
submitEmail: "Continuer",
signIn: "Se connecter",
or: "Ou",
emailRequired: "L'adresse e-mail est requise",
invalidEmail: "Adresse e-mail invalide",
maxAccountsExceeded:
"Nombre maximum de comptes dépassé. Veuillez en informer le développeur de l'application.",
socialLoginScreen: {
title: "Se connecter",
instruction: "Connectez-vous à votre compte dans la fenêtre pop-up",
failed: "Échec de la connexion",
retry: "Réessayer",
},
emailLoginScreen: {
title: "Se connecter",
enterCodeSendTo: "Entrez le code de vérification envoyé à",
newDeviceDetected: "Nouvel appareil détecté",
enterRecoveryCode:
"Entrez le code de récupération qui vous a été envoyé par e-mail lors de votre inscription",
invalidCode: "Code de vérification invalide",
invalidCodeOrRecoveryCode:
"Code de vérification ou code de récupération invalide",
verify: "Vérifier",
failedToSendCode: "Échec de l'envoi du code de vérification",
sendingCode: "Envoi du code de vérification",
resendCode: "Renvoyer le code de vérification",
},
createPassword: {
title: "Créer un mot de passe",
instruction:
"Définissez un mot de passe pour votre compte. Vous aurez besoin de ce mot de passe lorsque vous vous connecterez depuis un nouvel appareil.",
saveInstruction: "Assurez-vous de le sauvegarder",
inputPlaceholder: "Entrez votre mot de passe",
confirmation: "J'ai sauvegardé mon mot de passe",
submitButton: "Définir le mot de passe",
failedToSetPassword: "Échec de la définition du mot de passe",
},
enterPassword: {
title: "Entrer le mot de passe",
instruction: "Entrez le mot de passe de votre compte",
inputPlaceholder: "Entrez votre mot de passe",
submitButton: "Vérifier",
wrongPassword: "Mot de passe incorrect",
},
signInWithEmail: "Se connecter avec e-mail",
invalidPhone: "Numéro de téléphone invalide",
phonePlaceholder: "Téléphone",
signInWithPhone: "Se connecter avec le numéro de téléphone",
phoneRequired: "Le numéro de téléphone est requis",
passkey: "Passkey",
} satisfies InAppWalletLocale;
@@ -18,6 +18,10 @@ export async function getInAppWalletLocale(
return (await import("./vi.js")).default;
case "de_DE":
return (await import("./de.js")).default;
case "ko_KR":
return (await import("./kr.js")).default;
case "fr_FR":
return (await import("./fr.js")).default;
default:
return (await import("./en.js")).default;
}
@@ -1,20 +1,20 @@
import type { InAppWalletLocale } from "./types.js";
export default {
signInWithGoogle: "Googleでサインイン",
signInWithFacebook: "Facebookでサインイン",
signInWithApple: "Appleでサインイン",
signInWithDiscord: "Discordでサインイン",
emailPlaceholder: "メールアドレスを入力してください",
submitEmail: "続ける",
emailRequired: "メールアドレスが必要です",
invalidEmail: "無効なメールアドレス",
signInWithGoogle: "Google",
signInWithFacebook: "Facebook",
signInWithApple: "Apple",
signInWithDiscord: "Discord",
emailPlaceholder: "メールアドレス",
submitEmail: "続行",
signIn: "サインイン",
maxAccountsExceeded: "アカウントの最大数を超えました",
or: "または",
emailRequired: "メールアドレスは必須です",
invalidEmail: "無効なメールアドレス",
maxAccountsExceeded:
"アカウントの最大数を超えました。アプリ開発者に通知してください。",
socialLoginScreen: {
title: "サインイン",
instruction: "ポップアップウィンドウでアカウントにサインインします", // TODO: check if this is correct
instruction: "ポップアップでアカウントにサインインしてください",
failed: "サインインに失敗しました",
retry: "再試行",
},
@@ -23,7 +23,7 @@ export default {
enterCodeSendTo: "送信された確認コードを入力してください",
newDeviceDetected: "新しいデバイスが検出されました",
enterRecoveryCode:
"初回サインアップ時にメールで送信されたリカバリーコードを入力してください",
"初回サインアップ時に送信されたリカバリーコードを入力してください",
invalidCode: "無効な確認コード",
invalidCodeOrRecoveryCode: "無効な確認コードまたはリカバリーコード",
verify: "確認",
@@ -34,23 +34,24 @@ export default {
createPassword: {
title: "パスワードを作成",
instruction:
"アカウントのパスワードを設定してください。新しいデバイスから接続する際にこのパスワードが必要となります。",
saveInstruction: "パスワードは必ず保存してください。",
"アカウントのパスワードを設定してください。新しいデバイスから接続する際にこのパスワードが必要です。",
saveInstruction: "必ず保存してください",
inputPlaceholder: "パスワードを入力してください",
confirmation: "パスワードを保存しました。",
confirmation: "パスワードを保存しました",
submitButton: "パスワードを設定",
failedToSetPassword: "パスワードの設定に失敗しました。",
failedToSetPassword: "パスワードの設定に失敗しました",
},
enterPassword: {
title: "パスワードを入力",
instruction: "アカウントのパスワードを入力してください",
inputPlaceholder: "パスワードを入力してください",
submitButton: "確認",
wrongPassword: "パスワードが違います",
wrongPassword: "パスワードが間違っています",
},
signInWithEmail: "メールでサインイン",
invalidPhone: "無効な電話番号",
signInWithEmail: "電子メールでサインインする",
phonePlaceholder: "電話番号を入力してください",
signInWithPhone: "電話番号でログイン",
phoneRequired: "電話番号が必要です",
phonePlaceholder: "電話番号",
signInWithPhone: "電話番号でサインイン",
phoneRequired: "電話番号は必須です",
passkey: "パスキー",
} satisfies InAppWalletLocale;
@@ -0,0 +1,55 @@
import type { InAppWalletLocale } from "./types.js";
export default {
signInWithGoogle: "Google",
signInWithFacebook: "Facebook",
signInWithApple: "Apple",
signInWithDiscord: "Discord",
emailPlaceholder: "이메일 주소",
submitEmail: "계속하기",
signIn: "로그인",
or: "Or",
emailRequired: "이메일 주소가 필요합니다",
invalidEmail: "잘못된 이메일 주소",
maxAccountsExceeded: "계정 최대 수를 초과했습니다. 앱 개발자에게 알려주세요.",
socialLoginScreen: {
title: "로그인",
instruction: "팝업 창에서 계정에 로그인하세요",
failed: "로그인에 실패했습니다",
retry: "다시 시도",
},
emailLoginScreen: {
title: "로그인",
enterCodeSendTo: "전송된 인증 코드를 입력하세요",
newDeviceDetected: "새 기기가 감지되었습니다",
enterRecoveryCode: "처음 가입할 때 이메일로 전송된 복구 코드를 입력하세요",
invalidCode: "잘못된 인증 코드",
invalidCodeOrRecoveryCode: "잘못된 인증 코드 또는 복구 코드",
verify: "확인",
failedToSendCode: "인증 코드 전송에 실패했습니다",
sendingCode: "인증 코드 전송 중",
resendCode: "인증 코드 다시 보내기",
},
createPassword: {
title: "비밀번호 생성",
instruction:
"계정의 비밀번호를 설정하세요. 새 기기에서 연결할 때 이 비밀번호가 필요합니다.",
saveInstruction: "반드시 저장하세요",
inputPlaceholder: "비밀번호를 입력하세요",
confirmation: "비밀번호를 저장했습니다",
submitButton: "비밀번호 설정",
failedToSetPassword: "비밀번호 설정 실패",
},
enterPassword: {
title: "비밀번호를 입력하세요",
instruction: "계정의 비밀번호를 입력하세요",
inputPlaceholder: "비밀번호를 입력하세요",
submitButton: "확인",
wrongPassword: "잘못된 비밀번호",
},
signInWithEmail: "이메일로 로그인",
invalidPhone: "잘못된 전화번호",
phonePlaceholder: "전화번호",
signInWithPhone: "전화번호로 로그인",
phoneRequired: "전화번호가 필요합니다",
passkey: "비밀번호",
} satisfies InAppWalletLocale;
@@ -54,4 +54,5 @@ export default {
phonePlaceholder: "Ilagay ang iyong numero ng telepono",
signInWithPhone: "Mag-login gamit ang numero ng telepono",
phoneRequired: "Kinakailangan ang numero ng telepono",
passkey: "Passkey",
} satisfies InAppWalletLocale;
@@ -49,4 +49,5 @@ export type InAppWalletLocale = {
};
submitEmail: string;
maxAccountsExceeded: string;
passkey: string;
};
@@ -54,4 +54,5 @@ export default {
phonePlaceholder: "Số điện thoại",
signInWithPhone: "Đăng nhập bằng số điện thoại",
phoneRequired: "Vui lòng nhập số điện thoại",
passkey: "Passkey",
} satisfies InAppWalletLocale;
@@ -0,0 +1,13 @@
import type { SmartWalletLocale } from "./types.js";
const smartWalletLocalEn: SmartWalletLocale = {
connecting: "Connexion au compte intelligent",
failedToConnect: "Échec de la connexion au compte intelligent",
wrongNetworkScreen: {
title: "Mauvais réseau",
subtitle: "Votre portefeuille n'est pas connecté au réseau requis",
failedToSwitch: "Échec du changement de réseau",
},
};
export default smartWalletLocalEn;
@@ -18,6 +18,10 @@ export async function getSmartWalletLocale(
return (await import("./vi.js")).default;
case "de_DE":
return (await import("./de.js")).default;
case "ko_KR":
return (await import("./kr.js")).default;
case "fr_FR":
return (await import("./fr.js")).default;
default:
return (await import("./en.js")).default;
}
@@ -1,13 +1,11 @@
import type { SmartWalletLocale } from "./types.js";
const smartWalletLocaleJa: SmartWalletLocale = {
connecting: "スマートウォレットに接続中",
failedToConnect: "スマートウォレットに接続できませんでした",
const smartWalletLocale: SmartWalletLocale = {
connecting: "スマートアカウントに接続中",
failedToConnect: "スマートアカウントへの接続に失敗しました",
wrongNetworkScreen: {
title: "異なるネットワーク",
title: "ネットワークが違います",
subtitle: "ウォレットが必要なネットワークに接続されていません",
failedToSwitch: "ネットワークの切り替えに失敗しました",
},
};
export default smartWalletLocaleJa;
export default smartWalletLocale;
@@ -0,0 +1,11 @@
import type { SmartWalletLocale } from "./types.js";
const smartWalletLocale: SmartWalletLocale = {
connecting: "스마트 계정에 연결 중",
failedToConnect: "스마트 계정에 연결하지 못했습니다",
wrongNetworkScreen: {
title: "잘못된 네트워크",
subtitle: "지갑이 필요한 네트워크에 연결되어 있지 않습니다",
failedToSwitch: "네트워크 전환 실패",
},
};
export default smartWalletLocale;
@@ -33,4 +33,13 @@ export const walletConnectLocales: Record<LocaleId, WalletConnectLocale> = {
scanInstruction: "Scanne dies mit deiner Wallet-App, um zu verbinden",
openWCModal: "Offizielles WalletConnect-Modal öffnen",
},
ko_KR: {
scanInstruction: "지갑 앱으로 이 QR 코드를 스캔하여 연결하세요",
openWCModal: "공식 WalletConnect 모달 열기",
},
fr_FR: {
scanInstruction:
"Scannez ce code avec votre application de portefeuille pour vous connecter",
openWCModal: "Ouvrir le modal WalletConnect officiel",
},
};
@@ -111,7 +111,7 @@ export const loginWithOauth = async (options: {
break;
}
default: {
reject(new Error(`Invalid event type: ${event.data.eventType}`));
// no-op, DO NOT THROW HERE
}
}
};
Binary file not shown.
+7 -184
View File
@@ -1793,8 +1793,8 @@ importers:
specifier: 0.10.2
version: 0.10.2([email protected])([email protected])
'@coinbase/wallet-sdk':
specifier: ^3.9.0
version: 3.9.3
specifier: ^4.0.4
version: 4.0.4
'@google-cloud/kms':
specifier: ^4.4.0
version: 4.4.0
@@ -4591,12 +4591,12 @@ packages:
react: '*'
react-native: '*'
'@coinbase/[email protected]':
resolution: {integrity: sha512-N/A2DRIf0Y3PHc1XAMvbBUu4zisna6qAdqABMZwBMNEfWrXpAwx16pZGkYCLGE+Rvv1edbcB2LYDRnACNcmCiw==}
'@coinbase/[email protected]':
resolution: {integrity: sha512-y/OGEjlvosikjfB+wk+4CVb9OxD1ob9cidEBLI5h8Hxaf/Qoob2XoVT1uvhtAzBx34KpGYSd+alKvh/GCRre4Q==}
'@coinbase/[email protected]':
resolution: {integrity: sha512-74c040CRnGhfRjr3ArnkAgud86erIqdkPHNt5HR1k9u97uTIZCJww9eGYT67Qf7gHPpGS/xW8Be1D4dvRm63FA==}
'@corex/[email protected]':
resolution: {integrity: sha512-N8uEMrMPL0cu/bdboEWpQYb/0i2K5Qn8eCsxzOmxSggJbbQte7ljMRoXm917AbntqTGOzdTu+vP3KOOzoC70HQ==}
@@ -5120,23 +5120,11 @@ packages:
'@ethereumjs/[email protected]':
resolution: {integrity: sha512-lRyVQOeCDaIVtgfbowla32pzeDv2Obr8oR8Put5RdUBNRGr1VGPGQNGP6elWIpgK3YdpzqTOh4GyUGOureVeeA==}
'@ethereumjs/[email protected]':
resolution: {integrity: sha512-pksvzI0VyLgmuEF2FA/JR/4/y6hcPq8OUail3/AvycBaW1d5VSauOZzqGvJ3RTmR4MU35lWE8KseKOsEhrFRBA==}
'@ethereumjs/[email protected]':
resolution: {integrity: sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==}
engines: {node: '>=14'}
hasBin: true
'@ethereumjs/[email protected]':
resolution: {integrity: sha512-DziebCdg4JpGlEqEdGgXmjqcFoJi+JGulUXwEjsZGAscAQ7MyD/7LE/GVCP29vEQxKc7AAwjT3A2ywHp2xfoCA==}
engines: {node: '>=18'}
hasBin: true
'@ethereumjs/[email protected]':
resolution: {integrity: sha512-1nc6VO4jtFd172BbSnTnDQVr9IYBFl1y4xPzZdtkrkKIncBCkdbgfdRV+MiTkJYAtTxvV12GRZLqBFT1PNK6Yw==}
engines: {node: '>=14'}
'@ethereumjs/[email protected]':
resolution: {integrity: sha512-PmwzWDflky+7jlZIFqiGsBPap12tk9zK5SVH9YW2OEnDN7OEhCjUOMzbOqwuClrbkSIkM2ERivd7sXZ48Rh/vg==}
engines: {node: '>=18'}
@@ -5644,37 +5632,13 @@ packages:
resolution: {integrity: sha512-lpqC/HVb/fWljyphkEdifkr7vSfxHURnwLwKbJma7KvAkX2dl6xTsKLxwt4EpfxxuHhX7gaFOCCcs9Gqj//lEA==}
engines: {node: '>=14.18.0'}
'@metamask/[email protected]':
resolution: {integrity: sha512-whiUMPlAOrVGmX8aKYVPvlKyG4CpQXiNNyt74vE1xb5sPvmx5oA7B/kOi/JdBvhGQq97U1/AVdXEdk2zkP8qyA==}
engines: {node: '>=14.0.0'}
'@metamask/[email protected]':
resolution: {integrity: sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ==}
engines: {node: '>=12.0.0'}
'@metamask/[email protected]':
resolution: {integrity: sha512-dwZPq8wx9yV3IX2caLi9q9xZBw2XeIoYqdyihDDDpuHVCEiqadJLwqM3zy+uwf6F1QYQ65A8aOMQg1Uw7LMLNg==}
engines: {node: '>=16.0.0'}
'@metamask/[email protected]':
resolution: {integrity: sha512-VTgWkjWLzb0nupkFl1duQi9Mk8TGT9rsdnQg6DeRrYEFxtFOh0IF8nAwxM/4GWqDl6uIB06lqUBgUrAVWl62Bw==}
engines: {node: '>=16.0.0'}
'@metamask/[email protected]':
resolution: {integrity: sha512-/kSXhY692qiV1MXu6EeOZvg5nECLclxNXcKCxJ3cXQgYuRymRHpdx/t7JXfsK+JLjwA1e1c1/SBrlQYpusC29Q==}
'@metamask/[email protected]':
resolution: {integrity: sha512-ihb3B0T/wJm1eUuArYP4lCTSEoZsClHhuWyfo/kMX3m/odpqNcPfsz5O2A3NT7dXCAgWPGDQGPqygCpgeniKMw==}
engines: {node: '>=12.0.0'}
'@metamask/[email protected]':
resolution: {integrity: sha512-yfmE79bRQtnMzarnKfX7AEJBwFTxvTyw3nBQlu/5rmGXrjAeAMltoGxO62TFurxrQAFMNa/fEjIHNvungZp0+g==}
engines: {node: '>=14.0.0'}
'@metamask/[email protected]':
resolution: {integrity: sha512-dbIc3C7alOe0agCuBHM1h71UaEaEqOk2W8rAtEn8QGz4haH2Qq7MoK6i7v2guzvkJVVh79c+QCzIqphC3KvrJg==}
engines: {node: '>=16.0.0'}
'@microsoft/[email protected]':
resolution: {integrity: sha512-hGERhz4L11zni1ifapBK3zhHFcX1QIGoTf0WzoCC0mI2IXfWDJ5ToYMZTPO6qPmn3ElrZtSWcoaHVkaRz16Q/Q==}
hasBin: true
@@ -9383,9 +9347,6 @@ packages:
[email protected]:
resolution: {integrity: sha512-mFGTtlEpOugOoLOf9H5AJyJaZUNtOVXLGGOnPaPZDPQex6W6iIOgtV+fAgam0GQbgnLfgX+Wn/QzS6d+PYfFAQ==}
[email protected]:
resolution: {integrity: sha512-Hs4R+4SPgamu6rSGW8C7cV9gaWUKEHykfzCCvIRuaVv636Ju10ZdeUbvb4TBEW0INuq2DHZqXbK4Nd3yG4RaRw==}
[email protected]:
resolution: {integrity: sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==}
@@ -11268,23 +11229,12 @@ packages:
resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==}
engines: {node: '>= 0.6'}
[email protected]:
resolution: {integrity: sha512-8YdplnuE1IK4xfqpf4iU7oBxnOYAc35934o083G8ao+8WM8QQtt/mVlAY6yIAdY1eMeLqg4Z//PZjJGmWGPMRg==}
engines: {node: '>=14.0.0'}
[email protected]:
resolution: {integrity: sha512-ITJTvqoCw6OVMLs7pI8f4gG92n/St6x80ACtHodeS+IXmO0w+t1T5OOzfSt7KLSMLRkVUoexV7tztLgDxg+iig==}
engines: {node: '>=14.0.0'}
[email protected]:
resolution: {integrity: sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==}
[email protected]:
resolution: {integrity: sha512-/i0qSQby/rt3CCZrNVlgBdCUYQBwULStFRlBt7+ULNVpwbsYWl9VWXFaQxsbJLOo0x7swRS3OknIdlxlunsGJw==}
[email protected]:
resolution: {integrity: sha512-srES0ZcvwkR/wd5OQBRA1bIJMww1skfGS0s8wlwK3/oNP4+wnds60krvu5R1QbpRQjMmpG5OMIWro5s7gvDPsA==}
[email protected]:
resolution: {integrity: sha512-Z3ymjopaoft7JDoxZcEb3pwdGh7yiYMhOwm2doUt6ASXlMavpNlK6Cre0+IMl2VSGyEU9rkiperQhp5iRxn5Pg==}
@@ -13060,13 +13010,6 @@ packages:
[email protected]:
resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==}
[email protected]:
resolution: {integrity: sha512-NEdLrtrq1jUZyfjkr9OCz9EzCNhnRyWtt1PAnvnhwy6e8XETS0Dtc+ZNCO2gvuAoKsIn2+vCSowXTYE4CkgnAQ==}
engines: {node: '>=10.0.0'}
[email protected]:
resolution: {integrity: sha512-RJ9YYNCkhVDBuP4zN5BBtYAzEl03yq/jIIsyif0JY9qyJuQQZNeDK7anAPKKlyEtLSj2s8h6hNh2F8zO5q7ScA==}
[email protected]:
resolution: {integrity: sha512-YBOEogm5w9Op337yb6pAT6ZXDqlxAsQCanM3grid8lMWNxRJO/zWEJi3ZzqDL8boWfwhTFym5EFrNgWwpqcBRg==}
engines: {node: '>=6.0.0'}
@@ -14888,10 +14831,6 @@ packages:
resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==}
engines: {node: '>=6'}
[email protected]:
resolution: {integrity: sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==}
engines: {node: '>=10'}
[email protected]:
resolution: {integrity: sha512-+KAgmVeqXYbTtU2FScx1XS3kNyfZ5TrXY07V96QnUSFqo2gAqlvmaxH67Lj7SWazqsMabf+58ctdTcBgnOLUOQ==}
@@ -14964,10 +14903,6 @@ packages:
resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==}
engines: {node: '>=10.13.0'}
[email protected]:
resolution: {integrity: sha512-M7LhCsdNbNgiLYiP4WjsfLUuFmCfnjdF6jKe2R9NKl4WFN+HZPGHJZ9lnLP7f9ZnKe3U9nuWD0szirmj+migUg==}
engines: {node: '>=12.0.0'}
[email protected]:
resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==}
engines: {node: '>= 0.4'}
@@ -16630,10 +16565,6 @@ packages:
[email protected]:
resolution: {integrity: sha512-nMIjMrd5Z2nuB2RZCKJfFMjgS3fygbeyGk9PxPPaJR1RIcyN9yn4A63Isovzm3ZtQuEkLBVgMdPup8UeLH7aQw==}
[email protected]:
resolution: {integrity: sha512-7JpaAoX2NGyoFlI9NBh66BQXGONc+uE+MRS5i2iOBKuS4e+ccgMDjATgZldkah+33DakBxDHiss9kvUcGAO8UQ==}
engines: {node: '>=14.0.0'}
[email protected]:
resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==}
engines: {node: '>=4'}
@@ -23101,21 +23032,16 @@ snapshots:
react-native: 0.74.2(@babel/[email protected])(@babel/[email protected](@babel/[email protected]))(@types/[email protected])([email protected])([email protected])([email protected])
react-native-mmkv: 2.11.0([email protected](@babel/[email protected])(@babel/[email protected](@babel/[email protected]))(@types/[email protected])([email protected])([email protected])([email protected]))([email protected])
'@coinbase/wallet-sdk@3.9.3':
'@coinbase/wallet-sdk@4.0.3':
dependencies:
bn.js: 5.2.1
buffer: 6.0.3
clsx: 1.2.1
eth-block-tracker: 7.1.0
eth-json-rpc-filters: 6.0.1
eventemitter3: 5.0.1
keccak: 3.0.4
preact: 10.22.0
sha.js: 2.4.11
transitivePeerDependencies:
- supports-color
'@coinbase/[email protected].3':
'@coinbase/[email protected].4':
dependencies:
buffer: 6.0.3
clsx: 1.2.1
@@ -23557,22 +23483,8 @@ snapshots:
crc-32: 1.2.2
ethereumjs-util: 7.1.5
'@ethereumjs/[email protected]':
dependencies:
'@ethereumjs/util': 9.0.3
crc-32: 1.2.2
'@ethereumjs/[email protected]': {}
'@ethereumjs/[email protected]': {}
'@ethereumjs/[email protected]':
dependencies:
'@ethereumjs/common': 3.2.0
'@ethereumjs/rlp': 4.0.1
'@ethereumjs/util': 9.0.3
ethereum-cryptography: 2.1.3
'@ethereumjs/[email protected]':
dependencies:
'@ethereumjs/rlp': 5.0.2
@@ -24493,14 +24405,6 @@ snapshots:
jju: 1.4.0
read-yaml-file: 1.1.0
'@metamask/[email protected]':
dependencies:
'@metamask/json-rpc-engine': 7.3.3
'@metamask/safe-event-emitter': 3.1.1
'@metamask/utils': 5.0.2
transitivePeerDependencies:
- supports-color
'@metamask/[email protected]':
dependencies:
ethereumjs-abi: 0.6.8
@@ -24509,49 +24413,8 @@ snapshots:
tweetnacl: 1.0.3
tweetnacl-util: 0.15.1
'@metamask/[email protected]':
dependencies:
'@metamask/rpc-errors': 6.2.1
'@metamask/safe-event-emitter': 3.1.1
'@metamask/utils': 8.4.0
transitivePeerDependencies:
- supports-color
'@metamask/[email protected]':
dependencies:
'@metamask/utils': 8.4.0
fast-safe-stringify: 2.1.1
transitivePeerDependencies:
- supports-color
'@metamask/[email protected]': {}
'@metamask/[email protected]': {}
'@metamask/[email protected]':
dependencies:
'@ethereumjs/tx': 4.2.0
'@types/debug': 4.1.12
debug: 4.3.5([email protected])
semver: 7.6.2
superstruct: 1.0.4
transitivePeerDependencies:
- supports-color
'@metamask/[email protected]':
dependencies:
'@ethereumjs/tx': 4.2.0
'@noble/hashes': 1.4.0
'@scure/base': 1.1.6
'@types/debug': 4.1.12
debug: 4.3.5([email protected])
pony-cause: 2.1.11
semver: 7.6.2
superstruct: 1.0.4
uuid: 9.0.1
transitivePeerDependencies:
- supports-color
'@microsoft/[email protected](@types/[email protected])':
dependencies:
'@microsoft/api-extractor-model': 7.29.2(@types/[email protected])
@@ -30382,10 +30245,6 @@ snapshots:
- supports-color
- utf-8-validate
[email protected]:
dependencies:
tslib: 2.6.2
[email protected]:
dependencies:
retry: 0.13.1
@@ -32799,24 +32658,6 @@ snapshots:
[email protected]: {}
[email protected]:
dependencies:
'@metamask/eth-json-rpc-provider': 1.0.1
'@metamask/safe-event-emitter': 3.1.1
'@metamask/utils': 5.0.2
json-rpc-random-id: 1.0.1
pify: 3.0.0
transitivePeerDependencies:
- supports-color
[email protected]:
dependencies:
'@metamask/safe-event-emitter': 3.1.1
async-mutex: 0.2.6
eth-query: 2.1.2
json-rpc-engine: 6.1.0
pify: 5.0.0
[email protected]:
dependencies:
bn.js: 4.12.0
@@ -32835,11 +32676,6 @@ snapshots:
- bufferutil
- utf-8-validate
[email protected]:
dependencies:
json-rpc-random-id: 1.0.1
xtend: 4.0.2
[email protected]:
dependencies:
fast-safe-stringify: 2.1.1
@@ -35078,13 +34914,6 @@ snapshots:
[email protected]: {}
[email protected]:
dependencies:
'@metamask/safe-event-emitter': 2.0.0
eth-rpc-errors: 4.0.3
[email protected]: {}
[email protected]:
dependencies:
clone: 2.1.2
@@ -37330,8 +37159,6 @@ snapshots:
[email protected]: {}
[email protected]: {}
[email protected]:
dependencies:
duplexify: 4.1.3
@@ -37422,8 +37249,6 @@ snapshots:
[email protected]: {}
[email protected]: {}
[email protected]: {}
[email protected]([email protected]):
@@ -39623,8 +39448,6 @@ snapshots:
[email protected]: {}
[email protected]: {}
[email protected]:
dependencies:
has-flag: 3.0.0