Skip to content

Commit

Permalink
Merge pull request #34 from valory-xyz/resume-funding
Browse files Browse the repository at this point in the history
Resume funding
  • Loading branch information
truemiller authored Mar 8, 2024
2 parents 0cb5301 + 11240e1 commit 51af489
Show file tree
Hide file tree
Showing 29 changed files with 536 additions and 306 deletions.
4 changes: 2 additions & 2 deletions frontend/client/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,11 @@ export type UpdateServicePayload = {
};

export type DeleteServicesPayload = {
hashes: Array<ServiceHash>;
hashes: ServiceHash[];
};

export type DeleteServicesResponse = {
hashes: Array<ServiceHash>;
hashes: ServiceHash[];
};

export type AppInfo = {
Expand Down
6 changes: 0 additions & 6 deletions frontend/components/Layout/Navbar/Navbar.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
import { Flex } from 'antd';
import { SettingsButton } from './SettingsButton';
import { NotificationButton } from './NotificationButton';
import Image from 'next/image';

export const Navbar = () => {
return (
<Flex vertical={false} justify="space-between" style={{ minWidth: '100%' }}>
<Image src="/olas-logo.png" alt="" width={100} height={25} />
<Flex gap={4}>
<NotificationButton disabled />
<SettingsButton disabled />
</Flex>
</Flex>
);
};
4 changes: 2 additions & 2 deletions frontend/components/Marketplace/Marketplace.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Flex } from 'antd';
import { MarketplaceItemCard } from './MarketplaceItemCard';
import { useMemo } from 'react';
import { useMarketplace } from '@/hooks';
import { useServiceTemplates } from '@/hooks';

export const Marketplace = () => {
const { getServiceTemplates } = useMarketplace();
const { getServiceTemplates } = useServiceTemplates();

const serviceTemplates = useMemo(
() => getServiceTemplates(),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { copyToClipboard } from '@/common-util/copyToClipboard';
import { useModals } from '@/hooks';
import { Address, AddressBooleanRecord } from '@/types';
import { Address, SpawnData } from '@/types';
import { Button, Flex, Typography, message } from 'antd';
import {
Dispatch,
Expand All @@ -24,7 +24,7 @@ type FundRequirementProps = {
rpc: string,
contractAddress?: Address,
) => Promise<number>;
setReceivedFunds: Dispatch<SetStateAction<AddressBooleanRecord>>;
setSpawnData: Dispatch<SetStateAction<SpawnData>>;
};

/**
Expand All @@ -41,7 +41,7 @@ export const FundRequirement = ({
hasReceivedFunds,
isErc20,
getBalance,
setReceivedFunds,
setSpawnData,
}: FundRequirementProps) => {
const { qrModalOpen } = useModals();

Expand Down Expand Up @@ -77,11 +77,36 @@ export const FundRequirement = ({
.then((balance: number) => {
if (balance >= requirement) {
setIsPollingBalance(false);
setReceivedFunds((prev: AddressBooleanRecord) => ({
...prev,
[address]: true,
}));
message.success(`Funded ${address}`);
setSpawnData((prev: SpawnData) => {
// update agent fund requirements
if (prev.agentFundRequirements[address]) {
return {
...prev,
agentFundRequirements: {
...prev.agentFundRequirements,
[address]: {
...prev.agentFundRequirements[address],
received: true,
},
},
};
}
// update master wallet fund requirements
if (prev.masterWalletFundRequirements[address]) {
return {
...prev,
masterWalletFundRequirements: {
...prev.masterWalletFundRequirements,
[address]: {
...prev.masterWalletFundRequirements[address],
received: true,
},
},
};
}
// do nothing
return prev;
});
}
})
.catch(() => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Dispatch, SetStateAction } from 'react';
import { FundRequirement } from './FundRequirement';
import { Address, AddressBooleanRecord } from '@/types';
import EthersService from '@/service/Ethers';
import { Address, SpawnData } from '@/types';
import { EthersService } from '@/service';

type FundRequirementERC20Props = {
address: Address;
Expand All @@ -10,7 +10,7 @@ type FundRequirementERC20Props = {
symbol: string;
contractAddress?: Address;
hasReceivedFunds: boolean;
setReceivedFunds: Dispatch<SetStateAction<AddressBooleanRecord>>;
setSpawnData: Dispatch<SetStateAction<SpawnData>>;
};

export const FundRequirementERC20 = (props: FundRequirementERC20Props) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { Dispatch, SetStateAction } from 'react';
import { FundRequirement } from './FundRequirement';
import { Address, AddressBooleanRecord } from '@/types';
import EthersService from '@/service/Ethers';
import { Address, SpawnData } from '@/types';
import { EthersService } from '@/service';

type FundRequirementETHProps = {
address: Address;
symbol: string;
requirement: number;
rpc: string;
hasReceivedFunds: boolean;
setReceivedFunds: Dispatch<SetStateAction<AddressBooleanRecord>>;
setSpawnData: Dispatch<SetStateAction<SpawnData>>;
};

export const FundRequirementETH = (props: FundRequirementETHProps) => {
Expand Down
47 changes: 21 additions & 26 deletions frontend/components/Spawn/Funding/Funding.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
import { COLOR } from '@/constants';
import { SpawnScreen } from '@/enums';
import { useSpawn } from '@/hooks';
import { Address, AddressNumberRecord } from '@/types';
import { AddressBooleanRecord } from '@/types';
import { TimelineItemProps, Flex, Typography, Timeline } from 'antd';
import { Address, FundingRecord, SpawnData } from '@/types';
import { TimelineItemProps, Flex, Typography, Timeline, theme } from 'antd';
import { isEmpty } from 'lodash';
import {
useState,
useMemo,
useEffect,
SetStateAction,
Expand All @@ -15,7 +12,7 @@ import {
} from 'react';

type FundRequirementComponentProps = {
setReceivedFunds: Dispatch<SetStateAction<AddressBooleanRecord>>;
setSpawnData: Dispatch<SetStateAction<SpawnData>>;
rpc: string;
address: Address;
requirement: number;
Expand All @@ -25,7 +22,7 @@ type FundRequirementComponentProps = {
};

type FundingProps = {
fundRequirements: AddressNumberRecord;
fundRequirements: FundingRecord;
FundRequirementComponent: (
props: FundRequirementComponentProps,
) => ReactElement;
Expand All @@ -43,54 +40,52 @@ export const Funding = ({
symbol,
contractAddress,
}: FundingProps) => {
const { setSpawnData, rpc } = useSpawn();

const [receivedFunds, setReceivedFunds] = useState<AddressBooleanRecord>({
...(Object.keys(fundRequirements) as Address[]).reduce(
(acc: AddressBooleanRecord, address: Address) => {
acc[address] = false;
return acc;
},
{},
),
});
const {
setSpawnData,
spawnData: { rpc },
} = useSpawn();
const { token } = theme.useToken();

const timelineItems: TimelineItemProps[] = useMemo(
() =>
(Object.keys(fundRequirements) as Address[]).map((address) => {
const { required, received } = fundRequirements[address];
return {
children: (
<FundRequirementComponent
setReceivedFunds={setReceivedFunds}
setSpawnData={setSpawnData}
address={address}
requirement={fundRequirements[address]}
requirement={required}
symbol={symbol}
hasReceivedFunds={receivedFunds[address]}
hasReceivedFunds={received}
contractAddress={contractAddress}
rpc={rpc}
/>
),
color: receivedFunds[address] ? COLOR.GREEN_2 : COLOR.RED,
color: received ? token.green : token.red,
};
}) as TimelineItemProps[],
[
FundRequirementComponent,
contractAddress,
fundRequirements,
receivedFunds,
rpc,
setSpawnData,
symbol,
token.green,
token.red,
],
);

const hasSentAllFunds = useMemo(() => {
if (isEmpty(fundRequirements)) return false;
return (Object.keys(receivedFunds) as Address[]).reduce(
(acc: boolean, address) => acc && receivedFunds[address],
return (Object.keys(fundRequirements) as Address[]).reduce(
(acc: boolean, address) => acc && fundRequirements[address].received,
true,
);
}, [fundRequirements, receivedFunds]);
}, [fundRequirements]);

// if all funds have been sent, move to next page
useEffect(() => {
hasSentAllFunds && setSpawnData((prev) => ({ ...prev, screen: nextPage }));
}, [hasSentAllFunds, nextPage, setSpawnData]);
Expand Down
50 changes: 47 additions & 3 deletions frontend/components/Spawn/SpawnAgentFunding.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,61 @@
import { Funding } from './Funding/Funding';
import { SpawnScreen } from '@/enums';
import { FundRequirementETH } from './Funding/FundRequirement/FundRequirementETH';
import { useSpawn } from '@/hooks';
import { useAppInfo, useSpawn } from '@/hooks';
import { Spin } from 'antd';
import { useState, useEffect } from 'react';
import MulticallService from '@/service/Multicall';
import { Address, AddressNumberRecord } from '@/types';

type SpawnAgentFundingProps = {
nextPage: SpawnScreen;
};

export const SpawnAgentFunding = (props: SpawnAgentFundingProps) => {
const { agentFundRequirements: fundRequirements } = useSpawn();
const {
setSpawnData,
spawnData: { rpc, agentFundRequirements },
} = useSpawn();
const { userPublicKey } = useAppInfo();
const [isInitialLoaded, setIsInitialLoaded] = useState(false);

useEffect(() => {
if (!(!isInitialLoaded && userPublicKey)) return;
const agentAddresses = Object.keys(agentFundRequirements) as Address[];
MulticallService.getEthBalances(agentAddresses, rpc).then(
(balances: AddressNumberRecord) => {
setSpawnData((prev) => ({
...prev,
agentFundRequirements: agentAddresses.reduce(
(acc, address) => ({
...acc,
[address]: {
...agentFundRequirements[address],
received: balances[address] > 1,
},
}),
{},
),
}));
setIsInitialLoaded(true);
},
);
}, [
agentFundRequirements,
isInitialLoaded,
rpc,
setSpawnData,
userPublicKey,
]);

// if not inital loaded, show loader
if (agentFundRequirements === undefined || !isInitialLoaded) {
return <Spin />;
}

return (
<Funding
fundRequirements={fundRequirements}
fundRequirements={agentFundRequirements}
statement="Please fund the agent wallets to continue."
symbol={'XDAI'} // hardcoded while only trader is available
FundRequirementComponent={FundRequirementETH}
Expand Down
7 changes: 6 additions & 1 deletion frontend/components/Spawn/SpawnError.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useSpawn } from '@/hooks';
import { Button, Flex, Typography } from 'antd';
import { useRouter } from 'next/router';

Expand All @@ -6,11 +7,15 @@ type SpawnErrorProps = {
};

export const SpawnError = ({ message }: SpawnErrorProps) => {
const { resetSpawn } = useSpawn();
const router = useRouter();
return (
<Flex vertical justify="center" align="center">
<Typography.Text>{message}</Typography.Text>
<Button type="primary" onClick={() => router.push('/')}>
<Button
type="primary"
onClick={() => router.push('/').finally(resetSpawn)}
>
Back to Home
</Button>
</Flex>
Expand Down
Loading

0 comments on commit 51af489

Please sign in to comment.