Implement send transaction, payment works, yaay.

This commit is contained in:
muzam
2022-01-10 15:21:59 +05:30
parent b28bcfdd0a
commit ce5b307a8b
10 changed files with 311 additions and 63 deletions

View File

@@ -13,7 +13,7 @@ const Select: FC<Props> = props => {
// primary: pink.pink9,
primary: isDark ? grayDark.gray4 : gray.gray4,
secondary: isDark ? grayDark.gray8 : gray.gray8,
background: isDark ? "rgb(10, 10, 10)" : "rgb(245, 245, 245)",
background: isDark ? "rgb(10, 10, 10)" : "rgb(244, 244, 244)",
searchText: isDark ? grayDark.gray12 : gray.gray12,
placeholder: isDark ? grayDark.gray11 : gray.gray11,
};

View File

@@ -40,6 +40,7 @@
"react-hot-keys": "^2.7.1",
"react-hot-toast": "^2.1.1",
"react-new-window": "^0.2.1",
"react-query": "^3.34.7",
"react-select": "^5.2.1",
"react-stay-scrolled": "^7.4.0",
"reconnecting-websocket": "^4.4.0",

View File

@@ -1,4 +1,4 @@
import { useEffect } from "react";
import { useEffect, useState } from "react";
import "../styles/globals.css";
import type { AppProps } from "next/app";
import Head from "next/head";
@@ -7,6 +7,7 @@ import { ThemeProvider } from "next-themes";
import { Toaster } from "react-hot-toast";
import { useRouter } from "next/router";
import { IdProvider } from "@radix-ui/react-id";
import { QueryClient, QueryClientProvider } from "react-query";
import { darkTheme, css } from "../stitches.config";
import Navigation from "../components/Navigation";
@@ -17,6 +18,8 @@ function MyApp({ Component, pageProps: { session, ...pageProps } }: AppProps) {
const router = useRouter();
const slug = router.query?.slug;
const gistId = (Array.isArray(slug) && slug[0]) ?? null;
const [queryClient] = useState(() => new QueryClient());
useEffect(() => {
if (gistId && router.isReady) {
fetchFiles(gistId);
@@ -32,6 +35,7 @@ function MyApp({ Component, pageProps: { session, ...pageProps } }: AppProps) {
<Head>
<title>XRPL Hooks Playground</title>
</Head>
<QueryClientProvider client={queryClient}>
<IdProvider>
<SessionProvider session={session}>
<ThemeProvider
@@ -62,6 +66,7 @@ function MyApp({ Component, pageProps: { session, ...pageProps } }: AppProps) {
</ThemeProvider>
</SessionProvider>
</IdProvider>
</QueryClientProvider>
</>
);
}

View File

@@ -1,6 +1,12 @@
import { Container, Flex, Box, Tabs, Tab, Input, Select, Text, Button } from "../../components";
import { Play } from "phosphor-react";
import dynamic from "next/dynamic";
import { getTransactionTypes } from "../../utils/getTransactionTypes";
import { useQuery } from "react-query";
import { useSnapshot } from "valtio";
import state from "../../state";
import { sendTransaction } from "../../state/actions";
import { useCallback, useState } from "react";
const LogBox = dynamic(() => import("../../components/LogBox"), {
ssr: false,
@@ -9,16 +15,67 @@ const Accounts = dynamic(() => import("../../components/Accounts"), {
ssr: false,
});
// type SelectOption<T> = { value: T, label: string };
const Transaction = () => {
const options = [
{ value: "chocolate", label: "Chocolate" },
{ value: "strawberry", label: "Strawberry" },
{ value: "vanilla", label: "Vanilla" },
{
value: "long",
label: "lorem woy uiwyf wyfw8 fwfw98f w98fy wf8fw89f 9w8fy w9fyw9f wf7tdw9f ",
},
];
const snap = useSnapshot(state);
const {
data: typesData,
isLoading: typesDataLoading,
isError: typesDataError,
} = useQuery("transactionTypes", getTransactionTypes);
const transactionsOptions =
typesData
?.map(tt => ({
value: tt.transactionType,
label: tt.transactionType,
}))
.filter(opt => Boolean(opt.value)) || [];
const [selectedTransaction, setSelectedTransaction] = useState<
typeof transactionsOptions[0] | null
>(null);
const accountOptions = snap.accounts.map(acc => ({
label: acc.name,
value: acc.address,
}));
const [selectedAccount, setSelectedAccount] = useState<typeof accountOptions[0] | null>(null);
const destAccountOptions = snap.accounts
.map(acc => ({
label: acc.name,
value: acc.address,
}))
.filter(acc => acc.value !== selectedAccount?.value);
const [selectedDestAccount, setSelectedDestAccount] = useState<
typeof destAccountOptions[0] | null
>(null);
const [txOptions, setTxOptions] = useState({
Amount: "0",
});
const [txIsLoading, setTxIsLoading] = useState(false)
// const [txIsError, setTxIsError] = useState<string | null>(null)
const submitTest = useCallback(async () => {
const account = snap.accounts.find(acc => acc.address === selectedAccount?.value);
const TransactionType = selectedTransaction?.value;
if (!account || !TransactionType || txIsLoading) return;
setTxIsLoading(true)
// setTxIsError(null)
const { Amount, ...opts } = txOptions
await sendTransaction(account, {
TransactionType,
Destination: selectedDestAccount?.value,
Amount: +Amount ? +Amount * 1000000 + "" : undefined, // convert xrp to ...
...opts,
});
setTxIsLoading(false)
// TODO catch error for UI to show
}, [selectedAccount, selectedDestAccount, selectedTransaction, snap.accounts, txOptions, txIsLoading]);
return (
<>
<Container css={{ p: "$3 0", fontSize: "$sm" }}>
@@ -28,10 +85,15 @@ const Transaction = () => {
Transaction type:{" "}
</Text>
<Select
instanceId="transaction"
instanceId="transactionsType"
placeholder="Select transaction type"
isLoading={typesDataLoading}
isDisabled={typesDataError}
options={transactionsOptions}
hideSelectedOptions
css={{ width: "70%" }}
options={options}
value={selectedTransaction}
onChange={tt => setSelectedTransaction(tt as any)}
/>
</Flex>
<Flex row fluid css={{ justifyContent: "flex-end", alignItems: "center", mb: "$3" }}>
@@ -40,16 +102,23 @@ const Transaction = () => {
</Text>
<Select
instanceId="from-account"
placeholder="Select account from which to send from"
placeholder="Select your account"
css={{ width: "70%" }}
options={options}
options={accountOptions}
value={selectedAccount}
onChange={acc => setSelectedAccount(acc as any)}
/>
</Flex>
<Flex row fluid css={{ justifyContent: "flex-end", alignItems: "center", mb: "$3" }}>
<Text muted css={{ mr: "$3" }}>
Amount (XRP):{" "}
</Text>
<Input defaultValue="0" variant="deep" css={{ width: "70%", flex: "inherit", height: "$9" }} />
<Input
value={txOptions.Amount}
onChange={e => setTxOptions({ ...txOptions, Amount: e.target.value })}
variant="deep"
css={{ width: "70%", flex: "inherit", height: "$9" }}
/>
</Flex>
<Flex row fluid css={{ justifyContent: "flex-end", alignItems: "center", mb: "$3" }}>
<Text muted css={{ mr: "$3" }}>
@@ -57,9 +126,12 @@ const Transaction = () => {
</Text>
<Select
instanceId="to-account"
placeholder="Select account from which to send from"
placeholder="Select the destination account"
css={{ width: "70%" }}
options={options}
options={destAccountOptions}
value={selectedDestAccount}
isClearable
onChange={acc => setSelectedDestAccount(acc as any)}
/>
</Flex>
</Flex>
@@ -70,7 +142,7 @@ const Transaction = () => {
<Button outline css={{ mr: "$3" }}>
RESET
</Button>
<Button variant="primary">
<Button variant="primary" onClick={submitTest} isLoading={txIsLoading}>
<Play weight="bold" size="16px" />
RUN TEST
</Button>
@@ -81,10 +153,15 @@ const Transaction = () => {
};
const Test = () => {
const snap = useSnapshot(state);
return (
<Container css={{ py: "$3", px: 0 }}>
<Flex row fluid css={{ justifyContent: 'center', mb: "$2", height: '40vh', minHeight: '300px', p: '$3 $2' }}>
<Box css={{ width: "60%", px: "$2", maxWidth: '800px' }}>
<Flex
row
fluid
css={{ justifyContent: "center", mb: "$2", height: "40vh", minHeight: "300px", p: "$3 $2" }}
>
<Box css={{ width: "60%", px: "$2", maxWidth: "800px" }}>
<Tabs>
{/* TODO Dynamic tabs */}
<Tab header="test1.json">
@@ -95,14 +172,18 @@ const Test = () => {
</Tab>
</Tabs>
</Box>
<Box css={{ width: "40%", mx: "$2", height: '100%', maxWidth: '750px' }}>
<Box css={{ width: "40%", mx: "$2", height: "100%", maxWidth: "750px" }}>
<Accounts card hideDeployBtn showHookStats />
</Box>
</Flex>
<Flex row fluid css={{ borderBottom: "1px solid $mauve8" }}>
<Box css={{ width: "50%", borderRight: "1px solid $mauve8" }}>
<LogBox title="From Log" logs={[]} clearLog={() => {}} />
<LogBox
title="From Log"
logs={snap.transactionLogs}
clearLog={() => (state.transactionLogs = [])}
/>
</Box>
<Box css={{ width: "50%" }}>
<LogBox title="To Log" logs={[]} clearLog={() => {}} />

View File

@@ -8,6 +8,7 @@ import { saveFile } from "./saveFile";
import { syncToGist } from "./syncToGist";
import { updateEditorSettings } from "./updateEditorSettings";
import { downloadAsZip } from "./downloadAsZip";
import { sendTransaction } from "./sendTransaction";
export {
addFaucetAccount,
@@ -19,5 +20,6 @@ export {
saveFile,
syncToGist,
updateEditorSettings,
downloadAsZip
downloadAsZip,
sendTransaction
};

View File

@@ -0,0 +1,50 @@
import { derive, sign } from "xrpl-accountlib";
import state from '..'
import type { IAccount } from "..";
interface TransactionOptions {
TransactionType: string,
Account?: string,
Fee?: string,
Destination?: string
[index: string]: any
}
export const sendTransaction = async (account: IAccount, txOptions: TransactionOptions) => {
if (!state.client) throw Error('XRPL client not initalized')
const { Fee = "1000", ...opts } = txOptions
const tx: TransactionOptions = {
Account: account.address,
Sequence: account.sequence, // auto-fillable
Fee, // auto-fillable
...opts
};
const signedAccount = derive.familySeed(account.secret);
const { signedTransaction } = sign(tx, signedAccount);
try {
const response = await state.client.send({
command: "submit",
tx_blob: signedTransaction,
});
console.log(response)
if (response.engine_result === "tesSUCCESS") {
state.transactionLogs.push({
type: 'success',
message: `Transaction success [${response.engine_result}]: ${response.engine_result_message}`
})
} else {
state.transactionLogs.push({
type: "error",
message: `[${response.error || response.engine_result}] ${response.error_exception || response.engine_result_message}`,
});
}
} catch (err) {
console.log(err);
state.transactionLogs.push({
type: "error",
message: "Something went wrong!",
});
}
};

View File

@@ -49,6 +49,7 @@ export interface IState {
compiling: boolean;
logs: ILog[];
deployLogs: ILog[];
transactionLogs: ILog[];
editorCtx?: typeof monaco.editor;
editorSettings: {
tabSize: number;
@@ -70,6 +71,7 @@ let initialState: IState = {
compiling: false,
logs: [],
deployLogs: [],
transactionLogs: [],
editorCtx: undefined,
gistId: undefined,
gistOwner: undefined,

View File

@@ -51,7 +51,7 @@ export const {
primary: "$plum",
white: "white",
black: "black",
'deep': 'rgb(248, 248, 248)'
'deep': 'rgb(244, 244, 244)'
},
fonts: {
body: 'Work Sans, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", sans-serif',

View File

@@ -0,0 +1,36 @@
// From https://runkit.com/wietsewind/get-gh-xrpl-tx-types
export const getTransactionTypes = async () => {
const dirList: any[] = await fetch(
"https://api.github.com/repos/ripple/xrpl-dev-portal/contents/content/references/protocol-reference/transactions/transaction-types"
).then(r => r.json());
const relevantFiles = dirList.filter(r => r.name.match(/^[a-zA-Z]+\.md$/));
return Promise.all(
relevantFiles.map(async f => {
const source = await fetch(f.download_url).then(r => r.text());
return {
transactionType: source.match(/^# ([a-zA-Z]+)/gm)?.[0].slice(2),
docLink: "https://xrpl.org/" + f.name.split(".")[0] + ".html",
codeSamples: source
.split(`\n`)
.join(" ")
.match(/```.+?```/gm)
?.map(s =>
s
.split("```")[1]
.trim()
.replace(/^json[\n]*/gm, "")
)
.map(s => s.replace(/,[ \t\n\\t\\n]*}$/, "}"))
.map(s => {
try {
return JSON.parse(s);
} catch (e) {
return s;
}
}),
};
})
);
};

View File

@@ -50,7 +50,7 @@
dependencies:
regenerator-runtime "^0.13.4"
"@babel/runtime@^7.12.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.7":
"@babel/runtime@^7.12.0", "@babel/runtime@^7.12.5", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.2", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.7.tgz#03ff99f64106588c9c403c6ecb8c3bafbbdff1fa"
integrity sha512-9E9FJowqAsytyOY6LG+1KuueckRL+aQW+mKvXRXnuFGyRAyepJPmEo9vgMfXUA6O9u3IeEdv9MAkppFcaQwogQ==
@@ -1244,7 +1244,7 @@ before-after-hook@^2.2.0:
resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.2.2.tgz#a6e8ca41028d90ee2c24222f201c90956091613e"
integrity sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ==
big-integer@^1.6.48, big-integer@latest:
big-integer@^1.6.16, big-integer@^1.6.48, big-integer@latest:
version "1.6.51"
resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.51.tgz#0df92a5d9880560d3ff2d5fd20245c889d130686"
integrity sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==
@@ -1334,6 +1334,20 @@ braces@^3.0.1, braces@~3.0.2:
dependencies:
fill-range "^7.0.1"
broadcast-channel@^3.4.1:
version "3.7.0"
resolved "https://registry.yarnpkg.com/broadcast-channel/-/broadcast-channel-3.7.0.tgz#2dfa5c7b4289547ac3f6705f9c00af8723889937"
integrity sha512-cIAKJXAxGJceNZGTZSBzMxzyOn72cVgPnKx4dc6LRjQgbaJUQqhy5rzL3zbMxkMWsGKkv2hSFkPRMEXfoMZ2Mg==
dependencies:
"@babel/runtime" "^7.7.2"
detect-node "^2.1.0"
js-sha3 "0.8.0"
microseconds "0.2.0"
nano-time "1.0.0"
oblivious-set "1.0.0"
rimraf "3.0.2"
unload "2.2.0"
brorand@^1.0.1, brorand@^1.0.5, brorand@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f"
@@ -1792,6 +1806,11 @@ detect-node-es@^1.1.0:
resolved "https://registry.yarnpkg.com/detect-node-es/-/detect-node-es-1.1.0.tgz#163acdf643330caa0b4cd7c21e7ee7755d6fa493"
integrity sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==
detect-node@^2.0.4, detect-node@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1"
integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==
diffie-hellman@^5.0.0:
version "5.0.3"
resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875"
@@ -2847,6 +2866,11 @@ jose@^4.1.0, jose@^4.1.2:
resolved "https://registry.yarnpkg.com/jose/-/jose-4.1.2.tgz#04ed5173b0388a7c264c24eeb9810b31fe54bd77"
integrity sha512-1X2Lfm7myqavybkbgUyao/ocdCA9LPq0J60Miguasy7szHjViMkGadJ6Kx9WyWClgyTYQ7JPBGQ/fXuzqeZyTQ==
js-sha3@0.8.0:
version "0.8.0"
resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840"
integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==
"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
@@ -3084,6 +3108,14 @@ make-dir@^3.0.2:
dependencies:
semver "^6.0.0"
match-sorter@^6.0.2:
version "6.3.1"
resolved "https://registry.yarnpkg.com/match-sorter/-/match-sorter-6.3.1.tgz#98cc37fda756093424ddf3cbc62bfe9c75b92bda"
integrity sha512-mxybbo3pPNuA+ZuCUhm5bwNkXrJTbsk5VWbR5wiwz/GC6LIiegBGn2w3O08UG/jdbYLinw51fSQ5xNU1U3MgBw==
dependencies:
"@babel/runtime" "^7.12.5"
remove-accents "0.4.2"
md5.js@^1.3.4:
version "1.3.5"
resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f"
@@ -3121,6 +3153,11 @@ micromatch@^4.0.2, micromatch@^4.0.4:
braces "^3.0.1"
picomatch "^2.2.3"
microseconds@0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/microseconds/-/microseconds-0.2.0.tgz#233b25f50c62a65d861f978a4a4f8ec18797dc39"
integrity sha512-n7DHHMjR1avBbSpsTBj6fmMGh2AGrifVV4e+WYc3Q9lO+xnSZ3NyhcBND3vzzatt05LFhoKFRxrIyklmLlUtyA==
miller-rabin@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d"
@@ -3176,6 +3213,13 @@ nan@^2.13.2:
resolved "https://registry.yarnpkg.com/nan/-/nan-2.15.0.tgz#3f34a473ff18e15c1b5626b62903b5ad6e665fee"
integrity sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==
nano-time@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/nano-time/-/nano-time-1.0.0.tgz#b0554f69ad89e22d0907f7a12b0993a5d96137ef"
integrity sha1-sFVPaa2J4i0JB/ehKwmTpdlhN+8=
dependencies:
big-integer "^1.6.16"
nanoid@^3.1.23:
version "3.1.30"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.30.tgz#63f93cc548d2a113dc5dfbc63bfa09e2b9b64362"
@@ -3399,6 +3443,11 @@ object.values@^1.1.4, object.values@^1.1.5:
define-properties "^1.1.3"
es-abstract "^1.19.1"
oblivious-set@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/oblivious-set/-/oblivious-set-1.0.0.tgz#c8316f2c2fb6ff7b11b6158db3234c49f733c566"
integrity sha512-z+pI07qxo4c2CulUHCDf9lcqDlMSo72N/4rLUpRXf6fu+q8vjt8y0xS+Tlf8NTJDdTXHbdeO1n3MlbctwEoXZw==
octokit@^1.7.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/octokit/-/octokit-1.7.0.tgz#b98a663ecba951a35428de75786fb8e2669e1467"
@@ -3818,6 +3867,15 @@ react-new-window@^0.2.1:
dependencies:
prop-types "^15.7.2"
react-query@^3.34.7:
version "3.34.7"
resolved "https://registry.yarnpkg.com/react-query/-/react-query-3.34.7.tgz#e3d71318f510ea354794cd188b351bb57f577cb9"
integrity sha512-Q8+H2DgpoZdGUpwW2Z9WAbSrIE+yOdZiCUokHjlniOOmlcsfqNLgvHF5i7rtuCmlw3hv5OAhtpS7e97/DvgpWw==
dependencies:
"@babel/runtime" "^7.5.5"
broadcast-channel "^3.4.1"
match-sorter "^6.0.2"
react-refresh@0.8.3:
version "0.8.3"
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.8.3.tgz#721d4657672d400c5e3c75d063c4a85fb2d5d68f"
@@ -3952,6 +4010,11 @@ regexpp@^3.1.0:
resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2"
integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==
remove-accents@0.4.2:
version "0.4.2"
resolved "https://registry.yarnpkg.com/remove-accents/-/remove-accents-0.4.2.tgz#0a43d3aaae1e80db919e07ae254b285d9e1c7bb5"
integrity sha1-CkPTqq4egNuRngeuJUsoXZ4ce7U=
require-from-string@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909"
@@ -3983,6 +4046,13 @@ reusify@^1.0.4:
resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76"
integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==
rimraf@3.0.2, rimraf@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a"
integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==
dependencies:
glob "^7.1.3"
rimraf@^2.6.3:
version "2.7.1"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec"
@@ -3990,13 +4060,6 @@ rimraf@^2.6.3:
dependencies:
glob "^7.1.3"
rimraf@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a"
integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==
dependencies:
glob "^7.1.3"
ripemd160@^2.0.0, ripemd160@^2.0.1:
version "2.0.2"
resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c"
@@ -4606,6 +4669,14 @@ universalify@^0.1.0:
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==
unload@2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/unload/-/unload-2.2.0.tgz#ccc88fdcad345faa06a92039ec0f80b488880ef7"
integrity sha512-B60uB5TNBLtN6/LsgAf3udH9saB5p7gqJwcFfbOEZ8BcBHnGwCf6G/TGiEqkRAxX7zAFIUtzdrXQSdL3Q/wqNA==
dependencies:
"@babel/runtime" "^7.6.2"
detect-node "^2.0.4"
unpipe@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"