diff --git a/web/.eslintrc.yml b/web/.eslintrc.yml index d5a5b21..0906aff 100644 --- a/web/.eslintrc.yml +++ b/web/.eslintrc.yml @@ -26,6 +26,6 @@ rules: semi: - error - always - @typescript-eslint/no-explicit-any: "off" + typescript-eslint/no-explicit-any: "off" react/react-in-jsx-scope: "off" react/no-unescaped-entities: "off" diff --git a/web/package.json b/web/package.json index 30b50db..56ca008 100644 --- a/web/package.json +++ b/web/package.json @@ -11,7 +11,7 @@ "css": "npx tailwindcss -i ./src/style/app.scss -o ./src/style/app.css --watch" }, "dependencies": { - "@akashnetwork/akashjs": "^0.4.7", + "@akashnetwork/akashjs": "^0.4.11", "@cosmjs/launchpad": "^0.27.1", "@cosmjs/proto-signing": "0.25.4", "@craco/craco": "^6.4.4", @@ -92,4 +92,4 @@ ] }, "typings": "./src/react-app-env.d.ts" -} +} \ No newline at end of file diff --git a/web/src/_helpers/async-utils.ts b/web/src/_helpers/async-utils.ts new file mode 100644 index 0000000..632934c --- /dev/null +++ b/web/src/_helpers/async-utils.ts @@ -0,0 +1,66 @@ +type AsyncFunction = (...params: any[]) => Promise; +type AsyncMapFunction = (elem: T, index: number, array: T[]) => Promise; +type ErrorHandler = (e: any) => void; + +function noop(result: T) { + return result; +} + +export async function asyncForEach(arr: Array, callback: AsyncMapFunction) { + return asyncMap(arr, callback).then(noop); +} + +export async function asyncMap(arr: Array, callback: AsyncMapFunction) { + return Promise.all(arr.map(callback)); +} + +/** + * Wrapper for setTimeout that returns a promise. + * + * @param timeout The delay in milliseconds + * @param action The function to call after the delay + * + * @returns Promise that resolves after the delay + */ +export function schedule(timeout: number, action: TFn) { + return new Promise>((resolve, reject) => { + const fire = () => action().then(resolve, reject); + setTimeout(fire, timeout); + }); +} + +/** + * Returns a function that will accept an error, call the notify function + * with that error, and then schedule a retry using the provided function. + * + * @param fn The function to call after the delay + * @param delay The delay between catch the error and retrying + * @param notify A function to pass the captured error too + * + * @returns A function suitable for use as an error handler + */ +function retryHandler(fn: any, delay: number, notify: ErrorHandler) { + const attempt = () => fn(); + + return (e: any) => { + notify(e); + return schedule(delay, attempt); + }; +} + +/** + * Schedule retries for a function that returns a promise. + * + * @param attempt Function that returns a promise + * @param delays Array of delays between retries + * @param notify Function to call with the error (optional) + * + * @returns New that will only fail if all retries fail + */ +export function retry(attempt: any, delays: number[], notify = noop) { + const addRetry = (promise: Promise, delay: number) => ( + promise.catch(retryHandler(attempt, delay, notify)) + ); + + return delays.reduce(addRetry, attempt()); +} diff --git a/web/src/_helpers/sandbox-chain.ts b/web/src/_helpers/sandbox-chain.ts new file mode 100644 index 0000000..d5c4370 --- /dev/null +++ b/web/src/_helpers/sandbox-chain.ts @@ -0,0 +1,41 @@ +export default { + 'rpc': 'https://rpc.sandbox-01.aksh.pw', + 'rest': 'https://api.sandbox-01.aksh.pw', + 'chainId': 'sandbox-01', + 'chainName': 'Akash Sandbox', + 'chainSymbolImageUrl': 'https://raw.githubusercontent.com/chainapsis/keplr-chain-registry/main/images/akashnet/chain.png', + 'stakeCurrency': { + 'coinDenom': 'AKT', + 'coinMinimalDenom': 'uakt', + 'coinDecimals': 6, + 'coinGeckoId': 'akash-network' + }, + 'bip44': { + 'coinType': 118 + }, + 'bech32Config': { + 'bech32PrefixAccAddr': 'akash', + 'bech32PrefixAccPub': 'akashpub', + 'bech32PrefixValAddr': 'akashvaloper', + 'bech32PrefixValPub': 'akashvaloperpub', + 'bech32PrefixConsAddr': 'akashvalcons', + 'bech32PrefixConsPub': 'akashvalconspub' + }, + 'currencies': [ + { + 'coinDenom': 'AKT', + 'coinMinimalDenom': 'uakt', + 'coinDecimals': 6, + 'coinGeckoId': 'akash-network' + } + ], + 'feeCurrencies': [ + { + 'coinDenom': 'AKT', + 'coinMinimalDenom': 'uakt', + 'coinDecimals': 6, + 'coinGeckoId': 'akash-network' + } + ], + 'features': [] +}; \ No newline at end of file diff --git a/web/src/_helpers/chain.ts b/web/src/_helpers/testnet-chain.ts similarity index 100% rename from web/src/_helpers/chain.ts rename to web/src/_helpers/testnet-chain.ts diff --git a/web/src/api/rpc/beta3/deployments.tsx b/web/src/api/rpc/beta3/deployments.tsx index 1aea238..8237e48 100644 --- a/web/src/api/rpc/beta3/deployments.tsx +++ b/web/src/api/rpc/beta3/deployments.tsx @@ -315,6 +315,8 @@ export async function createDeployment( }), }; + console.log(msg); + const tx = await client.signAndBroadcast(account.address, [msg], 'auto', 'Creating the deployment'); return { diff --git a/web/src/components/Deployment/DeploymentActionButton.tsx b/web/src/components/Deployment/DeploymentActionButton.tsx index 6c9c3b8..f3f4de3 100644 --- a/web/src/components/Deployment/DeploymentActionButton.tsx +++ b/web/src/components/Deployment/DeploymentActionButton.tsx @@ -5,6 +5,7 @@ type DeploymentActionButtonProps = { tooltipTitle: string; tooltip: React.ReactNode; linkTo: string; + condition: boolean; children: React.ReactNode; } & ButtonProps; @@ -21,6 +22,7 @@ const DeploymentActionButton: React.FC = (props) => tooltip, linkTo, children, + condition, ...rest } = props; @@ -29,6 +31,7 @@ const DeploymentActionButton: React.FC = (props) => title={tooltipTitle} to={linkTo} className="grow" + condition={condition} >