diff --git a/examples/rental-model/advanced/deposit/funder.ts b/examples/rental-model/advanced/deposit/funder.ts index 7b9898955..61baa0b40 100644 --- a/examples/rental-model/advanced/deposit/funder.ts +++ b/examples/rental-model/advanced/deposit/funder.ts @@ -8,6 +8,7 @@ import config from "./config.js"; const abiGlm = JSON.parse(await readFile("./contracts/glmAbi.json", "utf8")); const abiLock = JSON.parse(await readFile("./contracts/lockAbi.json", "utf8")); const funderAccount = privateKeyToAccount(config.funder.privateKey); +const nonce = Math.floor(Math.random() * config.funder.nonceSpace); // walletClient for writeContract functions const walletClient = createWalletClient({ @@ -31,15 +32,15 @@ const GLM_CONTRACT = { abi: abiGlm, }; -const nonce = Math.floor(Math.random() * config.funder.nonceSpace); - async function createAllowance({ budget, fee }: { budget: number; fee: number }) { const amountWei = parseEther(`${budget}`); const flatFeeAmountWei = parseEther(`${fee}`); const allowanceBudget = amountWei + flatFeeAmountWei; console.log( - chalk.blue(`\nCreating allowance of ${formatEther(allowanceBudget)} GLM for ${LOCK_CONTRACT.address} contract ...`), + chalk.yellow( + `\nCreating allowance of ${formatEther(allowanceBudget)} GLM for ${LOCK_CONTRACT.address} contract ...`, + ), ); const hash = await walletClient.writeContract({ @@ -55,13 +56,13 @@ async function createAllowance({ budget, fee }: { budget: number; fee: number }) hash, }); - console.log(chalk.blue(`Allowance successfully created with Tx ${receipt.transactionHash}.`)); + console.log(chalk.yellow(`Allowance successfully created with Tx ${receipt.transactionHash}.`)); } async function checkAllowance() { const args = [config.funder.address, LOCK_CONTRACT.address]; - console.log(chalk.blue(`\nChecking allowance for ${args[1]} contract ...`)); + console.log(chalk.yellow(`\nChecking allowance for ${args[1]} contract ...`)); const allowance = await publicClient.readContract({ abi: GLM_CONTRACT.abi, @@ -70,7 +71,7 @@ async function checkAllowance() { args, }); - console.log(chalk.blue(`Allowance of ${formatEther(allowance)} GLM is set.`)); + console.log(chalk.yellow(`Allowance of ${formatEther(allowance)} GLM is set.`)); } type DepositParams = { @@ -85,11 +86,11 @@ async function createDeposit({ address, budget, fee, expirationSec }: DepositPar const args = [BigInt(nonce), address, parseEther(`${budget}`), parseEther(`${fee}`), BigInt(validToTimestamp)]; console.log( - chalk.grey( + chalk.blueBright( `\nCreating deposit of amount: ${formatEther(args[2])} GLM, flatFeeAmount: ${formatEther(args[3])} GLM, for ${(expirationSec / 3600).toFixed(2)} hours.`, ), ); - console.log(chalk.grey(`Using contract at address: ${LOCK_CONTRACT.address}.`)); + console.log(chalk.blueBright(`Using contract at address: ${LOCK_CONTRACT.address}.`)); const hash = await walletClient.writeContract({ address: LOCK_CONTRACT.address, @@ -104,7 +105,7 @@ async function createDeposit({ address, budget, fee, expirationSec }: DepositPar hash, }); - console.log(chalk.grey(`Deposit successfully created with Tx ${hash}.`)); + console.log(chalk.blueBright(`Deposit successfully created with Tx ${hash}.`)); const depositId = await getDepositID(); const depositDetails = await getDepositDetails(); @@ -125,11 +126,11 @@ async function extendDeposit({ budget, fee, expirationSec }: Partialargs[1])} GLM, flatFeeAmount: ${formatEther(args[2])} GLM, for ${(expirationSec / 3600).toFixed(2)} hours.`, ), ); - console.log(chalk.grey(`Using contract at address: ${LOCK_CONTRACT.address}.`)); + console.log(chalk.blueBright(`Using contract at address: ${LOCK_CONTRACT.address}.`)); const hash = await walletClient.writeContract({ abi: LOCK_CONTRACT.abi, @@ -144,7 +145,7 @@ async function extendDeposit({ budget, fee, expirationSec }: Partial { +async function clearAllowance() { const args = [LOCK_CONTRACT.address, BigInt(0)]; console.log(chalk.yellow(`\nClearing allowance for ${args[0]} contract ...`)); @@ -200,7 +207,7 @@ export const clearAllowance = async () => { }); console.log(chalk.yellow(`Allowance cleared with Tx ${hash}.\n`)); -}; +} export default { createAllowance, diff --git a/examples/rental-model/advanced/deposit/index.ts b/examples/rental-model/advanced/deposit/index.ts index e4e477b41..4fa0fa1dd 100644 --- a/examples/rental-model/advanced/deposit/index.ts +++ b/examples/rental-model/advanced/deposit/index.ts @@ -1,8 +1,19 @@ +/** + * In this example we demonstrate executing tasks on a golem but using funds deposited by another person. + * In this example, it is called Funder. The funder is responsible for allocating the deposit, + * which will then be used by the Spender (requestor) to create an allocation for a payment. + * + * To run the example, it is necessary to define the funder's address in the config.ts file and a private key + * that will allow depositing specific funds on the contract. + * + * In order to check if everything went correctly, the observer object logs transaction information + * in the smart contract and the script waits for confirmation on the blockchain until the deposit is closed. + */ + import funder from "./funder"; import observer from "./observer"; import { GolemNetwork, MarketOrderSpec, waitFor } from "@golem-sdk/golem-js"; import { pinoPrettyLogger } from "@golem-sdk/pino-logger"; -import chalk from "chalk"; (async () => { const glm = new GolemNetwork({ @@ -12,8 +23,7 @@ import chalk from "chalk"; try { await glm.connect(); - // const spenderAddress = glm.getIdentity().identity; TODO - const spenderAddress = "0x19ee20338a4c4bf8f6aebc79d9d3af2a01434119"; + const { identity: spenderAddress } = await glm.services.yagna.identity.getIdentity(); const budget = 1.0; const fee = 0.5; const expirationSec = 60 * 60; // 1 hour @@ -30,14 +40,15 @@ import chalk from "chalk"; // After the deposit is properly prepared, the funder can clear the allowance await funder.clearAllowance(); + // Now the Spender (requestor) can use the deposit to create an allocation const allocation = await glm.payment.createAllocation({ deposit, budget, expirationSec, }); - const { stopWatchingContractTransactions, isDepositClosed } = - await observer.startWatchingContractTransactions(spenderAddress); + // We are starting the contract transaction observations for the spender address + const observation = await observer.startWatchingContractTransactions(spenderAddress); const order1: MarketOrderSpec = { demand: { @@ -75,8 +86,8 @@ import chalk from "chalk"; await rental1 .getExeUnit() - .then((exe) => exe.run(`echo Task 1 running on ${exe.provider.name}`)) - .then((res) => console.log(chalk.inverse("\n", res.stdout))); + .then((exe) => exe.run(`echo Task 1 running on provider ${exe.provider.name} 👽`)) + .then((res) => console.log(res.stdout)); await rental1.stopAndFinalize(); @@ -84,17 +95,17 @@ import chalk from "chalk"; await rental2 .getExeUnit() - .then((exe) => exe.run(`echo Task 2 Running on ${exe.provider.name}`)) - .then((res) => console.log(chalk.inverse("\n", res.stdout))); + .then((exe) => exe.run(`echo Task 2 Running on provider ${exe.provider.name} 🤠`)) + .then((res) => console.log(res.stdout)); await rental2.stopAndFinalize(); - // Once the spender releases the allocation, the deposit will be closed - // and you will not be able to use it again. + // Once Spender releases the allocation, the deposit will be closed and cannot be used again. await glm.payment.releaseAllocation(allocation); - await waitFor(isDepositClosed); - stopWatchingContractTransactions(); + // We wait (max 2 mins) for confirmation from blockchain + await waitFor(observation.isDepositClosed, { abortSignal: AbortSignal.timeout(120_000) }); + observation.stopWatchingContractTransactions(); } catch (err) { console.error("Failed to run the example", err); } finally { diff --git a/examples/rental-model/advanced/deposit/observer.ts b/examples/rental-model/advanced/deposit/observer.ts index c57d6b83a..2957f68cc 100644 --- a/examples/rental-model/advanced/deposit/observer.ts +++ b/examples/rental-model/advanced/deposit/observer.ts @@ -19,20 +19,21 @@ async function checkIsDopositClosed(spenderAddress: Address, funderAddress: Addr abi: abiLock, data: transaction.input, }); - const functionNamePlusArgs = `${parsedMethod.functionName}(${parsedMethod.args.join(",")})`; - console.log(chalk.magenta("\ncall:", functionNamePlusArgs)); + const functionNameWithArgs = `${parsedMethod.functionName}(${parsedMethod.args.join(",")})`; + console.log(chalk.magenta("\nContract transaction log:")); + console.log(chalk.magenta("call:"), functionNameWithArgs); console.log(chalk.magenta("event:"), log["eventName"]); console.log(chalk.magenta("from:"), transaction.from); console.log(chalk.magenta("hash:"), transaction.hash, "\n"); const functionName = parsedMethod.functionName.toLowerCase(); - // if deposit is closed by spender (requestor), stop observing + // if deposit is closed by spender (requestor) if (functionName.includes("close") && transaction.from === spenderAddress) { - console.log(chalk.grey(`Deposit has been closed by spender.`)); + console.log(chalk.blueBright(`Deposit has been closed by spender.`)); return true; } - // if deposit is terminated by spender (requestor), stop observing + // if deposit is terminated by funder if (functionName === "terminatedeposit" && transaction.from === funderAddress) { - console.log(chalk.grey(`Deposit has been terminated by spender.`)); + console.log(chalk.blueBright(`Deposit has been terminated by spender.`)); return true; } } @@ -44,7 +45,7 @@ async function startWatchingContractTransactions(address: string) { const funderAddress =
config.funder.address; let isDepositClosed = false; - const stopWatchingContractTransactions = publicClient.watchEvent({ + const unwatch = publicClient.watchEvent({ onLogs: async (logs) => (isDepositClosed = await checkIsDopositClosed(spenderAddress, funderAddress, logs)), events: parseAbi([ "event DepositCreated(uint256 indexed id, address spender)", @@ -57,7 +58,7 @@ async function startWatchingContractTransactions(address: string) { address:
config.lockPaymentContract.holeskyAddress, }); return { - stopWatchingContractTransactions, + stopWatchingContractTransactions: unwatch, isDepositClosed: () => isDepositClosed, }; }