diff --git a/README.md b/README.md index de85243..75d8da5 100644 --- a/README.md +++ b/README.md @@ -74,6 +74,12 @@ In order to work on the Demo app, you need to compile the JS SDK (like above) as $ npm run build --workspace=ui/lib ``` +If you already had a build, you may need to run this command to be able to build the workspaces: + +```sh +$ npm run clean +``` + Then you are ready to contribute! To run the demo app in development mode, do the following: diff --git a/package.json b/package.json index 8f21392..9d4337a 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "scripts": { "format": "prettier -w ui && prettier -w sdk", "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", - "clean": "rm -rf js-dist", + "clean": "find . -name 'dist' -type d -exec rm -rf {} +", "build": "bash build-script.sh" }, "engines": { diff --git a/ui/app/src/CreatePage.tsx b/ui/app/src/CreatePage.tsx index 46ac068..3ff1d45 100644 --- a/ui/app/src/CreatePage.tsx +++ b/ui/app/src/CreatePage.tsx @@ -72,12 +72,13 @@ const StreamPage = () => {
} + productName={"simulation"} registerStream={addStreams} renderReasonCode={renderReasonCode} handleTransactionStatus={handleTransactionStatus} - tokenList={tokenList} - cart={} /> {/* CreateStream callback */}
diff --git a/ui/app/src/StreamPage.tsx b/ui/app/src/StreamPage.tsx index da911ab..6271061 100644 --- a/ui/app/src/StreamPage.tsx +++ b/ui/app/src/StreamPage.tsx @@ -6,9 +6,9 @@ import { ConnectButton } from "@rainbow-me/rainbowkit"; import "./styles.css"; import StreamManager, { Stream } from "@apeworx/apepay"; import { - CancelStream, UpdateStream, StreamStatus, + CancelStream, } from "@apeworx/apepay-react"; import { usePublicClient, @@ -80,13 +80,13 @@ const StreamPage = () => { }, [SM, address, walletClient]); const [streamInfo, setStreamInfo] = useState({ + token: null as string | null, amountPerSecond: null as bigint | null, + maxStreamLife: null as bigint | null, fundedAmount: null as bigint | null, + startTime: null as bigint | null, lastPull: null as bigint | null, - maxStreamLife: null as bigint | null, reason: null as Uint8Array | null, - startTime: null as bigint | null, - token: null as string | null, }); // Get info about your stream @@ -96,13 +96,13 @@ const StreamPage = () => { .streamInfo() .then((info) => { setStreamInfo({ + token: info.token, amountPerSecond: info.amount_per_second, + maxStreamLife: info.max_stream_life, fundedAmount: info.funded_amount, + startTime: info.start_time, lastPull: info.last_pull, - maxStreamLife: info.max_stream_life, reason: info.reason, - startTime: info.start_time, - token: info.token, }); }) .catch((error) => { diff --git a/ui/app/src/config.ts b/ui/app/src/config.ts index 513cf34..9dcd4a5 100644 --- a/ui/app/src/config.ts +++ b/ui/app/src/config.ts @@ -1,7 +1,7 @@ // Override this config in your downstream implementations as needed const config = { - fromBlock: 4615000, + fromBlock: 4900000, streamManagerAddress: "0x3543Faeeddb7bAbCbBB216B3627f9c5E0C39CE41", tokens: [ { diff --git a/ui/lib/CreateStream.tsx b/ui/lib/CreateStream.tsx index 87ca2c0..80e970a 100644 --- a/ui/lib/CreateStream.tsx +++ b/ui/lib/CreateStream.tsx @@ -10,6 +10,7 @@ import { useContractWrite, useWaitForTransaction, useNetwork, + useContractRead, } from "wagmi"; import { fetchBalance } from "@wagmi/core"; import StreamManager, { Stream } from "@apeworx/apepay"; @@ -23,6 +24,7 @@ export interface CreateStreamProps { tokenList: TokenInfo[]; amountPerSecond: bigint; cart?: ReactNode; + productName?: string; registerStream: (stream: Stream) => void; renderReasonCode: () => Promise; handleTransactionStatus: ( @@ -246,12 +248,60 @@ const CreateStream = (props: CreateStreamProps) => { } }, [props.tokenList, targetChainId]); + const [isAllowanceSufficient, setIsAllowanceSufficient] = + useState(false); + + // ABI used to fetch the current user allowance + const erc20ABI = [ + { + constant: true, + inputs: [ + { name: "_owner", type: "address" }, + { name: "_spender", type: "address" }, + ], + name: "allowance", + outputs: [{ name: "", type: "uint256" }], + type: "function", + }, + ]; + + // Fetch current user allowance + const { data: allowanceData } = useContractRead({ + address: selectedToken?.address as Address, + functionName: "allowance", + abi: erc20ABI, + args: [address, props.streamManagerAddress], + watch: true, + onError(error) { + console.log("Error fetching allowance", error); + }, + onSettled(data, error) { + console.log("Allowance settled", { data, error }); + }, + }); + + useEffect(() => { + // Check if allowance data is available and update allowance state + if (allowanceData !== null && allowanceData !== undefined) { + const fetchedAllowance = Number(allowanceData.toString()); + + // Check if the fetched allowance is sufficient for the transaction cost + if (txCost !== undefined) { + setIsAllowanceSufficient(fetchedAllowance >= txCost); + } + } + }, [allowanceData, txCost]); + // Select the payment token among tokens with the same chainID const Step1 = () => { return (
{props.cart && props.cart}
+
+ {" "} + Select a token to pay for your {props.productName || "Stream"}{" "} +