diff --git a/assets/_locales/en/messages.json b/assets/_locales/en/messages.json index 23024ec24..f7f4a82a1 100644 --- a/assets/_locales/en/messages.json +++ b/assets/_locales/en/messages.json @@ -589,6 +589,14 @@ "message": "Confirm", "description": "Confirm button text" }, + "confirm_transaction": { + "message": "Confirm Transaction", + "description": "Confirm Transaction Header" + }, + "subscription_payment": { + "message": "Subscription Payment", + "description": "Subscribtion payment header" + }, "removed_wallet_notification": { "message": "Removed wallet", "description": "Notification for wallet removal" @@ -915,6 +923,10 @@ "message": "network fee", "description": "Transaction network fee text" }, + "estimated": { + "message": "estimated", + "description": "estimated" + }, "invalid_amount": { "message": "Amount has to be more than 0", "description": "Invalid tx amount message" @@ -1229,10 +1241,18 @@ "message": "Scan the QR code below with your hardware wallet", "description": "Request to scan signature QR" }, + "viewblock": { + "message": "Viewblock", + "description": "view block" + }, "keystone_connect_title": { "message": "Connect Keystone", "description": "Connect keystone hardware wallet button" }, + "keystone_scan": { + "message": "Scan Response", + "description": "Notification about a keystone scanning error" + }, "keystone_scan_error": { "message": "There was an error scanning the QR code", "description": "Notification about a keystone scanning error" @@ -1365,6 +1385,10 @@ "message": "Sending transaction...", "description": "Sending transaction loading text" }, + "transaction_sending_token": { + "message": "Sending", + "description": "Sending token description in confirmation " + }, "not_connected": { "message": "Not connected", "description": "Not connected indicator" @@ -1377,6 +1401,14 @@ "message": "Disconnect", "description": "Disconnect button text" }, + "disconnected": { + "message": "Disconnected", + "description": "Disconnected tooltip" + }, + "account_connected": { + "message": "Account Connected", + "description": "Connected tooltip" + }, "copy_address": { "message": "Copy address", "description": "Click to copy address tooltip" @@ -1401,6 +1433,10 @@ "message": "Lock wallet", "description": "Lock wallet and terminate current session icon button" }, + "home": { + "message":"Home", + "description": "Home Button" + }, "home_no_balance": { "message": "Add $AR$ to get started", "description": "No balance message on homescreen", @@ -1443,6 +1479,14 @@ "message": "Introducing Notifications", "description": "Alternative Enable Notification title" }, + "no_notifications": { + "message": "No notifications at this time.", + "description": "No notifications title" + }, + "no_notifications_get_started": { + "message": "Send transactions to get started.", + "description": "Send Transactions to get notifications" + }, "enable_notifications_paragraph": { "message": "Stay updated with instant alerts for transactions and ao messages.", "description": "Enable notifications paragraph" @@ -1746,6 +1790,10 @@ "message": "AO testnet is now live!", "description": "ao announcement title text" }, + "ao_token_announcement_title": { + "message": "Congrats on the AO Token 4 year emissions rewards 🥳", + "description": "ao token announcement title text" + }, "ao_degraded": { "message": "AO Token Process Network Degraded.", "description": "ao degraded title text" @@ -1774,6 +1822,14 @@ "message": "Token Succesfully Removed", "description": "token removed" }, + "transaction_complete": { + "message": "Transaction Complete", + "description": "transaction complete header" + }, + "message": { + "message": "Message", + "description": "message header" + }, "subscription_allowance": { "message": "Subscription Allowance", "description": "subscription settings title" @@ -1782,6 +1838,18 @@ "message": "Subscription", "description": "subscription title" }, + "subscriptions": { + "message": "Subscriptions", + "description": "subscriptions title" + }, + "no_subscriptions": { + "message": "No subscriptions yet", + "description": "No subscriptions title" + }, + "no_subscriptions_description": { + "message": "Your future subscriptions will be available here", + "description": "No subscriptions description" + }, "subscribe_description": { "message": "APPNAME requests to set up a subscription with recurring payments", "description": "subscribe description" @@ -1809,5 +1877,78 @@ "subscription_add_failure": { "message": "Failed to add subscription", "description": "Failed to add subscription error message" + }, + "transaction_history_title": { + "message": "Transaction History", + "description": "Transaction History header" + }, + + "subscription_application_address": { + "message": "Application Address", + "description": "Address where payment will be made to" + }, + + + "subscription_recurring_amount": { + "message": "Recurring payment amount", + "description": "Recurring payment amount" + }, + + "auto_renewal": { + "message": "Auto-renewal", + "description": "auto-renewal" + }, + "auto_pay": { + "message": "Auto-Pay", + "description": "auto-pay" + }, + "confirm_subscription": { + "message": "Confirm Subscription", + "description": "confirm subscription" + }, + + "end": { + "message": "End", + "description": "end" + }, + "next_payment": { + "message": "Next payment", + "description": "next payment" + }, + "start": { + "message": "Start", + "description": "start" + }, + "Quarterly": { + "message": "Quarterly", + "description": "quarterly frequency" + }, + "Monthly": { + "message": "Monthly", + "description": "monthly frequency" + }, + "Weekly": { + "message": "Weekly", + "description": "weekly frequency" + }, + "Daily": { + "message": "Daily", + "description": "daily frequency" + }, + "transactions": { + "message": "Transactions", + "descriptions": "Transactions title" + }, + "no_transactions": { + "message": "No transactions found", + "description": "No transactions message" + }, + "sent": { + "message": "Sent", + "description": "sent" + }, + "received": { + "message": "Received", + "description": "received" } } diff --git a/assets/_locales/zh_CN/messages.json b/assets/_locales/zh_CN/messages.json new file mode 100644 index 000000000..da05eb714 --- /dev/null +++ b/assets/_locales/zh_CN/messages.json @@ -0,0 +1,1952 @@ +{ + "extensionDescription": { + "message": "Arweave 的安全钱包管理", + "description": "Extension description" + }, + "clickToCopy": { + "message": "点击复制", + "description": "Text to indicate the ability to copy something" + }, + "switchedToWallet": { + "message": "已切换到 $ADDRESS$", + "description": "Notification on switching active wallet", + "placeholders": { + "address": { + "content": "$1", + "example": "ljvCPN31...-CS-6Iho8U" + } + } + }, + "yes": { + "message": "是", + "description": "The word \"yes\"" + }, + "no": { + "message": "否", + "description": "The word \"no\"" + }, + "accept": { + "message": "接受", + "description": "Accept terms" + }, + "add_wallet": { + "message": "添加钱包", + "description": "Add a wallet text" + }, + "analytics_description": { + "message": "我们现在使用分析工具。", + "description": "Opting into Analytics text" + }, + "analytics_title": { + "message": "选择加入分析", + "description": "Analytics title" + }, + "edit": { + "message": "编辑", + "description": "Edit text" + }, + "appConnected": { + "message": "应用已连接", + "description": "Application connected text" + }, + "appNotConnected": { + "message": "应用未连接", + "description": "Application connected text" + }, + "forceConnect": { + "message": "强制连接", + "description": "Force connect button text" + }, + "decline": { + "message": "拒绝", + "description": "Decline terms" + }, + "devtools": { + "message": "开发者工具", + "description": "Devtools name" + }, + "gatewayNotTestnet": { + "message": "网关不是测试网网络", + "description": "Gateway not a testnet notification" + }, + "mint": { + "message": "铸造", + "description": "Mint button text" + }, + "mintAr": { + "message": "铸造 AR", + "description": "Mint AR tokens title" + }, + "arMinted": { + "message": "铸造了 $QTY$ AR 到 $ADDRESS$", + "description": "Message on arweave minted to an address", + "placeholders": { + "qty": { + "content": "$1", + "example": "10" + }, + "address": { + "content": "$2", + "example": "ljvCPN31...-CS-6Iho8U" + } + } + }, + "tokenMintFailed": { + "message": "铸造代币失败", + "description": "Message indicating minting failure" + }, + "mine": { + "message": "挖矿", + "description": "Mine button text" + }, + "mined": { + "message": "已挖矿", + "description": "Mine success message" + }, + "miningFailed": { + "message": "挖矿失败", + "description": "Mine failure message" + }, + "fillOutQtyField": { + "message": "请填写数量字段", + "description": "Fill out qty field error" + }, + "fillOutTargetField": { + "message": "请填写目标字段", + "description": "Fill out target field error" + }, + "addFileError": { + "message": "请添加文件", + "description": "Add file error" + }, + "couldNotReadTxData": { + "message": "无法读取交易数据文件", + "description": "File reading failure for tx data" + }, + "invalidPassword": { + "message": "密码无效", + "description": "Invalid password error" + }, + "testnetLive": { + "message": "测试网已上线", + "description": "Testnet live message" + }, + "testnetDown": { + "message": "测试网已离线", + "description": "Testnet offline message" + }, + "testnetGatewayUrlLabel": { + "message": "测试网网关网址", + "description": "Label indicating the input content to be the testnet gateway url" + }, + "arlocalCommandTutorial": { + "message": "没有安装 ArLocal?像这样运行它:", + "description": "Tutorial for the user on running ArLocal" + }, + "addTestnetTokensSubtitle": { + "message": "将测试网代币添加到您的钱包", + "description": "Subtitle indicating the ability to add testnet AR tokens to the active wallet" + }, + "analytics": { + "message": "分析", + "description": "Analytics text" + }, + "arQtyPlaceholder": { + "message": "AR 数量...", + "description": "Placeholder for AR amount input" + }, + "createTransaction": { + "message": "创建交易", + "description": "Create transaction title" + }, + "createTransactionSubtitle": { + "message": "发送带有标签和数据的交易", + "description": "Send transaction subtitle" + }, + "leaveEmptyForNone": { + "message": "留空表示无...", + "description": "Placeholder for inputs that take empty values as none" + }, + "target": { + "message": "目标", + "description": "Target label" + }, + "amount": { + "message": "金额", + "description": "Amount label" + }, + "tags": { + "message": "标签", + "description": "Tags label" + }, + "name": { + "message": "名称", + "description": "Name label" + }, + "tagNamePlaceholder": { + "message": "标签名称...", + "description": "Tag name placeholder" + }, + "value": { + "message": "值", + "description": "Value label" + }, + "tagValuePlaceholder": { + "message": "标签值...", + "description": "Tag value placeholder" + }, + "addTag": { + "message": "添加标签", + "description": "Add tag button" + }, + "data": { + "message": "数据", + "description": "Data label" + }, + "dragAndDropFile": { + "message": "拖放文件...", + "description": "File input label" + }, + "password": { + "message": "密码", + "description": "Password label" + }, + "new_password": { + "message": "新密码", + "description": "Password label" + }, + "confirm_new_password": { + "message": "重新输入新密码", + "description": "Password label" + }, + "enterPasswordToDecrypt": { + "message": "输入密码以解密钱包...", + "description": "Password request to decrypt wallet" + }, + "sendTransaction": { + "message": "发送交易", + "description": "Send transaction button" + }, + "permissionDescriptionAccessAddress": { + "message": "访问 ArConnect 中选择的当前地址", + "description": "Description for the \"ACCESS_ADDRESS\" permission" + }, + "permissionDescriptionAccessPublicKey": { + "message": "访问 ArConnect 中选择的当前地址的公钥", + "description": "Description for the \"ACCESS_PUBLIC_KEY\" permission" + }, + "permissionDescriptionAccessAllAddresses": { + "message": "访问添加到 ArConnect 的所有地址", + "description": "Description for the \"ACCESS_ALL_ADDRESSES\" permission" + }, + "permissionDescriptionSign": { + "message": "签署交易", + "description": "Description for the \"SIGN_TRANSACTION\" permission" + }, + "permissionDescriptionEncrypt": { + "message": "使用用户的密钥文件加密数据", + "description": "Description for the \"ENCRYPT\" permission" + }, + "permissionDescriptionDecrypt": { + "message": "使用用户的密钥文件解密数据", + "description": "Description for the \"DECRYPT\" permission" + }, + "permissionDescriptionSignature": { + "message": "使用用户的密钥文件签署数据", + "description": "Description for the \"SIGNATURE\" permission" + }, + "permissionDescriptionArweaveConfig": { + "message": "访问用户的自定义 Arweave 配置", + "description": "Description for the \"ACCESS_ARWEAVE_CONFIG\" permission" + }, + "permissionDescriptionDispatch": { + "message": "发送 Arweave 交易或互动", + "description": "Description for the \"DISPATCH\" permission" + }, + "copyId": { + "message": "复制 ID", + "description": "Copy ID button text" + }, + "connectionFailure": { + "message": "无法连接到应用", + "description": "Notification about app connection failure in devtools" + }, + "permissions": { + "message": "权限", + "description": "Permissions title" + }, + "allowance": { + "message": "额度", + "description": "Allowance title" + }, + "allowanceTip": { + "message": "为此应用设置支出限制", + "description": "Tip explaining allowances for the user" + }, + "enabled": { + "message": "已启用", + "description": "Enabled label" + }, + "disabled": { + "message": "已禁用", + "description": "Disabled label" + }, + "u_token_disabled": { + "message": "目前无法转移 U-Token", + "description": "U-token Disabled label" + }, + "spent": { + "message": "已支出", + "description": "Spent text" + }, + "reset": { + "message": "重置", + "description": "Reset text" + }, + "resetSpentQty": { + "message": "重置已支出数量", + "description": "Reset tooltip text" + }, + "limit": { + "message": "限制", + "description": "Limit text" + }, + "gateway": { + "message": "网关", + "description": "Gateway title" + }, + "bundlrNode": { + "message": "Bundler 节点", + "description": "Bundler node title" + }, + "removeApp": { + "message": "移除应用", + "description": "Remove app button" + }, + "removeAppNote": { + "message": "移除所有权限并断开与 ArConnect 的应用连接。", + "description": "Remove app note paragraph" + }, + "remove": { + "message": "移除", + "description": "Remove button text" + }, + "block": { + "message": "阻止", + "description": "Block button" + }, + "unblock": { + "message": "取消阻止", + "description": "Unblock button" + }, + "setCustomGateway": { + "message": "设置自定义网关", + "description": "Notification about setting a custom gateway for an app" + }, + "settings": { + "message": "设置", + "description": "Settings title" + }, + "setting_apps": { + "message": "应用程序", + "description": "Apps settings title" + }, + "setting_wallets": { + "message": "钱包", + "description": "Wallets settings title" + }, + "setting_config": { + "message": "下载配置", + "description": "Config settings title" + }, + "setting_about": { + "message": "关于", + "description": "About settings title" + }, + "setting_reset": { + "message": "重置", + "description": "Reset settings title" + }, + "setting_analytic": { + "message": "分析", + "description": "Analytics to help make ArConnect better" + }, + "setting_fee_multiplier": { + "message": "费用倍数", + "description": "Fee multiplier settings title" + }, + "setting_currency": { + "message": "货币", + "description": "Reset settings title" + }, + "setting_dre_node": { + "message": "Warp DRE 节点", + "description": "Warp DRE node setting title" + }, + "setting_arverify": { + "message": "ArVerify 阈值", + "description": "ArVerify settings title" + }, + "setting_arconfetti": { + "message": "ArConfetti 效果", + "description": "ArConfetti effect settings title" + }, + "setting_sign_notification": { + "message": "签署通知", + "description": "Sign notification settings title" + }, + "setting_sign_settings": { + "message": "签名设置", + "description": "Sign settings title" + }, + "setting_display_theme": { + "message": "主题", + "description": "Theme settings title" + }, + "setting_wayfinder": { + "message": "Wayfinder", + "description": "Wayfinder settings title" + }, + "setting_notifications": { + "message": "通知", + "description": "Notifications settings title" + }, + "setting_notifications_description": { + "message": "切换以接收钱包中新交易的提醒", + "description": "Notifications settings description" + }, + "setting_apps_description": { + "message": "查看所有已连接的应用程序和设置", + "description": "App settings description" + }, + "setting_wallets_description": { + "message": "管理您的钱包", + "description": "Wallet settings description" + }, + "setting_config_description": { + "message": "下载 ArConnect 配置", + "description": "Config settings description" + }, + "setting_about_description": { + "message": "关于 ArConnect 的信息", + "description": "Config settings description" + }, + "setting_reset_description": { + "message": "移除所有钱包和数据", + "description": "Reset settings description" + }, + "setting_analytics_description": { + "message": "向 ArConnect 团队提供有用的匿名数据以改进项目", + "description": "ArConnect Analytics description" + }, + "setting_fee_multiplier_description": { + "message": "控制交易后的费用", + "description": "Fee multiplier settings description" + }, + "setting_setting_currency_description": { + "message": "法定货币显示", + "description": "Currency settings description" + }, + "setting_setting_dre_node_description": { + "message": "设置首选的 DRE 节点以进行合约评估", + "desription": "Preferred DRE node setting description" + }, + "setting_setting_arverify_description": { + "message": "设置使用的验证阈值", + "description": "Arverify settings description" + }, + "setting_setting_arconfetti_description": { + "message": "在使用钱包时显示动画", + "description": "ArConfetti settings description" + }, + "setting_sign_notification_description": { + "message": "签署交易时通知", + "description": "Sign notification settings description" + }, + "setting_display_theme_description": { + "message": "扩展 UI 的主题", + "description": "Display theme settings description" + }, + "setting_wayfinder_description": { + "message": "针对 ar.io 网关的实验性系统范围导航器", + "description": "Wayfinder settings description" + }, + "search_pick_option": { + "message": "搜索选项...", + "description": "Search input placeholder for the \"pick\" option component" + }, + "search_apps": { + "message": "搜索应用...", + "description": "Search input placeholder for apps" + }, + "search_wallets": { + "message": "搜索钱包...", + "description": "Search input placeholder for wallets" + }, + "export_keyfile": { + "message": "导出密钥文件", + "description": "Export keyfile button" + }, + "remove_wallet": { + "message": "移除钱包", + "description": "Remove wallet button" + }, + "edit_wallet_name": { + "message": "编辑名称", + "description": "Edit wallet name title in settings" + }, + "updated_wallet_name": { + "message": "已更新钱包名称", + "description": "Wallet name update notification content" + }, + "error_updating_wallet_name": { + "message": "更新钱包名称时出错", + "description": "Wallet name update error notification content" + }, + "copied_address": { + "message": "$NAME$ ($ADDRESS$) 地址已复制", + "description": "Address copy notification", + "placeholders": { + "name": { + "content": "$1", + "example": "Account 1" + }, + "address": { + "content": "$2", + "example": "ljvCPN31...-CS-6Iho8U" + } + } + }, + "copied_address_2": { + "message": "地址已复制", + "description": "Address copy notification 2" + }, + "cannot_edit_with_ans": { + "message": "无法编辑昵称。钱包已经有 ANS 标签。", + "description": "Explainer for disabled edits for wallets with ANS profiles" + }, + "add_wallet_subtitle": { + "message": "您可以添加任意数量", + "description": "Subtitle for add wallet section" + }, + "drag_and_drop_wallet": { + "message": "拖放钱包...", + "description": "Wallet input text" + }, + "enter_new_password": { + "message": "输入新密码...", + "description": "Password input placeholder" + }, + "reenter_new_password": { + "message": "重新输入新密码...", + "description": "Re-enter input placeholder" + }, + "enter_password": { + "message": "输入您的密码...", + "description": "Password input placeholder" + }, + "enter_password_again": { + "message": "重新输入您的密码...", + "description": "Re-enter password input placeholder" + }, + "passwords_match": { + "message": "密码匹配!", + "description": "Passwords are matching indicator text" + }, + "passwords_not_match": { + "message": "密码不匹配", + "description": "Invalid re-entered password error" + }, + "passwords_match_previous": { + "message": "新密码不能与旧密码相同", + "description": "Password must be different from old one" + }, + "invalid_mnemonic": { + "message": "无效的助记词", + "description": "Invalid mnemonic seedphrase error notification" + }, + "added_wallet": { + "message": "已添加钱包", + "description": "Added wallets notification" + }, + "error_adding_wallet": { + "message": "添加钱包出错。请检查您的密码", + "description": "Error on wallet adding notification" + }, + "no_apps_added": { + "message": "尚未添加应用...", + "description": "No apps added message" + }, + "remove_wallet_modal_title": { + "message": "移除钱包?", + "description": "Remove wallet modal title" + }, + "remove_wallet_modal_content": { + "message": "您确定要继续吗?此操作无法撤销。", + "description": "Remove wallet modal content" + }, + "confirm": { + "message": "确认", + "description": "Confirm button text" + }, + "confirm_transaction": { + "message": "确认交易", + "description": "Confirm Transaction Header" + }, + "subscription_payment": { + "message": "订阅付款", + "description": "Subscribtion payment header" + }, + "removed_wallet_notification": { + "message": "已移除钱包", + "description": "Notification for wallet removal" + }, + "remove_wallet_error_notification": { + "message": "移除钱包出错", + "description": "Notification for wallet removal error" + }, + "cancel": { + "message": "取消", + "description": "Cancel button text" + }, + "export": { + "message": "导出", + "description": "Export button text" + }, + "export_wallet_modal_title": { + "message": "导出钱包", + "description": "Export wallet modal title" + }, + "export_wallet_error": { + "message": "导出钱包出错", + "description": "Wallet export error notification" + }, + "development_version": { + "message": "开发版本", + "description": "Development version badge text" + }, + "permissions_used": { + "message": "我们使用了以下权限:", + "description": "Used permissions label" + }, + "reset_warning": { + "message": "重置 ArConnect 将删除您所有的数据。这包括您的钱包、设置和缓存数据。", + "description": "Warning about resetting ArConnect" + }, + "irreversible_action": { + "message": "此操作是不可逆的!", + "description": "Warning about an irreversible action" + }, + "reset_error": { + "message": "无法重置 ArConnect", + "description": "Error message on reset" + }, + "welcome_to": { + "message": "欢迎来到", + "description": "\"Welcome to\" text" + }, + "get_me_started": { + "message": "开始使用", + "description": "Get me started button text" + }, + "have_wallet": { + "message": "我有一个钱包", + "description": "Has wallet button text" + }, + "skip": { + "message": "跳过", + "description": "Skip label" + }, + "next": { + "message": "下一步", + "description": "Next button text" + }, + "what_is_arweave": { + "message": "什么是 Arweave?", + "description": "What is arweave title" + }, + "about_arweave": { + "message": "Arweave 是一个允许您永久、可持续地存储数据的协议,只需一次性支付。该协议将拥有多余硬盘空间的人与需要永久存储数据或托管内容的个人和组织连接起来。", + "description": "A short paragraph explaining Arweave" + }, + "what_is_the_permaweb": { + "message": "什么是永久网络?", + "description": "What is the permaweb title" + }, + "about_permaweb": { + "message": "Arweave 上的永久网络是网络的下一次进化,使开发者和用户能够共享一个在全球范围内大量复制的有韧性的知识库,永久存在。除了数据,Arweave 还托管许多完全去中心化的永久应用程序。", + "description": "A short paragraph explaining the permaweb" + }, + "what_is_arconnect": { + "message": "什么是 ArConnect?", + "description": "What is arconnect title" + }, + "about_arconnect": { + "message": "ArConnect 是一个加密钱包扩展,允许您安全地与永久网络应用程序互动。它还让您可以轻松存储和管理资金。使用 ArConnect,您可以简单无缝地进入 Arweave 生态系统。", + "description": "A short paragraph explaining arconnect" + }, + "read_more_arwiki": { + "message": "阅读更多在", + "description": "\"Read more at (ArWiki)\" text" + }, + "backup": { + "message": "备份", + "description": "Backup title" + }, + "backup_wallet_title": { + "message": "备份您的钱包", + "description": "Backup wallet title" + }, + "backup_wallet_content": { + "message": "将这 12 个字的助记词保存到密码管理器,或将其写在纸上。永远不要与任何人分享。", + "description": "Backup wallet paragraph" + }, + "copySeed": { + "message": "复制助记词", + "description": "Copy seedphrase text" + }, + "done": { + "message": "完成", + "description": "Done button text" + }, + "setup_complete_title": { + "message": "设置完成", + "description": "Setup complete title" + }, + "generated_wallet": { + "message": "您的 Arweave 钱包地址为 $ADDRESS$ 已生成。您现在可以开始浏览永久网络了!", + "description": "Generated wallet notification", + "placeholders": { + "address": { + "content": "$1", + "example": "ljvCPN31...-CS-6Iho8U" + } + } + }, + "error_generating_wallet": { + "message": "生成钱包出错", + "description": "Error generating wallet notification" + }, + "written_down_seed": { + "message": "我已写下我的助记词", + "description": "Label for written down seedphrase checkbox" + }, + "generating_wallet": { + "message": "生成钱包中...", + "description": "Generating wallet in progress text" + }, + "keyfile": { + "message": "密钥文件", + "description": "Keyfile text" + }, + "confirm_seed": { + "message": "确认您的助记词", + "description": "Confirm seedphrase title" + }, + "confirm_seed_paragraph": { + "message": "通过在以下部分中完成缺失的助记词单词来验证您的助记词。", + "description": "Confirm seedphrase explainer paragraph" + }, + "correct": { + "message": "正确", + "description": "Correct text" + }, + "invalid_seed": { + "message": "输入的单词无效。请再试一次", + "description": "Invalid seed order notification" + }, + "create_password": { + "message": "创建密码", + "description": "Create password title" + }, + "create_password_paragraph": { + "message": "输入一个密码以保护 ArConnect。我们将使用此密码加密您的钱包。", + "description": "Create password explainer paragraph" + }, + "password_not_strong": { + "message": "您的密码不够强", + "description": "Notification about bad password strength" + }, + "password_strength_1": { + "message": "密码太弱", + "description": "Level 1 strength password text" + }, + "password_strength_2": { + "message": "弱密码", + "description": "Level 2 strength password text" + }, + "password_strength_3": { + "message": "还行的密码", + "description": "Level 3 strength password text" + }, + "password_strength_4": { + "message": "强密码", + "description": "Level 4 strength password text" + }, + "password_strength_5": { + "message": "非常强的密码", + "description": "Level 5 strength password text" + }, + "password_strength_checklist_case": { + "message": "使用小写和大写字母", + "description": "Password strength checklist lowercase and uppercase element" + }, + "password_strength_checklist_number": { + "message": "使用数字", + "description": "Password strength checklist number element" + }, + "password_strength_checklist_symbol": { + "message": "使用符号", + "description": "Password strength checklist symbol element" + }, + "password_strength_checklist_length": { + "message": "至少 10 个字符长", + "description": "Password strength checklist length element" + }, + "no_wallets_added": { + "message": "未添加钱包", + "description": "No wallets added title (devtools)" + }, + "no_wallets_added_paragraph": { + "message": "访问设置页面以使用此功能。", + "description": "No wallets added text (devtools)" + }, + "setup": { + "message": "设置", + "description": "Setup button text" + }, + "or": { + "message": "或", + "description": "\"Or\" text" + }, + "enter_seedphrase": { + "message": "输入助记词...", + "description": "Enter seedphrase input placeholder" + }, + "generate_wallet": { + "message": "生成钱包", + "description": "Generate wallet button text" + }, + "enter_pw_gen_wallet": { + "message": "输入密码以生成钱包", + "description": "Request to enter password before generating a wallet in settings" + }, + "select_recipient": { + "message": "选择接收者", + "description": "Select recipient when sending currency" + }, + "send_to": { + "message": "发送到", + "description": "Send To for slider menu" + }, + "no_close_window": { + "message": "不要关闭窗口!", + "description": "Request to not close the window" + }, + "generated_wallet_dashboard": { + "message": "钱包已生成,您现在可以关闭窗口了", + "description": "Notification about wallet generation" + }, + "provide_seedphrase": { + "message": "提供助记词", + "description": "Provide seedphrase for title in load wallet setup" + }, + "provide_seedphrase_paragraph": { + "message": "拖放您的密钥文件或输入您生成钱包时保存的 12 个字的助记词。确保其顺序正确。", + "description": "Explainer about the seedphrase loading" + }, + "sign_in": { + "message": "登录", + "description": "Sign In title" + }, + "app_wants_to_connect": { + "message": "一个应用想要连接", + "description": "App wants to connect label" + }, + "wallet": { + "message": "钱包", + "description": "Wallet label" + }, + "enter_your_password": { + "message": "输入您的密码...", + "description": "Enter password placeholder" + }, + "connect": { + "message": "连接", + "description": "Connect button text" + }, + "allow_these_permissions": { + "message": "允许这些权限给应用程序:", + "description": "Auth permissions label" + }, + "reset_allowance": { + "message": "重置额度", + "description": "Reset allowance title" + }, + "reset_spent": { + "message": "重置已支出", + "description": "Reset spent button" + }, + "allowance_limit_reached": { + "message": "此应用已达到其额度限制", + "description": "App allowance limit reached label" + }, + "unlock": { + "message": "解锁", + "description": "Unlock title" + }, + "unlock_wallet_to_use": { + "message": "您需要解锁钱包才能继续使用。", + "description": "Unlock wallet explanation" + }, + "reset_wallet_password_to_use": { + "message": "您需要重置密码才能安全使用 ArConnect。", + "description": "Reset wallet password explanation" + }, + "receive": { + "message": "接收", + "description": "Receive title" + }, + "share": { + "message": "分享", + "description": "Share button text" + }, + "send": { + "message": "发送", + "description": "Send title" + }, + "send_message_optional": { + "message": "消息(可选)", + "description": "Optional message field" + }, + "network_fee": { + "message": "网络费用", + "description": "Transaction network fee text" + }, + "estimated": { + "message": "预计", + "description": "estimated" + }, + "invalid_amount": { + "message": "金额必须大于 0", + "description": "Invalid tx amount message" + }, + "invalid_address": { + "message": "目标地址无效", + "description": "Invalid address message" + }, + "sent_tx": { + "message": "已发送交易", + "description": "Transaction sent successfully notification" + }, + "failed_tx": { + "message": "无法发送交易", + "description": "Transfer error notification" + }, + "assets": { + "message": "资产", + "description": "Assets title" + }, + "asset": { + "message": "资产", + "description": "Asset title" + }, + "view_all": { + "message": "查看全部", + "description": "View all link text" + }, + "setting_tokens": { + "message": "代币", + "description": "Tokens setting title" + }, + "setting_tokens_description": { + "message": "管理由去中心化应用程序或用户添加的代币", + "description": "Tokens setting description" + }, + "setting_contacts": { + "message": "联系人", + "description": "Contacts setting title" + }, + "setting_contacts_description": { + "message": "添加/编辑联系人", + "description": "Contacts setting description" + }, + "explore": { + "message": "探索", + "description": "Explore title" + }, + "explore_article_read_more": { + "message": "阅读更多", + "description": "Read more link text" + }, + "addToken": { + "message": "添加代币", + "description": "Add token title" + }, + "addTokenParagraph": { + "message": "$APP$ 想要向您的钱包添加一个代币。请查看以下详细信息。", + "description": "Add token explanation", + "placeholders": { + "app": { + "content": "$1", + "example": "ardrive.app" + } + } + }, + "recents": { + "message": "最近", + "description": "Recents for send modal" + }, + "all_set": { + "message": "一切就绪!", + "description": "All set title" + }, + "all_set_paragraph": { + "message": "ArConnect 已使用您的密码和钱包设置完成。您现在可以关闭窗口。", + "description": "Paragraph indicating setup" + }, + "token_add_failure": { + "message": "添加代币失败", + "description": "Failed to add token error message" + }, + "no_assets": { + "message": "未添加资产...", + "description": "No assets added note" + }, + "about_title": { + "message": "关于", + "description": "About title" + }, + "no_description": { + "message": "没有可用描述", + "description": "No token description note" + }, + "info_title": { + "message": "信息", + "description": "Token info section title" + }, + "no_price": { + "message": "没有价格数据...", + "description": "No price data available note" + }, + "collectibles": { + "message": "收藏品", + "description": "Collectibles title" + }, + "collectible": { + "message": "收藏品", + "description": "Collectible title" + }, + "no_collectibles": { + "message": "没有添加收藏品", + "description": "No collectibles added note" + }, + "custom_gateway_warning": { + "message": "此代币使用自定义网关。这可能会减慢评估速度。", + "description": "Warning about adding tokens with custom gateways" + }, + "custom_gateway_warning_simple": { + "message": "使用了自定义网关", + "description": "Custom gateway label for transaction details" + }, + "choose_theme": { + "message": "选择 UI 主题", + "description": "UI theme option title in setup" + }, + "light_theme": { + "message": "亮色", + "description": "Light theme" + }, + "dark_theme": { + "message": "暗色", + "description": "Dark theme" + }, + "system_theme": { + "message": "系统", + "description": "System theme" + }, + "migration_available": { + "message": "可用迁移", + "description": "Migration available title" + }, + "migration_available_paragraph": { + "message": "看来您之前已经使用过旧版本的 ArConnect。我们可以迁移您之前版本中的钱包供使用。您仍需完成设置过程。", + "description": "Migration available paragraph" + }, + "migrate": { + "message": "迁移", + "description": "Migrate button text" + }, + "migration_confirmation": { + "message": "完成设置后将迁移您的钱包", + "description": "Migration confirmation notification" + }, + "migrate_wallets_list": { + "message": "这些钱包将被迁移:", + "description": "Label for migrated wallets" + }, + "migrate_wallets_not_migrated": { + "message": "这些钱包不会被迁移:", + "description": "Label for wallets that won't be migrated" + }, + "migrate_anyway": { + "message": "还是迁移!", + "description": "Migrate anyway button text" + }, + "migration_available_welcome": { + "message": "您可以通过点击“我有一个钱包”来从旧的 ArConnect 迁移您的钱包。", + "description": "Migration available banner text" + }, + "click_and_drag": { + "message": "点击并拖动", + "description": "Hover text for drag icon" + }, + "token_type": { + "message": "代币类型", + "description": "Token type label" + }, + "token_type_asset": { + "message": "资产", + "description": "Asset token type" + }, + "token_type_collectible": { + "message": "收藏品", + "description": "Collectible token type (NFT, etc.)" + }, + "remove_token": { + "message": "移除代币", + "description": "Remove token button text" + }, + "your_balance": { + "message": "您的余额", + "description": "Balance label for tokens" + }, + "history": { + "message": "历史", + "description": "History title" + }, + "no_interaction_history": { + "message": "没有与此资产的历史记录", + "description": "No interaction history text for an asset" + }, + "titles_transaction": { + "message": "交易", + "description": "Transaction title" + }, + "transaction_id": { + "message": "交易 ID", + "description": "Transaction ID label" + }, + "transaction_from": { + "message": "从", + "description": "Transaction \"from\" label" + }, + "transaction_to": { + "message": "到", + "description": "Transaction \"to\" label" + }, + "transaction_fee": { + "message": "网络费用", + "description": "Transaction \"fee\" label" + }, + "transaction_size": { + "message": "大小", + "description": "Transaction \"size\" label" + }, + "transaction_confirmations": { + "message": "确认", + "description": "Transaction \"confirmations\" label" + }, + "transaction_block_height": { + "message": "区块", + "description": "Transaction \"block height\" label" + }, + "transaction_block_timestamp": { + "message": "时间戳", + "description": "Transaction \"timestamp\" label" + }, + "transaction_tags": { + "message": "标签", + "description": "Transaction \"tags\" label" + }, + "transaction_input": { + "message": "输入", + "description": "Contract interaction input label" + }, + "transaction_data": { + "message": "数据", + "description": "Transaction \"data\" label" + }, + "transaction_data_binary_warning": { + "message": "无法显示二进制交易数据...", + "description": "Warning about ArConnect not being able to display a transaction's data" + }, + "transaction_not_on_viewblock": { + "message": "在 Viewblock 上不可用", + "description": "Disabled viewblock link btn text" + }, + "transaction_view_last": { + "message": "点击查看您最近签署的交易", + "description": "View last tx prompt content" + }, + "sign_item": { + "message": "签署项目", + "description": "Sign message popup title" + }, + "titles_signature": { + "message": "签署消息", + "description": "Sign message popup title" + }, + "sign_data_description": { + "message": "$APPNAME$ 想要签署一笔交易。请查看以下详细信息。", + "description": "Description for signing an item containing a transfer", + "placeholders": { + "appname": { + "content": "$1", + "example": "permafacts.arweave.dev" + } + } + }, + "signature_description": { + "message": "$APPNAME$ 想要签署一条消息。请查看以下消息。", + "description": "App signature request for data that cannot be decoded to string", + "placeholders": { + "appname": { + "content": "$1", + "example": "permafacts.arweave.dev" + } + } + }, + "signature_message": { + "message": "消息", + "description": "Signature message label" + }, + "signature_authorize": { + "message": "签署", + "description": "Sign message authorize button" + }, + "titles_sign": { + "message": "签署交易", + "description": "Sign transaction popup title" + }, + "sign_authorize": { + "message": "授权", + "description": "Authorize button label" + }, + "sign_enter_password": { + "message": "输入密码以签署交易", + "description": "Request to enter password to sign transaction" + }, + "sign_scan_qr": { + "message": "使用您的硬件钱包扫描下面的二维码", + "description": "Request to scan signature QR" + }, + "viewblock": { + "message": "Viewblock", + "description": "view block" + }, + "keystone_connect_title": { + "message": "连接 Keystone", + "description": "Connect keystone hardware wallet button" + }, + + "keystone_scan": { + "message": "扫描响应", + "description": "Notification about a keystone scanning error" + }, + "keystone_scan_error": { + "message": "扫描二维码时出错", + "description": "Notification about a keystone scanning error" + }, + "keystone_invalid_result_type": { + "message": "检测到无效的二维码", + "description": "Notification about an invalid QR code while trying to scan a keystone wallet QR code" + }, + "keystone_scan_progress": { + "message": "进度:$PROGRESS$", + "description": "Progress label for QR code scanning", + "placeholders": { + "progress": { + "content": "$1", + "example": "10%" + } + } + }, + "keystone_loading_camera": { + "message": "加载扫描器...", + "description": "Loading hardware wallet QR scanner text" + }, + "keystone_disabled_camera": { + "message": "您的相机已禁用。启用它以扫描二维码!", + "description": "Request to enable the built-in camera" + }, + "keystone_allowed_camera": { + "message": "您已授予相机权限。请刷新页面!", + "description": "Request to refresh the page after granting camera permissions" + }, + "keystone_features_warning": { + "message": "Keystone 支持处于测试阶段。某些 API 功能可能不受支持。", + "description": "Warning about keystone support" + }, + "keystone_ao_description": { + "message": "Keystone 不支持发送 ao 代币。Keystone 只支持接收 ao 代币。发送支持即将到来。", + "description": "Description about keystone ao issue" + }, + "keystone_ao_title": { + "message": "检测到 Keystone 错误。", + "description": "Title about keystone ao issue" + }, + "keystone_ao_popup": { + "message": "Keystone 不支持发送 ao 代币。Keystone 只支持接收 ao 代币。发送支持即将到来。支持发送和接收 AR 代币。", + "description": "Popup description about keystone ao issue" + }, + "keystone_ao_popup_title": { + "message": "Keystone AO 代币支持通知", + "description": "Popup description about keystone ao issue" + }, + "token_price_estimate_warning": { + "message": "价格估算来自", + "description": "Price estimate warning text. Full text is displayed with a link to Redstone.finance" + }, + "wallet_hardware_added": { + "message": "已添加 $WALLETTYPE$ 钱包", + "description": "Notification on adding a hardware wallet", + "placeholders": { + "wallettype": { + "content": "$1", + "example": "Keystone" + } + } + }, + "wallet_hardware_not_added": { + "message": "无法添加 $WALLETTYPE$ 钱包", + "description": "Notification on error when adding a hardware wallet", + "placeholders": { + "wallettype": { + "content": "$1", + "example": "Keystone" + } + } + }, + "wallet_hardware_unsupported": { + "message": "此功能不支持硬件钱包", + "description": "Notification about a feature that does not support usage with a hardware wallet as an active/selected wallet" + }, + "notification_title_native_tx": { + "message": "交易已签署", + "description": "Notification title for signing a native tx" + }, + "notification_title_dispatched_tx": { + "message": "交易已发送", + "description": "Notification title for dispatching a tx" + }, + "notification_description_native_tx": { + "message": "总费用约为 $PRICE$ AR", + "description": "Notification body for native tx signing", + "placeholders": { + "price": { + "content": "$1", + "example": "10,234.15" + } + } + }, + "notification_description_dispatch_tx": { + "message": "已提交到 Bundlr 网络", + "description": "Notification body for dispatched tx" + }, + "transaction_send_add_target": { + "message": "添加接收者", + "description": "Add recipient title" + }, + "transaction_send_address_input_label": { + "message": "接收者", + "description": "Label for the address input" + }, + "transaction_send_address_input_placeholder": { + "message": "地址,ANS 或 ArNS...", + "description": "Placeholder for the address input" + }, + "transaction_send_scan_address": { + "message": "扫描地址", + "description": "Scan address tooltip content" + }, + "transaction_send_success": { + "message": "交易已发送", + "description": "Sent transaction successfully message" + }, + "transaction_send_error": { + "message": "无法发送交易", + "description": "Transaction failure" + }, + "transaction_auth_ur_fail": { + "message": "无法构建交易二维码", + "description": "Error notification about failed signing QR generation" + }, + "transaction_send_loading": { + "message": "发送交易中...", + "description": "Sending transaction loading text" + }, + "transaction_sending_token": { + "message": "发送中", + "description": "Sending token description in confirmation" + }, + "not_connected": { + "message": "未连接", + "description": "Not connected indicator" + }, + "not_connected_text": { + "message": "此应用尚未使用 ArConnect。找到页面上的“连接”按钮以连接。", + "description": "Not connected indicator explainer" + }, + "disconnect": { + "message": "断开连接", + "description": "Disconnect button text" + }, + "disconnected": { + "message": "已断开", + "description": "Disconnected tooltip" + }, + "account_connected": { + "message": "账户已连接", + "description": "Connected tooltip" + }, + "copy_address": { + "message": "复制地址", + "description": "Click to copy address tooltip" + }, + "expand_view": { + "message": "扩展视图", + "description": "Click to open extension in a browser tab" + }, + "allowance_edit": { + "message": "编辑额度", + "description": "Edit allowance tooltip" + }, + "balance_hide": { + "message": "隐藏余额", + "description": "Hide balance tooltip" + }, + "balance_show": { + "message": "显示余额", + "description": "Show balance tooltip" + }, + "lock_wallet": { + "message": "锁定钱包", + "description": "Lock wallet and terminate current session icon button" + }, + "home": { + "message": "首页", + "description": "Home Button" + }, + "home_no_balance": { + "message": "添加 $AR$ 以开始", + "description": "No balance message on homescreen", + "placeholders": { + "ar": { + "content": "$1", + "example": "$AR" + } + } + }, + "home_transfer_balance": { + "message": "转移 AR", + "description": "Transfer balance button text" + }, + "close_tab_generate_wallet_message": { + "message": "您确定要退出吗?您的新钱包正在生成中,将会丢失。", + "description": "Confirmation message for the user who tries to close a tab where a wallet is still being generated" + }, + "close_tab_load_wallet_message": { + "message": "您确定要退出吗?您的钱包正在加载中,关闭标签页将停止此过程。", + "description": "Confirmation message for the user who tries to close a tab where a wallet is still being loaded" + }, + "manage_assets_button": { + "message": "管理资产", + "description": "Manage assets button" + }, + "installation_complete": { + "message": "安装完成", + "description": "Installation complete title" + }, + "installation_complete_paragraph": { + "message": "将 ArConnect 固定到您的浏览器,使其易于访问并连接到您喜欢的 dApps。", + "description": "Installation complete paragraph" + }, + "enable_notifications_title": { + "message": "在 ArConnect 中启用通知", + "description": "Enable Notification title" + }, + "no_notifications": { + "message": "当前没有通知", + "description": "No notifications title" + }, + "no_notifications_get_started": { + "message": "发送交易以开始", + "description": "Send Transactions to get notifications" + }, + "introducing_notifications": { + "message": "介绍通知", + "description": "Alternative Enable Notification title" + }, + "enable_notifications_paragraph": { + "message": "保持更新,获取交易和 ao 消息的即时提醒。", + "description": "Enable notifications paragraph" + }, + "alternative_enable_notifications_paragraph": { + "message": "当交易处理时立即接收通知。", + "description": "Enable notifications paragraph" + }, + "get_started": { + "message": "开始", + "description": "Get started title" + }, + "get_started_description": { + "message": "通过 ArConnect 探索 Arweave 上的无限可能", + "description": "Get started description" + }, + "example_ardrive_description": { + "message": "ArDrive 提供永恒存储您的最有价值文件。只需一次付费,永远保存您的记忆。", + "description": "Placeholder for example get started" + }, + "example_ans_description": { + "message": "ans.gg 是一个基于 Arweave 区块链的流行名称服务。一次购买,永久拥有。", + "description": "Placeholder for example get started" + }, + "example_publish_description": { + "message": "一个旨在去中介化真相的证明中立出版平台。发布声明,并在事实市场中占据您的位置!", + "description": "Placeholder for example get started" + }, + "example_permaswap_description": { + "message": "Permaswap 是一个加密货币交易所,允许交换 Arweave 资产。", + "description": "Placeholder for example get started" + }, + "connect_with_us_title": { + "message": "与我们联系", + "description": "Connect with us title" + }, + "connect_paragraph": { + "message": "在 X 上关注我们,了解团队正在工作的最新动态。", + "description": "Connect with us description" + }, + "connect_paragraph_2": { + "message": "有问题吗?加入 Discord 服务器与开发人员聊天。", + "description": "Connect with us description" + }, + "buy_ar_button": { + "message": "购买 AR", + "description": "Buy AR with Onramper button text" + }, + "buy_screen_title": { + "message": "购买", + "description": "Buy AR with Onramper button text" + }, + "buy_screen_pay": { + "message": "您支付", + "description": "Payment input label title" + }, + "buy_screen_receive": { + "message": "您接收", + "description": "Receive input label title" + }, + "buy_screen_switch": { + "message": "切换", + "description": "Switch button" + }, + "buy_screen_payment_method": { + "message": "支付方式", + "description": "Select payment method title" + }, + "buy_screen_enter": { + "message": "输入金额", + "description": "Enter fiat amount placeholder" + }, + "buy_screen_receive_x": { + "message": "xxxx.xxxx", + "description": "Receive quantity placeholder" + }, + "AR_button": { + "message": "AR", + "description": "Receive quantity button text" + }, + "credit_debit": { + "message": "信用卡/借记卡", + "description": "Buy screen payment method text" + }, + "conversion_error": { + "message": "获取报价失败:无效的法定金额。", + "description": "Buy screen conversion error text" + }, + "confirm_purchase_title": { + "message": "将 AR 添加到您的钱包", + "description": "Confirm purchase header text" + }, + "wallet_address": { + "message": "钱包地址", + "description": "Confirm purchase wallet address header" + }, + "order_details": { + "message": "订单详情", + "description": "Confirm purchase order details title" + }, + "confirm_rate": { + "message": "汇率", + "description": "Confirm purchase rate text" + }, + "confirm_vendor_fee": { + "message": "供应商费用", + "description": "Confirm purchase vendor fee text" + }, + "confirm_total": { + "message": "总计", + "description": "Confirm purchase total cost text" + }, + "close_purchase_pending": { + "message": "关闭", + "description": "Close button text on purchase in progress page" + }, + "congrats_purchase_pending": { + "message": "恭喜!", + "description": "Congrats text on purchase in progress page" + }, + "info_purchase_pending": { + "message": "您的购买正在进行中。这可能需要 30-60 分钟完成。", + "description": "Info message text on purchase in progress page" + }, + "order_id_purchase_pending": { + "message": "报价 ID:", + "description": "Order ID text on purchase in progress page" + }, + "choose_payment_method": { + "message": "选择支付方式", + "description": "Payment method input modal title text" + }, + "choose_fiat_currency": { + "message": "选择法定货币", + "description": "Fiat currency input modal title text" + }, + "search_currency_placeholder": { + "message": "输入货币名称", + "description": "Currency search placeholder text" + }, + "receive_AR_button": { + "message": "接收 AR", + "description": "Button text for the receive AR button" + }, + "search_contacts": { + "message": "搜索联系人...", + "description": "Search input placeholder for contacts" + }, + "add_contact": { + "message": "添加联系人", + "description": "Add a contact button text" + }, + "send_transaction": { + "message": "发送交易", + "description": "Active contact send button text" + }, + "contact_info": { + "message": "联系信息", + "description": "Contact settings title" + }, + "user_not_in_contacts": { + "message": "此用户不在您的联系人中。", + "description": "Small message title on transaction confirmation page" + }, + "create_contact": { + "message": "创建联系人?", + "description": "Create contact question" + }, + "add_new_contact": { + "message": "添加新联系人", + "description": "Add a new contact title" + }, + "uploaded_avatar": { + "message": "已上传头像到 Arweave。", + "description": "Successful upload toast text" + }, + "ArNS_address": { + "message": "ArNS 地址", + "description": "Contact ArNS address subtitle" + }, + "select_ArNS_address": { + "message": "选择 ArNS 地址", + "description": "Select ArNS address text" + }, + "no_ArNS_address_found": { + "message": "未找到 ArNS 地址", + "description": "No ArNS address found text" + }, + "arweave_url": { + "message": "ar://", + "description": "Arweave address for ArNS names" + }, + "contact_avatar": { + "message": "头像", + "description": "Contact Avatar subtitle" + }, + "first_last_name": { + "message": "名字和姓氏", + "description": "Contact name input placeholder text" + }, + "arweave_account_address": { + "message": "Arweave 账户地址", + "description": "Contact arweave account address subtitle" + }, + "account_address": { + "message": "账户地址", + "description": "Contact account address input placeholder text" + }, + "notes": { + "message": "备注", + "description": "Contact notes subtitle" + }, + "type_message_here": { + "message": "在此输入消息...", + "description": "Contact notes input placeholder text" + }, + "save_changes": { + "message": "保存更改", + "description": "Save button text" + }, + "remove_contact": { + "message": "移除联系人", + "description": "Remove contact button text" + }, + "remove_contact_question": { + "message": "您确定要移除此联系人吗?", + "description": "Remove contact modal text" + }, + "save_new_contact": { + "message": "保存新联系人", + "description": "Save new contact button text" + }, + "address_in_use": { + "message": "地址已在使用中。", + "description": "Contacts error message if address is already in use" + }, + "password_allowance": { + "message": "需要密码额度", + "description": "Input title for the password allowance label" + }, + "add": { + "message": "添加", + "description": "Add button text" + }, + "your_contacts": { + "message": "您的联系人", + "description": "Your Contacts title in Send Modal" + }, + "check_address": { + "message": "请检查接收者地址", + "description": "Error message for invalid address/ArNS" + }, + "incorrect_address": { + "message": "接收者地址不正确", + "description": "Error message for invalid ANS" + }, + "arns_added": { + "message": "ar://$ADDRESS$ 已添加", + "description": "ArNS recipient added", + "placeholders": { + "address": { + "content": "$1", + "example": "Address" + } + } + }, + "ans_added": { + "message": "$ADDRESS$ 已添加", + "description": "ANS recipient added", + "placeholders": { + "address": { + "content": "$1", + "example": "Address" + } + } + }, + "setting_ao_support": { + "message": "ao 支持", + "description": "ao support settings title" + }, + "setting_ao_support_description": { + "message": "在您的钱包中显示 ao 代币(测试版)", + "description": "ao support settings description" + }, + "got_it": { + "message": "知道了", + "description": "Got it button text" + }, + "display_ao_tokens": { + "message": "在 ArConnect 中显示 AO 代币(测试版)", + "description": "Display AO tokens description" + }, + "ao_computer": { + "message": "ao.computer", + "description": "ao computer url" + }, + "ao_announcement_text": { + "message": "关注未来的 ao 更新。了解更多访问", + "description": "ao announcement description text" + }, + "ao_announcement_title": { + "message": "AO 测试网现已上线!", + "description": "ao announcement title text" + }, + "ao_token_announcement_title": { + "message": "恭喜获得 AO Token 4 年排放奖励 🥳", + "description": "ao token announcement title text" + }, + "ao_degraded": { + "message": "AO 代币处理网络降级。", + "description": "ao degraded title text" + }, + "ao_degraded_description": { + "message": "网络问题解决后,AO 代币处理将可用。", + "description": "ao degraded description text" + }, + "import_token": { + "message": "导入代币", + "description": "Import token button description" + }, + "token_already_added": { + "message": "代币已添加", + "description": "Token already imported" + }, + "token_already_removed": { + "message": "代币已移除", + "description": "Token already removed" + }, + "token_imported": { + "message": "代币成功添加", + "description": "Token added" + }, + "token_removed": { + "message": "代币成功移除", + "description": "Token removed" + }, + "transaction_complete": { + "message": "交易完成", + "description": "transaction complete header" + }, + "message": { + "message": "消息", + "description": "message header" + }, + "subscription_allowance": { + "message": "订阅额度", + "description": "Subscription settings title" + }, + "subscription_title": { + "message": "订阅", + "description": "Subscription title" + }, + "subscriptions": { + "message": "订阅", + "description": "Subscriptions title" + }, + "no_subscriptions": { + "message": "尚未订阅", + "description": "No subscriptions title" + }, + "no_subscriptions_description": { + "message": "您的未来订阅将显示在这里", + "description": "No subscriptions description" + }, + "subscribe_description": { + "message": "$APPNAME 请求设置一个定期付款的订阅", + "description": "Subscribe description" + }, + "subscription_description": { + "message": "管理自动提现额度", + "description": "Subscription setting description" + }, + "subscription_cancelled": { + "message": "订阅已取消", + "description": "The subscription has been successfully cancelled." + }, + "subscription_cancelled_error": { + "message": "订阅取消错误", + "description": "There was an error cancelling the subscription. Please try again." + }, + "subscription_deleted": { + "message": "订阅已删除", + "description": "The subscription has been successfully deleted." + }, + "subscription_delete_error": { + "message": "订阅删除错误", + "description": "There was an error deleting the subscription. Please try again." + }, + "subscription_add_failure": { + "message": "添加订阅失败", + "description": "Failed to add subscription error message" + }, + "transaction_history_title": { + "message": "交易历史", + "description": "Transaction History header" + }, + "subscription_application_address": { + "message": "应用地址", + "description": "付款地址" + }, + + "subscription_recurring_amount": { + "message": "定期付款金额", + "description": "Recurring payment amount" + }, + "auto_renewal": { + "message": "自动续订", + "description": "auto-renewal" + }, + "auto_pay": { + "message": "自动付款", + "description": "auto-pay" + }, + "confirm_subscription": { + "message": "确认订阅", + "description": "confirm subscription" + }, + "end": { + "message": "结束", + "description": "end" + }, + "next_payment": { + "message": "下一次付款", + "description": "next payment" + }, + "start": { + "message": "开始", + "description": "start" + }, + "Quarterly": { + "message": "季度", + "description": "quarterly frequency" + }, + "Monthly": { + "message": "每月", + "description": "monthly frequency" + }, + "Weekly": { + "message": "每周", + "description": "weekly frequency" + }, + "Daily": { + "message": "每天", + "description": "daily frequency" + }, + "transactions": { + "message": "交易", + "descriptions": "Transactions title" + }, + "no_transactions": { + "message": "未找到交易", + "description": "No transactions message" + }, + "sent": { + "message": "已发送", + "description": "sent" + }, + "received": { + "message": "已收到", + "description": "received" + } +} diff --git a/package.json b/package.json index e24d9df40..021956952 100644 --- a/package.json +++ b/package.json @@ -68,7 +68,7 @@ "check-password-strength": "^2.0.7", "copy-to-clipboard": "^3.3.2", "dayjs": "^1.11.6", - "framer-motion": "^7.5.3", + "framer-motion": "7.5.3", "human-crypto-keys": "^0.1.4", "js-confetti": "^0.11.0", "mitt": "^3.0.0", diff --git a/src/components/popup/Navigation.tsx b/src/components/popup/Navigation.tsx index f902ac96d..85b86c3df 100644 --- a/src/components/popup/Navigation.tsx +++ b/src/components/popup/Navigation.tsx @@ -6,6 +6,7 @@ import { Home01, Home02 } from "@untitled-ui/icons-react"; +import browser from "webextension-polyfill"; import styled from "styled-components"; import { useLocation } from "wouter"; import { useHistory } from "~utils/hash_router"; @@ -69,7 +70,7 @@ export const NavigationBar = () => { {button.icon} -
{button.title}
+
{browser.i18n.getMessage(button.title)}
); })} diff --git a/src/components/popup/Token.tsx b/src/components/popup/Token.tsx index 6f1809b4e..38fd854e2 100644 --- a/src/components/popup/Token.tsx +++ b/src/components/popup/Token.tsx @@ -3,7 +3,13 @@ import { formatTokenBalance, balanceToFractioned } from "~tokens/currency"; -import { type MouseEventHandler, useEffect, useMemo, useState } from "react"; +import { + type MouseEventHandler, + useEffect, + useMemo, + useRef, + useState +} from "react"; import { hoverEffect, useTheme } from "~utils/theme"; import { loadTokenLogo, type Token } from "~tokens/token"; import { useStorage } from "@plasmohq/storage/hook"; @@ -24,13 +30,33 @@ import { getUserAvatar } from "~lib/avatar"; import { abbreviateNumber } from "~utils/format"; import Skeleton from "~components/Skeleton"; import { TrashIcon, PlusIcon, SettingsIcon } from "@iconicicons/react"; +import JSConfetti from "js-confetti"; export default function Token({ onClick, ...props }: Props) { + const ref = useRef(null); const [totalBalance, setTotalBalance] = useState(""); const [showTooltip, setShowTooltip] = useState(false); // display theme const theme = useTheme(); + const [aoNativeToken] = useStorage( + { + key: "ao_native_token", + instance: ExtensionStorage + }, + "" + ); + + const [activeAddress] = useStorage({ + key: "active_address", + instance: ExtensionStorage + }); + + const [aoConfettiShown, setAoConfettiShown] = useStorage({ + key: `ao_confetti_shown_${activeAddress}`, + instance: ExtensionStorage + }); + const arweaveLogo = useMemo( () => (theme === "dark" ? arLogoDark : arLogoLight), [theme] @@ -87,6 +113,12 @@ export default function Token({ onClick, ...props }: Props) { const hasActionButton = props?.onAddClick || props?.onRemoveClick || props?.onSettingsClick; + const triggerConfetti = async () => { + const jsConfetti = new JSConfetti({ canvas: ref.current }); + jsConfetti.addConfetti(); + setAoConfettiShown(true); + }; + useEffect(() => { (async () => { if (!props?.id || logo) return; @@ -110,8 +142,31 @@ export default function Token({ onClick, ...props }: Props) { } }, [arweaveLogo]); + useEffect(() => { + if ( + ref.current && + activeAddress && + !props.loading && + aoNativeToken === props.id && + !aoConfettiShown && + +props.balance > 0 + ) { + triggerConfetti(); + } + }, [ + ref.current, + aoConfettiShown, + activeAddress, + aoNativeToken, + props.balance, + props.loading + ]); + return ( + {(!aoConfettiShown || ref.current) && + aoNativeToken === props.id && + +props.balance > 0 && } @@ -313,6 +368,14 @@ const BalanceSection = styled.div` } `; +const Canvas = styled.canvas` + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; +`; + interface Props extends Token { ao?: boolean; loading?: boolean; diff --git a/src/components/popup/WalletHeader.tsx b/src/components/popup/WalletHeader.tsx index c806d0fce..a41bccffd 100644 --- a/src/components/popup/WalletHeader.tsx +++ b/src/components/popup/WalletHeader.tsx @@ -21,6 +21,7 @@ import { TooltipV2 } from "@arconnect/components"; import { + ArrowUpRightIcon, CheckIcon, ChevronDownIcon, CopyIcon, @@ -251,7 +252,10 @@ export default function WalletHeader() { - + { @@ -274,7 +278,9 @@ export default function WalletHeader() { }} > , - title: "Contacts", + title: "setting_contacts", route: () => browser.tabs.create({ url: browser.runtime.getURL("tabs/dashboard.html#/contacts") @@ -432,7 +438,7 @@ export default function WalletHeader() { }, { icon: , - title: "Expand view", + title: "expand_view", route: () => { window.open( window.location.href.split("#")[0] + "?expanded=true" @@ -441,10 +447,19 @@ export default function WalletHeader() { }, { icon: , - title: "Subscriptions", + title: "subscriptions", route: () => { push("/subscriptions"); } + }, + { + icon: ( + + ), + title: "transactions", + route: () => { + push("/transactions"); + } } ]} /> diff --git a/src/components/popup/WalletMenu.tsx b/src/components/popup/WalletMenu.tsx index 8afa43d84..63f2a2963 100644 --- a/src/components/popup/WalletMenu.tsx +++ b/src/components/popup/WalletMenu.tsx @@ -1,4 +1,5 @@ import { motion, AnimatePresence, type Variants } from "framer-motion"; +import browser from "webextension-polyfill"; import styled from "styled-components"; export default function WalletMenu({ open, close, menuItems }: Props) { @@ -22,7 +23,7 @@ export default function WalletMenu({ open, close, menuItems }: Props) { }} > {item.icon} - {item.title} + {browser.i18n.getMessage(item.title)} ))} diff --git a/src/components/popup/home/AoBanner.tsx b/src/components/popup/home/AoBanner.tsx new file mode 100644 index 000000000..5b10525ef --- /dev/null +++ b/src/components/popup/home/AoBanner.tsx @@ -0,0 +1,97 @@ +import type { DisplayTheme } from "@arconnect/components"; +import { useStorage } from "@plasmohq/storage/hook"; +import { Quantity } from "ao-tokens"; +import type { TokenInfo } from "ao-tokens/dist/utils"; +import { useEffect, useMemo, useState } from "react"; +import styled, { useTheme } from "styled-components"; +import browser from "webextension-polyfill"; +import { getTagValue, useAo, type Message } from "~tokens/aoTokens/ao"; +import { ExtensionStorage } from "~utils/storage"; + +interface AoBannerProps { + activeAddress: string; +} + +export default function AoBanner({ activeAddress }: AoBannerProps) { + const ao = useAo(); + const theme = useTheme(); + const [showBanner, setShowBanner] = useState(false); + + const [aoNativeToken] = useStorage({ + key: "ao_native_token", + instance: ExtensionStorage + }); + + const [aoTokens] = useStorage( + { + key: "ao_tokens", + instance: ExtensionStorage + }, + [] + ); + + const aoToken = useMemo(() => { + if (!aoNativeToken || aoTokens.length === 0) return undefined; + return aoTokens.find((token) => token.processId === aoNativeToken); + }, [aoTokens, aoNativeToken]); + + async function getAoNativeTokenBalance() { + const res = await ao.dryrun({ + Id: "0000000000000000000000000000000000000000001", + Owner: activeAddress, + process: aoNativeToken, + tags: [{ name: "Action", value: "Balance" }] + }); + + // find result message + for (const msg of res.Messages as Message[]) { + const balance = getTagValue("Balance", msg.Tags); + + // return balance if found + if (balance) { + return new Quantity(BigInt(balance), BigInt(aoToken.Denomination)); + } + } + + // default return + return new Quantity(0, BigInt(aoToken.Denomination)); + } + + async function fetchAoNativeTokenBalance() { + const balance = await getAoNativeTokenBalance(); + setShowBanner(balance.toNumber() > 0); + } + + useEffect(() => { + if (activeAddress && aoNativeToken && aoToken && ao) { + fetchAoNativeTokenBalance().catch(() => {}); + } + }, [activeAddress, aoNativeToken, aoToken, ao]); + + if (!activeAddress || !aoNativeToken || !aoToken || !showBanner) { + return null; + } + + return ( + +

{browser.i18n.getMessage("ao_token_announcement_title")}

+
+ ); +} + +const Banner = styled.div<{ displayTheme: DisplayTheme }>` + display: flex; + padding: 0.75rem; + background: ${(props) => + props.displayTheme === "light" ? "#ffffff" : "#191919"}; + border-bottom: 2px solid #8e7bea; + justify-content: center; + + h4 { + font-weight: 500; + font-size: 0.8rem !important; + margin: 0; + padding: 0; + font-size: inherit; + } +`; diff --git a/src/components/popup/home/Tokens.tsx b/src/components/popup/home/Tokens.tsx index b619c760f..fa4644bab 100644 --- a/src/components/popup/home/Tokens.tsx +++ b/src/components/popup/home/Tokens.tsx @@ -43,13 +43,6 @@ export default function Tokens() { {browser.i18n.getMessage("no_assets")} )} - {assets.slice(0, 8).map((token, i) => ( - push(`/token/${token.id}`)} - key={i} - /> - ))} {aoTokens.map((token) => ( handleTokenClick(token.id)} /> ))} + {assets.slice(0, 8).map((token, i) => ( + push(`/token/${token.id}`)} + key={i} + /> + ))} ); diff --git a/src/notifications/api.ts b/src/notifications/api.ts index 04d39cead..d8b711437 100644 --- a/src/notifications/api.ts +++ b/src/notifications/api.ts @@ -15,7 +15,7 @@ import { processTransactions } from "./utils"; -export type Transaction = { +export type RawTransaction = { node: { id: string; recipient: string; @@ -34,6 +34,9 @@ export type Transaction = { value: string; }>; }; +}; + +export type Transaction = RawTransaction & { transactionType: string; quantity: string; isAo?: boolean; diff --git a/src/notifications/utils.ts b/src/notifications/utils.ts index cb5e8205a..1f6f8ffed 100644 --- a/src/notifications/utils.ts +++ b/src/notifications/utils.ts @@ -5,6 +5,7 @@ query ($address: String!) { transactions(first: 10, recipients: [$address], tags: [{ name: "Type", values: ["Transfer"] }]) { edges { + cursor node { id recipient @@ -24,6 +25,7 @@ query ($address: String!) { export const AR_SENT_QUERY = `query ($address: String!) { transactions(first: 10, owners: [$address], tags: [{ name: "Type", values: ["Transfer"] }]) { edges { + cursor node { id recipient @@ -52,6 +54,7 @@ query($address: String!) { ] ) { edges { + cursor node { recipient id @@ -78,6 +81,7 @@ query($address: String!) { ] ) { edges { + cursor node { id recipient @@ -130,6 +134,104 @@ export const ALL_AR_SENT_QUERY = `query ($address: String!) { } }`; +export const AR_RECEIVER_QUERY_WITH_CURSOR = ` +query ($address: String!, $after: String) { + transactions(first: 10, recipients: [$address], tags: [{ name: "Type", values: ["Transfer"] }], after: $after) { + edges { + cursor + node { + id + recipient + owner { address } + quantity { ar } + block { timestamp, height } + tags { + name + value + } + } + } + } +} +`; + +export const AR_SENT_QUERY_WITH_CURSOR = ` +query ($address: String!, $after: String) { + transactions(first: 10, owners: [$address], tags: [{ name: "Type", values: ["Transfer"] }], after: $after) { + edges { + cursor + node { + id + recipient + owner { address } + quantity { ar } + block { timestamp, height } + tags { + name + value + } + } + } + } +} +`; + +export const AO_RECEIVER_QUERY_WITH_CURSOR = ` +query($address: String!, $after: String) { + transactions( + first: 10, + tags: [ + {name: "Data-Protocol", values: ["ao"]}, + {name: "Action", values: ["Transfer"]}, + {name: "Recipient", values: [$address]} + ], + after: $after + ) { + edges { + cursor + node { + recipient + id + owner { address } + block { timestamp, height } + tags { + name + value + } + } + } + } +} +`; + +export const AO_SENT_QUERY_WITH_CURSOR = ` +query($address: String!, $after: String) { + transactions( + first: 10, + owners: [$address], + tags: [ + {name: "Data-Protocol", values: ["ao"]}, + {name: "Action", values: ["Transfer"]} + ], + after: $after + ) { + edges { + cursor + node { + id + recipient + owner { address } + block { timestamp, height } + tags { + name + value + } + } + } + } +} +`; + export const combineAndSortTransactions = (responses: any[]) => { const combinedTransactions = responses.reduce((acc, response) => { const transactions = response.data.transactions.edges; diff --git a/src/popup.tsx b/src/popup.tsx index ecb2bc3e1..e2b3d89d1 100644 --- a/src/popup.tsx +++ b/src/popup.tsx @@ -33,6 +33,8 @@ import MessageNotification from "~routes/popup/notification/[id]"; import SubscriptionDetails from "~routes/popup/subscriptions/subscriptionDetails"; import SubscriptionPayment from "~routes/popup/subscriptions/subscriptionPayment"; import SubscriptionManagement from "~routes/popup/subscriptions/subscriptionManagement"; +import Transactions from "~routes/popup/transaction/transactions"; +import { importAoNativeToken } from "~utils/ao_import"; export default function Popup() { const theme = useTheme(); @@ -45,6 +47,9 @@ export default function Popup() { // sync ans labels syncLabels(); + // import ao native token + importAoNativeToken(); + // check expanded view if (new URLSearchParams(window.location.search).get("expanded")) { setExpanded(true); @@ -95,6 +100,7 @@ export default function Popup() { )} + {(params: { id: string }) => ( diff --git a/src/routes/auth/subscription.tsx b/src/routes/auth/subscription.tsx index 63f04ad1b..43331f586 100644 --- a/src/routes/auth/subscription.tsx +++ b/src/routes/auth/subscription.tsx @@ -134,7 +134,7 @@ export default function Subscription() { return ( <> - + {params && (
@@ -157,7 +157,7 @@ export default function Subscription() { - Application address:{" "} + {browser.i18n.getMessage("subscription_application_address")}:{" "} {formatAddress(params.arweaveAccountAddress, 8)} @@ -168,7 +168,8 @@ export default function Subscription() { fontSize="14px" color={theme === "light" ? "#191919" : "#ffffff"} > - Subscription: {params.recurringPaymentFrequency} + {browser.i18n.getMessage("subscriptions")}:{" "} + {browser.i18n.getMessage(params.recurringPaymentFrequency)} @@ -179,7 +180,7 @@ export default function Subscription() { fontSize="14px" color={theme === "light" ? "#191919" : "#ffffff"} > - Next payment:{" "} + {browser.i18n.getMessage("next_payment")}:{" "} {dayjs(params.nextPaymentDue).format("MMM DD, YYYY")} @@ -191,13 +192,13 @@ export default function Subscription() { fontSize="14px" color={theme === "light" ? "#191919" : "#ffffff"} > - Start + {browser.i18n.getMessage("start")} - End + {browser.i18n.getMessage("end")} @@ -214,7 +215,7 @@ export default function Subscription() { - Auto-renewal + {browser.i18n.getMessage("auto_renewal")} @@ -222,7 +223,7 @@ export default function Subscription() { - Auto-Pay + {browser.i18n.getMessage("auto_pay")} @@ -254,14 +255,14 @@ export default function Subscription() { }} > - Confirm Subscription + {browser.i18n.getMessage("confirm_subscription")} - Cancel + {browser.i18n.getMessage("cancel")} diff --git a/src/routes/dashboard/index.tsx b/src/routes/dashboard/index.tsx index 5c6e9f0f2..db7444bcf 100644 --- a/src/routes/dashboard/index.tsx +++ b/src/routes/dashboard/index.tsx @@ -110,9 +110,11 @@ export default function Settings({ params }: Props) { > - {formatSettingName( - allSettings.find((s) => s.name === activeSetting)?.name - ) || ""} + {allSettings && + browser.i18n.getMessage( + allSettings.find((s) => s.name === activeSetting)?.displayName || + "" + )} {activeSetting && @@ -247,6 +249,7 @@ const MidSettingsTitle = styled(Text).attrs({ })` padding: 0 ${setting_element_padding}; font-weight: 600; + text-transform: capitalize; `; interface Setting extends SettingItemData { diff --git a/src/routes/popup/index.tsx b/src/routes/popup/index.tsx index 5b19178cd..fdd063edf 100644 --- a/src/routes/popup/index.tsx +++ b/src/routes/popup/index.tsx @@ -15,6 +15,7 @@ import { useTokens } from "~tokens"; import { useAoTokens } from "~tokens/aoTokens/ao"; import { useActiveWallet, useBalance } from "~wallets/hooks"; import BuyButton from "~components/popup/home/BuyButton"; +import AoBanner from "~components/popup/home/AoBanner"; export default function Home() { // get if the user has no balance @@ -115,6 +116,7 @@ export default function Home() { return ( + {loggedIn && } diff --git a/src/routes/popup/notifications.tsx b/src/routes/popup/notifications.tsx index e469399a9..2c707e387 100644 --- a/src/routes/popup/notifications.tsx +++ b/src/routes/popup/notifications.tsx @@ -189,8 +189,12 @@ export default function Notifications() { )} {empty && ( - No notifications at this time. - Send transactions to get started. + + {browser.i18n.getMessage("no_notifications")} + + + {browser.i18n.getMessage("no_notifications_get_started")} + )} {subscriptions.map((subscription) => ( @@ -240,7 +244,7 @@ export default function Notifications() { ); } -const Empty = styled.div` +export const Empty = styled.div` width: calc(100% - 30px); height: calc(100% - 64.59px); margin-top: 50%; @@ -272,7 +276,7 @@ const Link = styled.a` cursor: pointer; `; -const TitleMessage = styled.div` +export const TitleMessage = styled.div` color: ${(props) => props.theme.primaryTextv2}; font-size: 14px; `; diff --git a/src/routes/popup/send/confirm.tsx b/src/routes/popup/send/confirm.tsx index 47a058cce..99f66a409 100644 --- a/src/routes/popup/send/confirm.tsx +++ b/src/routes/popup/send/confirm.tsx @@ -630,7 +630,9 @@ export default function Confirm({ tokenID, qty, subscription }: Props) { return ( @@ -661,21 +663,22 @@ export default function Confirm({ tokenID, qty, subscription }: Props) { {token && !hardwareStatus && ( <> { @@ -754,7 +757,9 @@ export default function Confirm({ tokenID, qty, subscription }: Props) { } }} > - {(hardwareStatus === "play" && "Scan response") || "Confirm"} + {(hardwareStatus === "play" && + browser.i18n.getMessage("keystone_scan")) || + browser.i18n.getMessage("confirm")} {" >"} @@ -890,6 +895,9 @@ const Price = styled.div` const ArAmount = styled.div<{ alternate?: boolean }>` display: inline-flex; + flex-wrap: wrap; + margin-left: auto; + justify-content: flex-end; align-items: baseline; font-size: ${(props) => (props.alternate ? "16px" : "32px")}; font-weight: 600; diff --git a/src/routes/popup/send/index.tsx b/src/routes/popup/send/index.tsx index 74eea6c8a..ec9a7d63a 100644 --- a/src/routes/popup/send/index.tsx +++ b/src/routes/popup/send/index.tsx @@ -579,15 +579,6 @@ export default function Send({ id }: Props) { > updateSelectedToken("AR")} /> - {tokens - .filter((token) => token.type === "asset") - .map((token, i) => ( - updateSelectedToken(token.id)} - key={i} - /> - ))} {aoTokens.map((token, i) => ( updateSelectedToken(token.id)} /> ))} + {tokens + .filter((token) => token.type === "asset") + .map((token, i) => ( + updateSelectedToken(token.id)} + key={i} + /> + ))} {tokens @@ -617,6 +617,7 @@ export default function Send({ id }: Props) { /> ))} + )} {showSlider && ( diff --git a/src/routes/popup/subscriptions/subscriptionDetails.tsx b/src/routes/popup/subscriptions/subscriptionDetails.tsx index 9b88da365..efe97820b 100644 --- a/src/routes/popup/subscriptions/subscriptionDetails.tsx +++ b/src/routes/popup/subscriptions/subscriptionDetails.tsx @@ -213,7 +213,7 @@ export default function SubscriptionDetails({ id }: Props) { displayTheme={theme} color={theme === "light" ? "#191919" : "#ffffff"} > - Application address:{" "} + {browser.i18n.getMessage("subscription_application_address")}:{" "} {formatAddress(subData.arweaveAccountAddress, 5)} diff --git a/src/routes/popup/subscriptions/subscriptions.tsx b/src/routes/popup/subscriptions/subscriptions.tsx index be912e59a..2ec1c447c 100644 --- a/src/routes/popup/subscriptions/subscriptions.tsx +++ b/src/routes/popup/subscriptions/subscriptions.tsx @@ -7,6 +7,7 @@ import { useEffect, useState } from "react"; import { getActiveAddress } from "~wallets"; import styled from "styled-components"; import Squircle from "~components/Squircle"; +import browser from "webextension-polyfill"; import { getSubscriptionData, updateSubscription } from "~subscriptions"; import dayjs from "dayjs"; import { useHistory } from "~utils/hash_router"; @@ -73,7 +74,7 @@ export default function Subscriptions() { return (
- + {subData && subData.length > 0 ? ( {subData.map((sub) => { @@ -92,8 +93,8 @@ export default function Subscriptions() { ) : ( -
No subscriptions yet
- Your future subscriptions will be available here +
{browser.i18n.getMessage("no_subscriptions")}
+ {browser.i18n.getMessage("no_subscriptions_description")}
)}
diff --git a/src/routes/popup/tokens.tsx b/src/routes/popup/tokens.tsx index db07fc7ce..dfe4d4dad 100644 --- a/src/routes/popup/tokens.tsx +++ b/src/routes/popup/tokens.tsx @@ -132,19 +132,6 @@ export default function Tokens() { <> - {assets.map((token, i) => ( - push(`/token/${token.id}`)} - onSettingsClick={(e) => { - e.preventDefault(); - window.open( - `${browser.runtime.getURL("tabs/dashboard.html")}#/tokens` - ); - }} - key={i} - /> - ))} {aoTokens.map((token) => ( ))} + {assets.map((token, i) => ( + push(`/token/${token.id}`)} + onSettingsClick={(e) => { + e.preventDefault(); + window.open( + `${browser.runtime.getURL("tabs/dashboard.html")}#/tokens` + ); + }} + key={i} + /> + ))} {aoTokensCache.map((token) => ( ({ isAo: false }); + const [ticker, setTicker] = useState(null); + const [showTags, setShowTags] = useState(false); // arweave gateway @@ -124,8 +132,10 @@ export default function Transaction({ id: rawId, gw, message }: Props) { } else { timeoutID = undefined; - const sdkTag = data.transaction.tags.find((tag) => tag.name === "SDK"); - if (sdkTag && sdkTag.value === "aoconnect") { + const dataProtocolTag = data.transaction.tags.find( + (tag) => tag.name === "Data-Protocol" + ); + if (dataProtocolTag && dataProtocolTag.value === "ao") { setAo({ isAo: true, tokenId: data.transaction.recipient }); const aoRecipient = data.transaction.tags.find( (tag) => tag.name === "Recipient" @@ -133,8 +143,17 @@ export default function Transaction({ id: rawId, gw, message }: Props) { const aoQuantity = data.transaction.tags.find( (tag) => tag.name === "Quantity" ); - data.transaction.quantity = { ar: aoQuantity.value, winston: "" }; - data.transaction.recipient = aoRecipient.value; + + if (aoQuantity) { + const tokenInfo = (await Token(data.transaction.recipient)).info; + const amount = balanceToFractioned(Number(aoQuantity.value), { + id: data.transaction.recipient, + decimals: Number(tokenInfo.Denomination) + }); + setTicker(tokenInfo.Ticker); + data.transaction.quantity = { ar: amount.toString(), winston: "" }; + data.transaction.recipient = aoRecipient.value; + } } setTransaction(data.transaction); @@ -265,9 +284,11 @@ export default function Transaction({ id: rawId, gw, message }: Props) {
{ - if (backPath === "/notifications") { + if (backPath === "/notifications" || backPath === "/transactions") { back(); } else { push("/"); @@ -282,9 +303,9 @@ export default function Transaction({ id: rawId, gw, message }: Props) { {!ao.isAo ? formatTokenBalance(Number(transaction.quantity.ar)) - : 0} + : transaction.quantity.ar} {/* NEEDS TO BE DYNAMIC */} - {!ao.isAo && AR} + {ticker ? ticker : "AR"} {ao.isAo ? "$-.--" : formatFiatBalance(fiatPrice, currency)} @@ -527,13 +548,13 @@ export default function Transaction({ id: rawId, gw, message }: Props) { fullWidth onClick={() => { const url = ao.isAo - ? `https://ao_marton.g8way.io/#/process/${ao.tokenId}/${id}` + ? `https://www.ao.link/message/${id}` : `https://viewblock.io/arweave/tx/${id}`; browser.tabs.create({ url }); }} > - {ao.isAo ? "ao Scanner" : "Viewblock"} + {ao.isAo ? "AOLink" : "Viewblock"} diff --git a/src/routes/popup/transaction/transactions.tsx b/src/routes/popup/transaction/transactions.tsx new file mode 100644 index 000000000..576121bb5 --- /dev/null +++ b/src/routes/popup/transaction/transactions.tsx @@ -0,0 +1,374 @@ +import HeadV2 from "~components/popup/HeadV2"; +import browser from "webextension-polyfill"; +import { useEffect, useState } from "react"; +import { ExtensionStorage } from "~utils/storage"; +import { useStorage } from "@plasmohq/storage/hook"; + +import { gql } from "~gateways/api"; +import type { RawTransaction } from "~notifications/api"; +import styled from "styled-components"; +import { Empty, TitleMessage } from "../notifications"; +import { fetchTokenByProcessId } from "~utils/notifications"; +import { formatAddress } from "~utils/format"; +import { balanceToFractioned, formatFiatBalance } from "~tokens/currency"; +import { + AO_RECEIVER_QUERY, + AO_SENT_QUERY, + AR_RECEIVER_QUERY, + AR_SENT_QUERY +} from "~notifications/utils"; +import { useHistory } from "~utils/hash_router"; +import { getArPrice } from "~lib/coingecko"; +import useSetting from "~settings/hook"; +import { suggestedGateways } from "~gateways/gateway"; + +type ExtendedTransaction = RawTransaction & { + month: number; + year: number; + transactionType: string; + date: string | null; + day: number; + aoInfo?: { + tickerName: string; + denomination?: number; + quantity: number; + }; +}; + +type GroupedTransactions = { + [key: string]: ExtendedTransaction[]; +}; + +export default function Transactions() { + const [transactions, setTransaction] = useState({}); + const [arPrice, setArPrice] = useState(0); + const [push] = useHistory(); + const [loading, setLoading] = useState(false); + const [currency] = useSetting("currency"); + const [activeAddress] = useStorage({ + key: "active_address", + instance: ExtensionStorage + }); + + useEffect(() => { + getArPrice(currency) + .then((res) => setArPrice(res)) + .catch(); + }, [currency]); + + useEffect(() => { + const getNotifications = async () => { + setLoading(true); + try { + if (activeAddress) { + const [rawReceived, rawSent, rawAoSent, rawAoReceived] = + await Promise.all([ + gql( + AR_RECEIVER_QUERY, + { address: activeAddress }, + suggestedGateways[1] + ), + gql( + AR_SENT_QUERY, + { address: activeAddress }, + suggestedGateways[1] + ), + gql( + AO_SENT_QUERY, + { address: activeAddress }, + suggestedGateways[1] + ), + gql( + AO_RECEIVER_QUERY, + { address: activeAddress }, + suggestedGateways[1] + ) + ]); + + const sent: ExtendedTransaction[] = + rawSent.data.transactions.edges.map((transaction) => ({ + ...transaction, + transactionType: "sent", + day: 0, + month: 0, + year: 0, + date: "" + })); + + const received: ExtendedTransaction[] = + rawReceived.data.transactions.edges.map((transaction) => ({ + ...transaction, + transactionType: "received", + day: 0, + month: 0, + year: 0, + date: "" + })); + + const aoSent: ExtendedTransaction[] = await Promise.all( + rawAoSent.data.transactions.edges.map(async (transaction) => { + const tokenData = await fetchTokenByProcessId( + transaction.node.recipient + ); + const quantityTag = transaction.node.tags.find( + (tag) => tag.name === "Quantity" + ); + return { + ...transaction, + transactionType: "aoSent", + day: 0, + month: 0, + year: 0, + date: "", + aoInfo: { + quantity: quantityTag ? Number(quantityTag.value) : undefined, + tickerName: + tokenData?.Ticker || + formatAddress(transaction.node.recipient, 4), + denomination: tokenData?.Denomination || 0 + } + }; + }) + ); + + const aoReceived: ExtendedTransaction[] = await Promise.all( + rawAoReceived.data.transactions.edges.map(async (transaction) => { + const tokenData = await fetchTokenByProcessId( + transaction.node.recipient + ); + const quantityTag = transaction.node.tags.find( + (tag) => tag.name === "Quantity" + ); + return { + ...transaction, + transactionType: "aoReceived", + day: 0, + month: 0, + year: 0, + date: "", + aoInfo: { + quantity: quantityTag ? Number(quantityTag.value) : undefined, + tickerName: + tokenData?.Ticker || + formatAddress(transaction.node.recipient, 4), + denomination: tokenData?.Denomination || 1 + } + }; + }) + ); + + let combinedTransactions: ExtendedTransaction[] = [ + ...sent, + ...received, + ...aoReceived, + ...aoSent + ]; + combinedTransactions.sort((a, b) => { + const timestampA = + a.node?.block?.timestamp || Number.MAX_SAFE_INTEGER; + const timestampB = + b.node?.block?.timestamp || Number.MAX_SAFE_INTEGER; + return timestampB - timestampA; + }); + + combinedTransactions = combinedTransactions.map((transaction) => { + if (transaction.node.block && transaction.node.block.timestamp) { + const date = new Date(transaction.node.block.timestamp * 1000); + const day = date.getDate(); + const month = date.getMonth() + 1; + const year = date.getFullYear(); + return { + ...transaction, + day, + month, + year, + date: date.toISOString() + }; + } else { + const now = new Date(); + return { + ...transaction, + day: now.getDate(), + month: now.getMonth() + 1, + year: now.getFullYear(), + date: null + }; + } + }); + + const groupedTransactions = combinedTransactions.reduce( + (acc, transaction) => { + const monthYear = `${transaction.month}-${transaction.year}`; + if (!acc[monthYear]) { + acc[monthYear] = []; + } + acc[monthYear].push(transaction); + return acc; + }, + {} as { [key: string]: ExtendedTransaction[] } + ); + setTransaction(groupedTransactions); + } + } catch (error) { + console.error("Error fetching transactions", error); + } finally { + setLoading(false); + } + }; + + getNotifications(); + }, [activeAddress]); + + const handleClick = (id: string) => { + push(`/transaction/${id}?back=${encodeURIComponent("/transactions")}`); + }; + + const getFormattedAmount = (transaction: ExtendedTransaction) => { + switch (transaction.transactionType) { + case "sent": + case "received": + return `${parseFloat(transaction.node.quantity.ar).toFixed(3)} AR`; + case "aoSent": + case "aoReceived": + if (transaction.aoInfo) { + return `${balanceToFractioned(transaction.aoInfo.quantity, { + divisibility: transaction.aoInfo.denomination + })} ${transaction.aoInfo.tickerName}`; + } + return ""; + default: + return ""; + } + }; + + const getTransactionDescription = (transaction: ExtendedTransaction) => { + switch (transaction.transactionType) { + case "sent": + return `${browser.i18n.getMessage("sent")} AR`; + case "received": + return `${browser.i18n.getMessage("received")} AR`; + case "aoSent": + return `${browser.i18n.getMessage("sent")} ${ + transaction.aoInfo.tickerName + }`; + case "aoReceived": + return `${browser.i18n.getMessage("received")} ${ + transaction.aoInfo.tickerName + }`; + default: + return ""; + } + }; + + const getFullMonthName = (monthYear: string) => { + const [month, year] = monthYear.split("-").map(Number); + const date = new Date(year, month - 1); + return date.toLocaleString("default", { month: "long" }); + }; + + return ( + <> + + + {!loading && + (Object.keys(transactions).length > 0 ? ( + Object.keys(transactions).map((monthYear) => ( +
+ {getFullMonthName(monthYear)}{" "} + + {transactions[monthYear].map((transaction) => ( + handleClick(transaction.node.id)} + > +
+
{getTransactionDescription(transaction)}
+ + {transaction.date + ? `${getFullMonthName(monthYear)} ${ + transaction.day + }` + : "Pending"} + +
+
+
{getFormattedAmount(transaction)}
+ + {transaction.node.quantity && + formatFiatBalance( + transaction.node.quantity.ar, + currency + )} + +
+
+ ))} +
+
+ )) + ) : ( + + + {browser.i18n.getMessage("no_transactions")} + + + ))} +
+ + ); +} + +const Selector = styled.span<{ active?: string }>``; + +const Month = styled.p` + margin: 0; + padding-bottom: 12px; + font-size: 10px; + font-weight: 500; +`; + +const TransactionsWrapper = styled.div` + padding: 0 15px 15px 15px; + display: flex; + flex-direction: column; + gap: 12px; +`; + +const Main = styled.h4` + font-weight: 500; + font-size: 14px; + margin: 0; +`; + +const Secondary = styled.h6` + margin: 0; + font-weight: 500; + color: ${(props) => props.theme.secondaryTextv2}; + font-size: 10px; +`; + +const Transaction = styled.div` + display: flex; + cursor: pointer; + justify-content: space-between; + border-bottom: 1px solid ${(props) => props.theme.backgroundSecondary}; + padding-bottom: 8px; + + &:last-child { + padding-bottom: 0; + border-bottom: none; + } +`; + +const Section = styled.div<{ alignRight?: boolean }>` + text-align: ${({ alignRight }) => (alignRight ? "right" : "left")}; +`; + +const TransactionItem = styled.div` + border: 1px solid ${(props) => props.theme.backgroundSecondary}; + gap: 8px; + display: flex; + flex-direction: column; + padding: 8px 10px; + border-radius: 10px; +`; diff --git a/src/routes/welcome/generate/done.tsx b/src/routes/welcome/generate/done.tsx index 8e75bda54..c9bebde0b 100644 --- a/src/routes/welcome/generate/done.tsx +++ b/src/routes/welcome/generate/done.tsx @@ -6,12 +6,19 @@ import Paragraph from "~components/Paragraph"; import browser from "webextension-polyfill"; import { addWallet } from "~wallets"; import { useContext, useEffect } from "react"; -import { EventType, PageType, trackEvent, trackPage } from "~utils/analytics"; +import { + EventType, + PageType, + isUserInGDPRCountry, + trackEvent, + trackPage +} from "~utils/analytics"; import useSetting from "~settings/hook"; import { ExtensionStorage } from "~utils/storage"; import { useStorage } from "@plasmohq/storage/hook"; import JSConfetti from "js-confetti"; import { useLocation } from "wouter"; +import { addExpiration } from "~wallets/auth"; export default function Done() { // wallet context @@ -48,6 +55,9 @@ export default function Done() { password ); + // add password expiration + await addExpiration(); + // log user onboarded await trackEvent(EventType.ONBOARDED, {}); @@ -66,6 +76,20 @@ export default function Done() { jsConfetti.addConfetti(); }, []); + // determine location + useEffect(() => { + const getLocation = async () => { + try { + const loc = await isUserInGDPRCountry(); + setAnalytics(!loc); + } catch (err) { + console.error(err); + } + }; + + getLocation(); + }, []); + // Segment useEffect(() => { trackPage(PageType.ONBOARD_COMPLETE); @@ -81,8 +105,8 @@ export default function Done() { { - setAnalytics(checked); + onChange={() => { + setAnalytics((prev) => !prev); setAnswered(true); }} > diff --git a/src/routes/welcome/load/done.tsx b/src/routes/welcome/load/done.tsx index 345afb62e..329c7d863 100644 --- a/src/routes/welcome/load/done.tsx +++ b/src/routes/welcome/load/done.tsx @@ -1,5 +1,5 @@ import { ButtonV2, Checkbox, Spacer, Text } from "@arconnect/components"; -import { PageType, trackPage } from "~utils/analytics"; +import { PageType, isUserInGDPRCountry, trackPage } from "~utils/analytics"; import { useStorage } from "@plasmohq/storage/hook"; import { ExtensionStorage } from "~utils/storage"; import Paragraph from "~components/Paragraph"; @@ -29,6 +29,20 @@ export default function Done() { setLocation("/getting-started/1"); } + // determine location + useEffect(() => { + const getLocation = async () => { + try { + const loc = await isUserInGDPRCountry(); + setAnalytics(!loc); + } catch (err) { + console.error(err); + } + }; + + getLocation(); + }, []); + // Segment useEffect(() => { trackPage(PageType.ONBOARD_COMPLETE); @@ -47,8 +61,8 @@ export default function Done() { {browser.i18n.getMessage("all_set_paragraph")} { - setAnalytics(checked); + onChange={() => { + setAnalytics((prev) => !prev); setAnswered(true); }} > diff --git a/src/utils/analytics.ts b/src/utils/analytics.ts index 18cf30d51..199852c9a 100644 --- a/src/utils/analytics.ts +++ b/src/utils/analytics.ts @@ -6,6 +6,7 @@ import Arweave from "arweave"; import { defaultGateway } from "~gateways/gateway"; import { v4 as uuid } from "uuid"; import browser, { type Alarms } from "webextension-polyfill"; +import axios from "axios"; const PUBLIC_SEGMENT_WRITEKEY = "J97E4cvSZqmpeEdiUQNC2IxS1Kw4Cwxm"; @@ -223,3 +224,64 @@ const setToStartOfNextMonth = (currentDate: Date): Date => { ); return newDate; }; + +const GDPR_COUNTRIES_AND_OTHERS = [ + "AT", // Austria + "BE", // Belgium + "BG", // Bulgaria + "HR", // Croatia + "CY", // Cyprus + "CZ", // Czech Republic + "DK", // Denmark + "EE", // Estonia + "FI", // Finland + "FR", // France + "DE", // Germany + "GR", // Greece + "HU", // Hungary + "IE", // Ireland + "IT", // Italy + "LV", // Latvia + "LT", // Lithuania + "LU", // Luxembourg + "MT", // Malta + "NL", // Netherlands + "PL", // Poland + "PT", // Portugal + "RO", // Romania + "SK", // Slovakia + "SI", // Slovenia + "ES", // Spain + "SE", // Sweden + "GB", // United Kingdom + "CH", // Switzerland + "BH", // Bahrain + "IL", // Israel + "QA", // Qatar + "TR", // Turkey + "KE", // Kenya + "MU", // Mauritius + "NG", // Nigeria + "ZA", // South Africa + "UG", // Uganda + "JP", // Japan + "KR", // South Korea + "NZ", // New Zealand + "AR", // Argentina + "BR", // Brazil + "UY", // Uruguay + "CA" // Canada +]; + +// Defaults to true to +export const isUserInGDPRCountry = async (): Promise => { + try { + const response = await axios.get("https://ipinfo.io?token=f73f7a8b88a8bf"); + + const { country } = response.data; + return GDPR_COUNTRIES_AND_OTHERS.includes(country); + } catch (error) { + console.error("Error fetching location:", error); + return true; + } +}; diff --git a/src/utils/ao_import.ts b/src/utils/ao_import.ts new file mode 100644 index 000000000..9a64723a2 --- /dev/null +++ b/src/utils/ao_import.ts @@ -0,0 +1,102 @@ +import { ExtensionStorage } from "./storage"; +import { getAoTokens } from "~tokens"; +import { getTagValue, type Message, type TokenInfo } from "~tokens/aoTokens/ao"; + +const AO_NATIVE_TOKEN_REGISTRY = "Q2ri6Yl0wCIekTrVE0R6fQ9TT6ZlI7yIOPBnJsBhMzk"; +const AO_NATIVE_TOKEN_IMPORTED = "ao_native_token_imported"; +const AO_TOKENS = "ao_tokens"; +const AO_NATIVE_TOKEN = "ao_native_token"; +let isImporting = false; + +async function getTokenInfo(id: string): Promise { + const body = { + Id: "0000000000000000000000000000000000000000001", + Target: id, + Owner: "0000000000000000000000000000000000000000002", + Anchor: "0", + Data: "1234", + Tags: [ + { name: "Action", value: "Info" }, + { name: "Data-Protocol", value: "ao" }, + { name: "Type", value: "Message" }, + { name: "Variant", value: "ao.TN.1" } + ] + }; + const res = await ( + await fetch(`https://cu.ao-testnet.xyz/dry-run?process-id=${id}`, { + headers: { + "content-type": "application/json" + }, + body: JSON.stringify(body), + method: "POST" + }) + ).json(); + + // find message with token info + for (const msg of res.Messages as Message[]) { + const Ticker = getTagValue("Ticker", msg.Tags); + const Name = getTagValue("Name", msg.Tags); + const Denomination = getTagValue("Denomination", msg.Tags); + const Logo = getTagValue("Logo", msg.Tags); + const processId = getTagValue("Process-Id", msg.Tags); + + if (!Ticker && !Name) continue; + + // if the message was found, return the token details + return { + Name, + Ticker, + Denomination: Number(Denomination || 0), + Logo, + processId + }; + } + + throw new Error("Could not load token info."); +} + +export async function importAoNativeToken() { + try { + if (isImporting) return; + isImporting = true; + + // check if ao native token is already imported + const aoTokenImported = await ExtensionStorage.get( + AO_NATIVE_TOKEN_IMPORTED + ); + if (aoTokenImported) return; + + // check if there is a valid ao native token + const token = await getTokenInfo(AO_NATIVE_TOKEN_REGISTRY); + if (!token?.Ticker || !token?.processId) return; + + // check if ao native token is already added + const aoTokens = await getAoTokens(); + const isAoTokenPresent = aoTokens.some( + (t) => t.processId === token.processId + ); + if (isAoTokenPresent) { + await ExtensionStorage.set(AO_NATIVE_TOKEN, token.processId); + await ExtensionStorage.set(AO_NATIVE_TOKEN_IMPORTED, true); + return; + } + + // add ao native token to the first + aoTokens.unshift({ + Name: token.Name, + Ticker: token.Ticker, + Denomination: token.Denomination, + Logo: token.Logo, + processId: token.processId + }); + + // set ao native token imported and updated ao tokens + await ExtensionStorage.set(AO_NATIVE_TOKEN_IMPORTED, true); + await ExtensionStorage.set(AO_TOKENS, aoTokens); + await ExtensionStorage.set(AO_NATIVE_TOKEN, token.processId); + } catch (e) { + console.log("Error importing ao native token"); + } finally { + isImporting = false; + } +} diff --git a/src/utils/runtime.ts b/src/utils/runtime.ts index 25262b91f..b4aa3d9e4 100644 --- a/src/utils/runtime.ts +++ b/src/utils/runtime.ts @@ -27,7 +27,7 @@ export async function onInstalled(details: Runtime.OnInstalledDetailsType) { browser.alarms.create("notifications", { periodInMinutes: 1 }); // reset notifications - await ExtensionStorage.set("show_announcement", true); + // await ExtensionStorage.set("show_announcement", true); // initialize tokens in wallet await loadTokens(); diff --git a/yarn.lock b/yarn.lock index ca109d58c..754716b22 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1151,6 +1151,16 @@ "@lezer/lr" "^1.0.0" json5 "^2.2.1" +"@motionone/animation@^10.13.1": + version "10.18.0" + resolved "https://registry.npmjs.org/@motionone/animation/-/animation-10.18.0.tgz#868d00b447191816d5d5cf24b1cafa144017922b" + integrity sha512-9z2p5GFGCm0gBsZbi8rVMOAJCtw1WqBTIPw3ozk06gDvZInBPIsQcHgYogEJ4yuHJ+akuW8g1SEIOpTOvYs8hw== + dependencies: + "@motionone/easing" "^10.18.0" + "@motionone/types" "^10.17.1" + "@motionone/utils" "^10.18.0" + tslib "^2.3.1" + "@motionone/animation@^10.17.0": version "10.17.0" resolved "https://registry.yarnpkg.com/@motionone/animation/-/animation-10.17.0.tgz#7633c6f684b5fee2b61c405881b8c24662c68fca" @@ -1161,6 +1171,18 @@ "@motionone/utils" "^10.17.0" tslib "^2.3.1" +"@motionone/dom@10.13.1": + version "10.13.1" + resolved "https://registry.npmjs.org/@motionone/dom/-/dom-10.13.1.tgz#fc29ea5d12538f21b211b3168e502cfc07a24882" + integrity sha512-zjfX+AGMIt/fIqd/SL1Lj93S6AiJsEA3oc5M9VkUr+Gz+juRmYN1vfvZd6MvEkSqEjwPQgcjN7rGZHrDB9APfQ== + dependencies: + "@motionone/animation" "^10.13.1" + "@motionone/generators" "^10.13.1" + "@motionone/types" "^10.13.0" + "@motionone/utils" "^10.13.1" + hey-listen "^1.0.8" + tslib "^2.3.1" + "@motionone/dom@^10.15.3": version "10.17.0" resolved "https://registry.yarnpkg.com/@motionone/dom/-/dom-10.17.0.tgz#519dd78aab0750a94614c69a82da5290cd617383" @@ -1181,6 +1203,23 @@ "@motionone/utils" "^10.17.0" tslib "^2.3.1" +"@motionone/easing@^10.18.0": + version "10.18.0" + resolved "https://registry.npmjs.org/@motionone/easing/-/easing-10.18.0.tgz#7b82f6010dfee3a1bb0ee83abfbaff6edae0c708" + integrity sha512-VcjByo7XpdLS4o9T8t99JtgxkdMcNWD3yHU/n6CLEz3bkmKDRZyYQ/wmSf6daum8ZXqfUAgFeCZSpJZIMxaCzg== + dependencies: + "@motionone/utils" "^10.18.0" + tslib "^2.3.1" + +"@motionone/generators@^10.13.1": + version "10.18.0" + resolved "https://registry.npmjs.org/@motionone/generators/-/generators-10.18.0.tgz#fe09ab5cfa0fb9a8884097feb7eb60abeb600762" + integrity sha512-+qfkC2DtkDj4tHPu+AFKVfR/C30O1vYdvsGYaR13W/1cczPrrcjdvYCj0VLFuRMN+lP1xvpNZHCRNM4fBzn1jg== + dependencies: + "@motionone/types" "^10.17.1" + "@motionone/utils" "^10.18.0" + tslib "^2.3.1" + "@motionone/generators@^10.17.0": version "10.17.0" resolved "https://registry.yarnpkg.com/@motionone/generators/-/generators-10.17.0.tgz#878d292539c41434c13310d5f863a87a94e6e689" @@ -1190,11 +1229,25 @@ "@motionone/utils" "^10.17.0" tslib "^2.3.1" +"@motionone/types@^10.13.0", "@motionone/types@^10.17.1": + version "10.17.1" + resolved "https://registry.npmjs.org/@motionone/types/-/types-10.17.1.tgz#cf487badbbdc9da0c2cb86ffc1e5d11147c6e6fb" + integrity sha512-KaC4kgiODDz8hswCrS0btrVrzyU2CSQKO7Ps90ibBVSQmjkrt2teqta6/sOG59v7+dPnKMAg13jyqtMKV2yJ7A== + "@motionone/types@^10.17.0": version "10.17.0" resolved "https://registry.yarnpkg.com/@motionone/types/-/types-10.17.0.tgz#179571ce98851bac78e19a1c3974767227f08ba3" integrity sha512-EgeeqOZVdRUTEHq95Z3t8Rsirc7chN5xFAPMYFobx8TPubkEfRSm5xihmMUkbaR2ErKJTUw3347QDPTHIW12IA== +"@motionone/utils@^10.13.1", "@motionone/utils@^10.18.0": + version "10.18.0" + resolved "https://registry.npmjs.org/@motionone/utils/-/utils-10.18.0.tgz#a59ff8932ed9009624bca07c56b28ef2bb2f885e" + integrity sha512-3XVF7sgyTSI2KWvTf6uLlBJ5iAgRgmvp3bpuOiQJvInd4nZ19ET8lX5unn30SlmRH7hXbBbH+Gxd0m0klJ3Xtw== + dependencies: + "@motionone/types" "^10.17.1" + hey-listen "^1.0.8" + tslib "^2.3.1" + "@motionone/utils@^10.17.0": version "10.17.0" resolved "https://registry.yarnpkg.com/@motionone/utils/-/utils-10.17.0.tgz#cc0ba8acdc6848ff48d8c1f2d0d3e7602f4f942e" @@ -6727,6 +6780,20 @@ form-data@^4.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +framer-motion@7.5.3: + version "7.5.3" + resolved "https://registry.npmjs.org/framer-motion/-/framer-motion-7.5.3.tgz#a1de7d6c4abbf7333619d4a6c8df74c12240be43" + integrity sha512-VvANga9Z7bYtKMAsM/je81FwJDHfThOYywN04xVQ4OGdMVY09Bowx/q7nZd6XtytLuv6byc6GT1mYwag+SQ/nw== + dependencies: + "@motionone/dom" "10.13.1" + framesync "6.1.2" + hey-listen "^1.0.8" + popmotion "11.0.5" + style-value-types "5.1.2" + tslib "2.4.0" + optionalDependencies: + "@emotion/is-prop-valid" "^0.8.2" + framer-motion@^7.5.3: version "7.10.3" resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-7.10.3.tgz#8b23f50bbc1ee8c830c869c5398e457d5272feb5" @@ -6738,6 +6805,13 @@ framer-motion@^7.5.3: optionalDependencies: "@emotion/is-prop-valid" "^0.8.2" +framesync@6.1.2: + version "6.1.2" + resolved "https://registry.npmjs.org/framesync/-/framesync-6.1.2.tgz#755eff2fb5b8f3b4d2b266dd18121b300aefea27" + integrity sha512-jBTqhX6KaQVDyus8muwZbBeGGP0XgujBRbQ7gM7BRdS3CadCZIHiawyzYLnafYcvZIh5j8WE7cxZKFn7dXhu9g== + dependencies: + tslib "2.4.0" + from2@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" @@ -9738,6 +9812,16 @@ plasmo@0.86.3: tempy "3.1.0" typescript "5.2.2" +popmotion@11.0.5: + version "11.0.5" + resolved "https://registry.npmjs.org/popmotion/-/popmotion-11.0.5.tgz#8e3e014421a0ffa30ecd722564fd2558954e1f7d" + integrity sha512-la8gPM1WYeFznb/JqF4GiTkRRPZsfaj2+kCxqQgr2MJylMmIKUwBfWW8Wa5fml/8gmtlD5yI01MP1QCZPWmppA== + dependencies: + framesync "6.1.2" + hey-listen "^1.0.8" + style-value-types "5.1.2" + tslib "2.4.0" + possible-typed-array-names@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz#89bb63c6fada2c3e90adc4a647beeeb39cc7bf8f" @@ -11022,6 +11106,14 @@ strip-json-comments@~2.0.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== +style-value-types@5.1.2: + version "5.1.2" + resolved "https://registry.npmjs.org/style-value-types/-/style-value-types-5.1.2.tgz#6be66b237bd546048a764883528072ed95713b62" + integrity sha512-Vs9fNreYF9j6W2VvuDTP7kepALi7sk0xtk2Tu8Yxi9UoajJdEVpNpCov0HsLTqXvNGKX+Uv09pkozVITi1jf3Q== + dependencies: + hey-listen "^1.0.8" + tslib "2.4.0" + styled-components@^5.3.6: version "5.3.11" resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-5.3.11.tgz#9fda7bf1108e39bf3f3e612fcc18170dedcd57a8"