diff --git a/wallets/provider-all/package.json b/wallets/provider-all/package.json index 8988d02c6..1d0e6d9d1 100644 --- a/wallets/provider-all/package.json +++ b/wallets/provider-all/package.json @@ -49,6 +49,7 @@ "@rango-dev/provider-taho": "^0.39.0", "@rango-dev/provider-tokenpocket": "^0.39.0", "@rango-dev/provider-tomo": "^0.6.0", + "@rango-dev/provider-tonconnect": "^0.1.0", "@rango-dev/provider-mytonwallet": "^0.24.1-next.0", "@rango-dev/provider-trezor": "^0.6.0", "@rango-dev/provider-tron-link": "^0.39.1-next.0", diff --git a/wallets/provider-all/src/index.ts b/wallets/provider-all/src/index.ts index f0c107e21..22f33c7c9 100644 --- a/wallets/provider-all/src/index.ts +++ b/wallets/provider-all/src/index.ts @@ -1,4 +1,4 @@ -import type { Environments as MyTonWalletEnvironments } from '@rango-dev/provider-mytonwallet'; +import type { Environments as TonConnectEnvironments } from '@rango-dev/provider-tonconnect'; import type { Environments as TrezorEnvironments } from '@rango-dev/provider-trezor'; import type { Environments as WalletConnectEnvironments } from '@rango-dev/provider-walletconnect-2'; import type { ProviderInterface } from '@rango-dev/wallets-react'; @@ -32,6 +32,7 @@ import * as solflareSnap from '@rango-dev/provider-solflare-snap'; import * as taho from '@rango-dev/provider-taho'; import * as tokenpocket from '@rango-dev/provider-tokenpocket'; import * as tomo from '@rango-dev/provider-tomo'; +import * as tonconnect from '@rango-dev/provider-tonconnect'; import * as trezor from '@rango-dev/provider-trezor'; import * as tronLink from '@rango-dev/provider-tron-link'; import * as trustwallet from '@rango-dev/provider-trustwallet'; @@ -45,7 +46,7 @@ interface Options { walletconnect2: WalletConnectEnvironments; selectedProviders?: (WalletType | ProviderInterface)[]; trezor?: TrezorEnvironments; - tonConnect?: MyTonWalletEnvironments; + tonConnect?: TonConnectEnvironments; } export const allProviders = (options?: Options) => { @@ -88,12 +89,24 @@ export const allProviders = (options?: Options) => { } } + if ( + !isWalletExcluded(providers, { + type: WalletTypes.TON_CONNECT, + name: 'tonconnect', + }) + ) { + if (!!options?.tonConnect?.manifestUrl) { + tonconnect.init(options.tonConnect); + } + } + return [ safe, defaultInjected, metamask, solflareSnap, walletconnect2, + tonconnect, keplr, phantom, argentx, diff --git a/wallets/provider-tonconnect/package.json b/wallets/provider-tonconnect/package.json new file mode 100644 index 000000000..fbf3b481d --- /dev/null +++ b/wallets/provider-tonconnect/package.json @@ -0,0 +1,36 @@ +{ + "name": "@rango-dev/provider-tonconnect", + "version": "0.1.0", + "license": "MIT", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + } + }, + "typings": "dist/index.d.ts", + "files": [ + "dist", + "src" + ], + "scripts": { + "build": "node ../../scripts/build/command.mjs --path wallets/provider-tonconnect", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" + }, + "dependencies": { + "@rango-dev/wallets-shared": "^0.39.0", + "@ton/core": "^0.59.0", + "@ton/crypto": "^3.3.0", + "@tonconnect/ui": "^2.0.9", + "rango-types": "^0.1.75" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/wallets/provider-tonconnect/readme.md b/wallets/provider-tonconnect/readme.md new file mode 100644 index 000000000..5da1c55d4 --- /dev/null +++ b/wallets/provider-tonconnect/readme.md @@ -0,0 +1,3 @@ +# @rango-dev/provider-tonconnect + +TonConnect \ No newline at end of file diff --git a/wallets/provider-tonconnect/src/helpers.ts b/wallets/provider-tonconnect/src/helpers.ts new file mode 100644 index 000000000..508d680f0 --- /dev/null +++ b/wallets/provider-tonconnect/src/helpers.ts @@ -0,0 +1,47 @@ +import type { TonConnectUI } from '@tonconnect/ui'; + +export async function getTonConnectUIModule() { + const tonConnectUI = await import('@tonconnect/ui'); + return tonConnectUI; +} + +export async function getTonCoreModule() { + const tonCore = await import('@ton/core'); + return tonCore; +} + +export async function waitForConnection( + tonConnectUI: TonConnectUI +): Promise { + return new Promise((resolve, reject) => { + const unsubscribeStatusChange = tonConnectUI.onStatusChange( + (state) => { + const walletConnected = !!state?.account.address; + + if (walletConnected) { + unsubscribeStatusChange(); + resolve(state.account.address); + } + }, + (error) => { + unsubscribeStatusChange(); + reject(error); + } + ); + + const unsubscribeModalStateChange = tonConnectUI.onModalStateChange( + (modalState) => { + if (modalState.closeReason === 'action-cancelled') { + unsubscribeStatusChange(); + unsubscribeModalStateChange(); + reject(new Error('The action was canceled by the user')); + } + } + ); + }); +} + +export async function parseAddress(rawAddress: string): Promise { + const tonCore = await getTonCoreModule(); + return tonCore.Address.parse(rawAddress).toString({ bounceable: false }); +} diff --git a/wallets/provider-tonconnect/src/index.ts b/wallets/provider-tonconnect/src/index.ts new file mode 100644 index 000000000..11726377a --- /dev/null +++ b/wallets/provider-tonconnect/src/index.ts @@ -0,0 +1,97 @@ +import type { Environments } from './types.js'; +import type { + CanEagerConnect, + CanSwitchNetwork, + Connect, + Disconnect, + GetInstance, + WalletInfo, +} from '@rango-dev/wallets-shared'; +import type { TonConnectUI } from '@tonconnect/ui'; +import type { BlockchainMeta, SignerFactory } from 'rango-types'; + +import { Networks, WalletTypes } from '@rango-dev/wallets-shared'; +import { tonBlockchain } from 'rango-types'; + +import { + getTonConnectUIModule, + parseAddress, + waitForConnection, +} from './helpers.js'; +import signer from './signer.js'; + +let envs: Environments = { + manifestUrl: '', +}; + +const WALLET = WalletTypes.TON_CONNECT; + +export const config = { + type: WALLET, + isAsyncInstance: true, + checkInstallation: false, +}; + +export type { Environments }; + +export const init = (environments: Environments) => { + envs = environments; +}; + +let instance: TonConnectUI | null = null; + +export const getInstance: GetInstance = async () => { + if (!instance) { + const { TonConnectUI } = await getTonConnectUIModule(); + instance = new TonConnectUI(envs); + } + return instance; +}; + +export const connect: Connect = async ({ instance }) => { + const tonConnectUI: TonConnectUI = instance; + const connectionRestored = await tonConnectUI.connectionRestored; + + if (connectionRestored && tonConnectUI.account?.address) { + const parsedAddress = await parseAddress(tonConnectUI.account.address); + return { accounts: [parsedAddress], chainId: Networks.TON }; + } + + await tonConnectUI.openModal(); + const result = await waitForConnection(tonConnectUI); + const parsedAddress = await parseAddress(result); + + return { + accounts: [parsedAddress], + chainId: Networks.TON, + }; +}; + +export const canEagerConnect: CanEagerConnect = async ({ instance }) => { + const tonConnectUI = instance as TonConnectUI; + const connectionRestored = await tonConnectUI.connectionRestored; + return connectionRestored; +}; + +export const canSwitchNetworkTo: CanSwitchNetwork = () => false; + +export const getSigners: (provider: TonConnectUI) => Promise = + signer; + +export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( + allBlockChains +) => { + const ton = tonBlockchain(allBlockChains); + return { + name: 'TON Connect', + img: 'https://raw.githubusercontent.com/rango-exchange/assets/7fb19ed5d5019b4d6a41ce91b39cde64f86af4c6/wallets/tonconnect/icon.svg', + installLink: '', + color: '#fff', + supportedChains: ton, + }; +}; + +export const disconnect: Disconnect = async ({ instance }) => { + const tonConnectUI = instance as TonConnectUI; + await tonConnectUI.disconnect(); +}; diff --git a/wallets/provider-tonconnect/src/signer.ts b/wallets/provider-tonconnect/src/signer.ts new file mode 100644 index 000000000..1bbe14a9d --- /dev/null +++ b/wallets/provider-tonconnect/src/signer.ts @@ -0,0 +1,13 @@ +import type { TonConnectUI } from '@tonconnect/ui'; +import type { SignerFactory } from 'rango-types'; + +import { DefaultSignerFactory, TransactionType as TxType } from 'rango-types'; + +export default async function getSigners( + provider: TonConnectUI +): Promise { + const signers = new DefaultSignerFactory(); + const { CustomTonSigner } = await import('./ton-signer.js'); + signers.registerSigner(TxType.TON, new CustomTonSigner(provider)); + return signers; +} diff --git a/wallets/provider-tonconnect/src/ton-signer.ts b/wallets/provider-tonconnect/src/ton-signer.ts new file mode 100644 index 000000000..7eacba12b --- /dev/null +++ b/wallets/provider-tonconnect/src/ton-signer.ts @@ -0,0 +1,29 @@ +import type { TonConnectUI } from '@tonconnect/ui'; +import type { GenericSigner, TonTransaction } from 'rango-types'; + +import { Cell } from '@ton/core'; +import { CHAIN } from '@tonconnect/ui'; +import { SignerError } from 'rango-types'; + +export class CustomTonSigner implements GenericSigner { + private provider: TonConnectUI; + + constructor(provider: TonConnectUI) { + this.provider = provider; + } + + async signMessage(): Promise { + throw SignerError.UnimplementedError('signMessage'); + } + + async signAndSendTx(tx: TonTransaction): Promise<{ hash: string }> { + const { blockChain, type, ...txObjectForSign } = tx; + const result = await this.provider.sendTransaction({ + ...txObjectForSign, + network: CHAIN.MAINNET, + }); + + const hash = Cell.fromBase64(result.boc).hash().toString('hex'); + return { hash }; + } +} diff --git a/wallets/provider-tonconnect/src/types.ts b/wallets/provider-tonconnect/src/types.ts new file mode 100644 index 000000000..8403e975c --- /dev/null +++ b/wallets/provider-tonconnect/src/types.ts @@ -0,0 +1,3 @@ +export interface Environments extends Record { + manifestUrl: string; +} diff --git a/wallets/provider-tonconnect/tsconfig.build.json b/wallets/provider-tonconnect/tsconfig.build.json new file mode 100644 index 000000000..d2ac5e673 --- /dev/null +++ b/wallets/provider-tonconnect/tsconfig.build.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.libnext.json", + "include": ["src", "types", "../../global-wallets-env.d.ts"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "lib": ["dom", "esnext"] + } +} diff --git a/wallets/provider-tonconnect/tsconfig.json b/wallets/provider-tonconnect/tsconfig.json new file mode 100644 index 000000000..a3a0b0f59 --- /dev/null +++ b/wallets/provider-tonconnect/tsconfig.json @@ -0,0 +1 @@ +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/wallets/shared/src/rango.ts b/wallets/shared/src/rango.ts index dd8a9510b..ef3bc44c6 100644 --- a/wallets/shared/src/rango.ts +++ b/wallets/shared/src/rango.ts @@ -75,6 +75,7 @@ export enum WalletTypes { TOMO = 'tomo', TREZOR = 'trezor', SOLFLARE = 'solflare', + TON_CONNECT = 'tonconnect', } export const namespaces: Record< diff --git a/widget/playground/src/utils/export.ts b/widget/playground/src/utils/export.ts index 68c6b547d..3d31b0f47 100755 --- a/widget/playground/src/utils/export.ts +++ b/widget/playground/src/utils/export.ts @@ -91,6 +91,16 @@ export function filterConfig( filteredConfigForExport.tonConnect = config.tonConnect; } + const isTonconnectNeeded = isWalletConfigNeeded( + filteredConfigForExport, + 'tonConnect', + 'tonconnect' + ); + + if (isTonconnectNeeded) { + filteredConfigForExport.tonConnect = config.tonConnect; + } + return { userSelectedConfig, filteredConfigForExport }; } diff --git a/yarn.lock b/yarn.lock index b1c3fa40a..d55fa741f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7323,7 +7323,7 @@ dependencies: jssha "3.2.0" -"@ton/crypto@3.3.0": +"@ton/crypto@^3.3.0": version "3.3.0" resolved "https://registry.yarnpkg.com/@ton/crypto/-/crypto-3.3.0.tgz#019103df6540fbc1d8102979b4587bc85ff9779e" integrity sha512-/A6CYGgA/H36OZ9BbTaGerKtzWp50rg67ZCH2oIjV1NcrBaCK9Z343M+CxedvM7Haf3f/Ee9EhxyeTp0GKMUpA== @@ -7332,6 +7332,47 @@ jssha "3.2.0" tweetnacl "1.0.3" +"@tonconnect/isomorphic-eventsource@^0.0.2": + version "0.0.2" + resolved "https://registry.yarnpkg.com/@tonconnect/isomorphic-eventsource/-/isomorphic-eventsource-0.0.2.tgz#e58c44cf9953e090f2c35da9a638946ddb614be5" + integrity sha512-B4UoIjPi0QkvIzZH5fV3BQLWrqSYABdrzZQSI9sJA9aA+iC0ohOzFwVVGXanlxeDAy1bcvPbb29f6sVUk0UnnQ== + dependencies: + eventsource "^2.0.2" + +"@tonconnect/isomorphic-fetch@^0.0.3": + version "0.0.3" + resolved "https://registry.yarnpkg.com/@tonconnect/isomorphic-fetch/-/isomorphic-fetch-0.0.3.tgz#31978e04ddc4428eff532c23d20229ed5ddb6417" + integrity sha512-jIg5nTrDwnite4fXao3dD83eCpTvInTjZon/rZZrIftIegh4XxyVb5G2mpMqXrVGk1e8SVXm3Kj5OtfMplQs0w== + dependencies: + node-fetch "^2.6.9" + +"@tonconnect/protocol@^2.2.6": + version "2.2.6" + resolved "https://registry.yarnpkg.com/@tonconnect/protocol/-/protocol-2.2.6.tgz#24b3fbcde6003e65fb5840a190072db5378699db" + integrity sha512-kyoDz5EqgsycYP+A+JbVsAUYHNT059BCrK+m0pqxykMODwpziuSAXfwAZmHcg8v7NB9VKYbdFY55xKeXOuEd0w== + dependencies: + tweetnacl "^1.0.3" + tweetnacl-util "^0.15.1" + +"@tonconnect/sdk@3.0.5": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@tonconnect/sdk/-/sdk-3.0.5.tgz#08a202bdc8ea897c37221fd69925c35cd2106323" + integrity sha512-ow0qnN4s3iQ/r2uXobZ7YzdQBtan/36CgCT9IP35G07g38UxsUXwzw8ANmJTDj/JPiQcIKuYBMfIwIX9zLM0wg== + dependencies: + "@tonconnect/isomorphic-eventsource" "^0.0.2" + "@tonconnect/isomorphic-fetch" "^0.0.3" + "@tonconnect/protocol" "^2.2.6" + +"@tonconnect/ui@^2.0.9": + version "2.0.9" + resolved "https://registry.yarnpkg.com/@tonconnect/ui/-/ui-2.0.9.tgz#589285c9b8f4b0d94c10b3feadfae266bf086503" + integrity sha512-ZxofTBf81NqrxyD0ybI8AuFHN11uKVg/00xTDFhP5FoPB8rYC7En9qE2VJ6IvwvtTpmh8jspi2ancOHUMBoCQA== + dependencies: + "@tonconnect/sdk" "3.0.5" + classnames "^2.3.2" + deepmerge "^4.2.2" + ua-parser-js "^1.0.35" + "@trezor/analytics@1.0.17": version "1.0.17" resolved "https://registry.yarnpkg.com/@trezor/analytics/-/analytics-1.0.17.tgz#5835fe8201498367104d9fa63a2cb6094ad2cbdc" @@ -10043,7 +10084,7 @@ cjs-module-lexer@^1.2.3: resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107" integrity sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ== -classnames@^2.3.1: +classnames@^2.3.1, classnames@^2.3.2: version "2.5.1" resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.5.1.tgz#ba774c614be0f016da105c858e7159eae8e7687b" integrity sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow== @@ -12147,6 +12188,11 @@ events@^3.2.0, events@^3.3.0: resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== +eventsource@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-2.0.2.tgz#76dfcc02930fb2ff339520b6d290da573a9e8508" + integrity sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA== + evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" @@ -15354,7 +15400,7 @@ node-fetch@^1.0.1: encoding "^0.1.11" is-stream "^1.0.1" -node-fetch@^2.0.0, node-fetch@^2.6.1, node-fetch@^2.6.12, node-fetch@^2.7.0: +node-fetch@^2.0.0, node-fetch@^2.6.1, node-fetch@^2.6.12, node-fetch@^2.6.9, node-fetch@^2.7.0: version "2.7.0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== @@ -16700,6 +16746,11 @@ rango-types@^0.1.74: resolved "https://registry.yarnpkg.com/rango-types/-/rango-types-0.1.74.tgz#a6049242ce60f5d84d638c70650735529979a8dd" integrity sha512-sMWGAxNF2Yv/PG3eTL01FoHEVf40VEypt1VqPP0HkIwo+gR8WGhEL3JFkAo0UE3gJ7rjgwmMLziAMu1zwwJ+ng== +rango-types@^0.1.75: + version "0.1.75" + resolved "https://registry.yarnpkg.com/rango-types/-/rango-types-0.1.75.tgz#24d2a3a30e113a7bf1088853e89b39b5722e9c04" + integrity sha512-Xb/lfV+fXEQdk6APY77C0oKl++mqdDdwlRyfVi10tV5tfw0Yvl5+p8Av16oPqBcM20WJGjBFCUpHEAKsEprXNQ== + raw-body@2.5.2: version "2.5.2" resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a" @@ -18118,7 +18169,16 @@ string-argv@0.3.2: resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.2.tgz#2b6d0ef24b656274d957d54e0a4bbf6153dc02b6" integrity sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q== -"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0": + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -18210,7 +18270,14 @@ stringify-object@^5.0.0: is-obj "^3.0.0" is-regexp "^3.1.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -18737,7 +18804,12 @@ tween-functions@^1.2.0: resolved "https://registry.yarnpkg.com/tween-functions/-/tween-functions-1.2.0.tgz#1ae3a50e7c60bb3def774eac707acbca73bbc3ff" integrity sha512-PZBtLYcCLtEcjL14Fzb1gSxPBeL7nWvGhO5ZFPGqziCcr8uvHp0NDmdjBchp6KHL+tExcg0m3NISmKxhU394dA== -tweetnacl@1.0.3: +tweetnacl-util@^0.15.1: + version "0.15.1" + resolved "https://registry.yarnpkg.com/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz#b80fcdb5c97bcc508be18c44a4be50f022eea00b" + integrity sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw== + +tweetnacl@1.0.3, tweetnacl@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596" integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw== @@ -18878,6 +18950,11 @@ ua-parser-js@^0.7.30: resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.37.tgz#e464e66dac2d33a7a1251d7d7a99d6157ec27832" integrity sha512-xV8kqRKM+jhMvcHWUKthV9fNebIzrNy//2O9ZwWcfiBFR5f25XVZPLlEajk/sf3Ra15V92isyQqnIEXRDaZWEA== +ua-parser-js@^1.0.35: + version "1.0.39" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-1.0.39.tgz#bfc07f361549bf249bd8f4589a4cccec18fd2018" + integrity sha512-k24RCVWlEcjkdOxYmVJgeD/0a1TiSpqLg+ZalVGV9lsnr4yqu0w7tX/x2xX6G4zpkgQnRf89lxuZ1wsbjXM8lw== + ua-parser-js@^1.0.37: version "1.0.38" resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-1.0.38.tgz#66bb0c4c0e322fe48edfe6d446df6042e62f25e2" @@ -19559,7 +19636,7 @@ wordwrap@^1.0.0: resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -19577,6 +19654,15 @@ wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrap-ansi@^8.0.1, wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"