Search
Search

Transaction: HNfDccf...kAGP

Status
Succeeded
Transaction Fee
0.00099 
Deposit Value
0 
Gas Used
10 Tgas
Attached Gas
200 Tgas
Created
March 29, 2024 at 8:11:55am
Hash
HNfDccfr7XXHDmAaDutKnJ8bcYfHG31CsrEcRDGtkAGP

Actions

Called method: 'register' in contract: query…tform.near
Arguments:
{ "function_name": "index_potlock_test", "code": "\n const BASE_ACCOUNT_ID = \"potlock.near\"; // potlock base id to match all actions\n // this function helps match factories, deployed in the manner `version.ptofactory....` where version can be v1,v2,vn\n function matchVersionPattern(text) {\n const pattern = /^v\\d+\\.potfactory\\.potlock\\.near$/;\n return pattern.test(text);\n }\n\n // filter receipts in this block to make sure we're inly indexing successful actions\n const receiptStatusMap = block\n .receipts()\n .filter(\n (receipt) =>\n receipt.receiverId.endsWith(BASE_ACCOUNT_ID) &&\n (receipt.status.hasOwnProperty(\"SuccessValue\") ||\n receipt.status.hasOwnProperty(\"SuccessReceiptId\"))\n )\n .map((receipt) => receipt.receiptId);\n\n console.log(\"let us see...\", receiptStatusMap);\n\n // filter actions in this block whose receipts can be found in the list of successful receipts\n\n console.log(\"txises:\", block.transactions);\n\n // filter actions in this block whose receipts can be found in the list of successful receipts\n const matchingActions = block\n .actions()\n .filter(\n (action) =>\n action.receiverId.endsWith(BASE_ACCOUNT_ID) &&\n receiptStatusMap.includes(action.receiptId)\n );\n\n console.log(\"macthing actions rambo=====\", matchingActions);\n\n // if there are no actions matching our conditions, then we have nothing to index in this block, unto the next.\n if (!matchingActions.length) {\n console.log(\"nothin concerns us here\");\n return;\n }\n\n const created_at = new Date(\n Number(BigInt(block.header().timestampNanosec) / BigInt(1000000))\n );\n\n async function handleNewPot(\n args,\n receiverId,\n signerId,\n predecessorId,\n receiptId\n ) {\n let data = JSON.parse(args);\n console.log(\"new pot data::\", { ...data }, receiverId, signerId);\n await context.db.Account.upsert({ id: data.owner }, [\"id\"], []);\n await context.db.Account.upsert({ id: signerId }, [\"id\"], []);\n\n if (data.chef) {\n await context.db.Account.upsert({ id: data.chef }, [\"id\"], []);\n }\n\n if (data.admins) {\n for (const admin in data.admins) {\n await context.db.Account.upsert({ id: admin }, [\"id\"], []);\n let pot_admin = {\n pot_id: receiverId,\n admin_id: admin,\n };\n await context.db.PotAdmin.insert(pot_admin);\n }\n }\n\n const potObject = {\n id: receiverId,\n pot_factory_id: predecessorId,\n deployer_id: signerId,\n deployed_at: created_at,\n source_metadata: JSON.stringify(data.source_metadata),\n owner_id: data.owner,\n chef_id: data.chef,\n name: data.pot_name,\n description: data.pot_description,\n max_approved_applicants: data.max_projects,\n base_currency: \"near\",\n application_start: new Date(data.application_start_ms),\n application_end: new Date(data.application_end_ms),\n matching_round_start: new Date(data.public_round_start_ms),\n matching_round_end: new Date(data.public_round_end_ms),\n registry_provider: data.registry_provider,\n min_matching_pool_donation_amount: data.min_matching_pool_donation_amount,\n sybil_wrapper_provider: data.sybil_wrapper_provider,\n custom_sybil_checks: data.custom_sybil_checks\n ? JSON.stringify(data.custom_sybil_checks)\n : null,\n custom_min_threshold_score: data.custom_min_threshold_score,\n referral_fee_matching_pool_basis_points:\n data.referral_fee_matching_pool_basis_points,\n referral_fee_public_round_basis_points:\n data.referral_fee_public_round_basis_points,\n chef_fee_basis_points: data.chef_fee_basis_points,\n total_matching_pool: \"0\",\n total_matching_pool_usd: data.total_matching_pool_usd,\n matching_pool_balance: \"0\",\n matching_pool_donations_count: 0,\n total_public_donations: \"0\",\n total_public_donations_usd: data.total_public_donations_usd,\n public_donations_count: 0,\n cooldown_period_ms: null,\n all_paid_out: false,\n protocol_config_provider: data.protocol_config_provider,\n };\n\n await context.db.Pot.insert(potObject);\n\n let activity = {\n signer_id: signerId,\n receiver_id: receiverId,\n timestamp: created_at,\n type: \"Deploy_Pot\",\n action_result: JSON.stringify(potObject),\n tx_hash: receiptId,\n };\n\n await context.db.Activity.insert(activity);\n }\n\n async function handleNewFactory(args, receiverId, signerId, receiptId) {\n let data = JSON.parse(args);\n console.log(\"new factory data::\", { ...data }, receiverId);\n // try saving concerned accounts\n await context.db.Account.upsert({ id: data.owner }, [\"id\"], []);\n await context.db.Account.upsert(\n { id: data.protocol_fee_recipient_account },\n [\"id\"],\n []\n );\n if (data.admins) {\n for (const admin in data.admins) {\n await context.db.Account.upsert({ id: admin }, [\"id\"], []);\n let factory_admin = {\n pot_factory_id: receiverId,\n admin_id: admin,\n };\n await context.db.PotFactoryAdmin.insert(factory_admin);\n }\n }\n\n if (data.whitelisted_deployers) {\n for (const deployer in data.whitelisted_deployers) {\n await context.db.Account.upsert({ id: deployer }, [\"id\"], []);\n let factory_deployer = {\n pot_factory_id: receiverId,\n whitelisted_deployer_id: deployer,\n };\n await context.db.PotFactoryWhitelistedDeployer.insert(factory_deployer);\n }\n }\n const factory = {\n id: receiverId,\n owner_id: data.owner,\n deployed_at: created_at,\n source_metadata: JSON.stringify(data.source_metadata),\n protocol_fee_basis_points: data.protocol_fee_basis_points,\n protocol_fee_recipient_account: data.protocol_fee_recipient_account,\n require_whitelist: data.require_whitelist,\n };\n console.log(\"factory..\", factory);\n await context.db.PotFactory.insert(factory);\n }\n\n // function tracks registry contracts, where projects are registered\n async function handleRegistry(args, receiverId, signerId, receiptId) {\n let receipt = block\n .receipts()\n .filter((receipt) => receipt.receiptId == receiptId)[0];\n let data = JSON.parse(atob(receipt.status[\"SuccessValue\"]));\n console.log(\"new Registry data::\", { ...data }, receiverId);\n\n if (data.admins) {\n for (const admin in data.admins) {\n await context.db.Account.upsert({ id: data.admins[admin] }, [\"id\"], []);\n let list_admin = {\n list_id: data.id,\n admin_id: admin,\n };\n await context.db.ListAdmin.insert(list_admin);\n }\n }\n\n let regv = {\n id: data.id,\n owner_id: data.owner,\n default_registration_status: data.default_registration_status, // the first registry contract has approved as default, and the later changed through the admin set function call, which we also listen to, so it should self correct.\n name: data.name,\n description: data.description,\n cover_image_url: data.cover_image_url,\n admin_only_registrations: data.admin_only_registrations,\n tx_hash: receiptId,\n created_at: data.created_at,\n updated_at: data.updated_at,\n };\n\n await context.db.Account.upsert({ id: data.owner }, [\"id\"], []);\n\n await context.db.List.insert(regv);\n }\n\n // function tracks register function calls on the registry conract\n async function handleNewProject(args, receiverId, signerId, receiptId) {\n let data = JSON.parse(args);\n console.log(\"new Project data::\", { ...data }, receiverId);\n let receipt = block\n .receipts()\n .filter((receipt) => receipt.receiptId == receiptId)[0];\n let reg_data = JSON.parse(atob(receipt.status[\"SuccessValue\"]));\n // let array_data = Array.isArray(reg_data) ? reg_data : [reg_data]\n let project_list = [];\n let insert_data = reg_data.map((dt) => {\n project_list.push({ id: dt.registrant_id });\n return {\n id: dt.id,\n registrant_id: dt.registrant_id,\n list_id: dt.list_id,\n status: dt.status,\n submitted_at: dt.submitted_ms,\n updated_at: dt.updated_ms,\n registered_by: dt.registered_by,\n admin_notes: dt.admin_notes,\n registrant_notes: dt.registrant_notes,\n tx_hash: receiptId,\n };\n });\n await context.db.Account.upsert(project_list, [\"id\"], []);\n await context.db.Account.upsert({ id: signerId }, [\"id\"], []);\n\n await context.db.ListRegistration.insert(insert_data);\n let activity = {\n signer_id: signerId,\n receiver_id: receiverId,\n timestamp: insert_data[0].submitted_at,\n type: \"Register_Batch\",\n action_result: JSON.stringify(reg_data),\n tx_hash: receiptId,\n };\n\n await context.db.Activity.insert(activity);\n }\n\n async function handleProjectRegistrationUpdate(\n args,\n receiverId,\n signerId,\n receiptId\n ) {\n let data = JSON.parse(args);\n console.log(\"new Project data::\", { ...data }, receiverId);\n let regUpdate = {\n status: data.status,\n admin_notes: data.review_notes,\n updated_at: created_at,\n };\n\n await context.db.ListRegistration.update(\n { registrant_id: data.project_id },\n regUpdate\n );\n }\n\n async function handlePotApplication(args, receiverId, signerId, receiptId) {\n let data = JSON.parse(args);\n let receipt = block\n .receipts()\n .filter((receipt) => receipt.receiptId == receiptId)[0];\n let result = receipt.status[\"SuccessValue\"];\n if (!result) {\n return;\n }\n let appl_data = JSON.parse(atob(receipt.status[\"SuccessValue\"]));\n console.log(\"new pot application data::\", { ...data }, appl_data);\n await context.db.Account.upsert({ id: data.project_id }, [\"id\"], []);\n let application = {\n pot_id: receiverId,\n applicant_id: appl_data.project_id,\n message: appl_data.message,\n submitted_at: appl_data.submitted_at,\n status: appl_data.status,\n tx_hash: receiptId,\n };\n await context.db.PotApplication.insert(application);\n\n let activity = {\n signer_id: signerId,\n receiver_id: receiverId,\n timestamp: application.submitted_at,\n type: \"Submit_Application\",\n action_result: JSON.stringify(appl_data), // result points to the pot application created.\n tx_hash: receiptId, // should we have receipt on both action and activity?\n };\n\n await context.db.Activity.insert(activity);\n }\n\n async function handleApplicationStatusChange(\n args,\n receiverId,\n signerId,\n receiptId\n ) {\n let data = JSON.parse(args);\n console.log(\"pot application update data::\", { ...data }, receiverId);\n\n let receipt = block\n .receipts()\n .filter((receipt) => receipt.receiptId == receiptId)[0];\n let update_data = JSON.parse(atob(receipt.status[\"SuccessValue\"]));\n let appl = (\n await context.db.PotApplication.select({ applicant_id: data.project_id })\n )[0];\n\n let applicationReview = {\n application_id: appl.id,\n reviewer_id: signerId,\n notes: update_data.notes,\n status: update_data.status,\n reviewed_at: update_data.updated_at,\n tx_hash: receiptId,\n };\n let applicationUpdate = {\n current_status: update_data.status,\n last_updated_at: update_data.updated_at,\n };\n\n await context.db.PotApplicationReview.insert(applicationReview);\n await context.db.PotApplication.update({ id: appl.id }, applicationUpdate);\n }\n\n async function handleDefaultListStatusChange(\n args,\n receiverId,\n signerId,\n receiptId\n ) {\n let data = JSON.parse(args);\n console.log(\"update project data::\", { ...data }, receiverId);\n\n let listUpdate = {\n default_registration_status: data.status,\n };\n\n await context.db.List.update(\n { id: data.list_id || receiverId },\n listUpdate\n );\n }\n\n async function handleUpVoting(args, receiverId, signerId, receiptId) {\n let data = JSON.parse(args);\n console.log(\"upvote list::\", { ...data }, receiverId);\n\n let listUpVote = {\n list_id: data.list_id,\n account_id: signerId,\n created_at,\n };\n\n let activity = {\n signer_id: signerId,\n receiver_id: receiverId,\n timestamp: created_at,\n type: \"Upvote\",\n action_result: JSON.stringify(data),\n tx_hash: receiptId,\n };\n\n await context.db.List.update(\n { id: data.list_id || receiverId },\n listUpVote\n );\n await context.db.Activity.insert(activity);\n }\n\n async function handleSettingPayout(args, receiverId, signerId, receiptId) {\n let data = JSON.parse(args);\n console.log(\"set payout data::\", { ...data }, receiverId);\n let payouts = data.payouts;\n for (const payout in payouts) {\n // general question: should we register projects as accounts?\n let potPayout = {\n recipient_id: payout[\"project_id\"],\n amount: payout[\"amount\"],\n ft_id: payout[\"ft_id\"] || \"near\",\n tx_hash: receiptId,\n };\n await context.db.PotPayout.insert(potPayout);\n }\n }\n\n async function handlePayout(args, receiverId, signerId, receiptId) {\n let data = JSON.parse(args);\n data = data.payout;\n console.log(\"fulfill payout data::\", { ...data }, receiverId);\n let payout = {\n recipient_id: data.project_id,\n amount: data.amount,\n paid_at: data.paid_at || created_at,\n tx_hash: receiptId,\n };\n await context.db.PotPayout.update(\n { recipient_id: data.project_id },\n payout\n );\n }\n\n async function handlePayoutChallenge(args, receiverId, signerId, receiptId) {\n let data = JSON.parse(args);\n console.log(\"challenging payout..: \", { ...data }, receiverId);\n let created_at = new Date(\n Number(BigInt(block.header().timestampNanosec) / BigInt(1000000)) // convert to ms then date\n );\n let payoutChallenge = {\n challenger_id: signerId,\n pot_id: receiverId,\n created_at,\n message: data.reason,\n tx_hash: receiptId,\n };\n await context.db.PotPayoutChallenge.insert(payoutChallenge);\n\n let activity = {\n signer_id: signerId,\n receiver_id: receiverId,\n timestamp: created_at,\n type: \"Challenge_Payout\",\n action_result: JSON.stringify(payoutChallenge),\n tx_hash: receiptId,\n };\n\n await context.db.Activity.insert(activity);\n }\n\n async function handleListAdminRemoval(args, receiverId, signerId, receiptId) {\n let data = JSON.parse(args);\n console.log(\"removing admin...: \", { ...data }, receiverId);\n let list = await context.db.List.select({ id: data.list_id });\n\n for (const acct in data.admins) {\n await context.db.ListAdmin.delete({\n list_id: list[0].id,\n admin_id: acct,\n });\n }\n\n let activity = {\n signer_id: signerId,\n receiver_id: receiverId,\n timestamp: created_at,\n type: \"Remove_List_Admin\",\n tx_hash: receiptId,\n };\n\n await context.db.Activity.insert(activity);\n }\n\n const GECKO_URL = \"https://api.coingecko.com/api/v3\";\n function formatDate(date) {\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, \"0\");\n const day = String(date.getDate()).padStart(2, \"0\");\n\n return `${day}-${month}-${year}`;\n }\n\n // helper function to format\n function formatToNear(yoctoAmount) {\n const nearAmount = yoctoAmount / 10 ** 24;\n return nearAmount;\n }\n\n async function handleNewDonations(\n args,\n receiverId,\n signerId,\n actionName,\n receiptId\n ) {\n let donation_data;\n if (actionName == \"direct\") {\n console.log(\"calling donate on projects...\");\n let event = block\n .events()\n .filter((evt) => evt.relatedReceiptId == receiptId);\n if (!event.length) {\n return;\n }\n const event_data = event[0].rawEvent.standard;\n console.log(\"pioper..\", event_data);\n donation_data = JSON.parse(event_data).data[0].donation;\n console.log(\"DODONDAWA..\", donation_data);\n } else {\n let receipt = block\n .receipts()\n .filter((receipt) => receipt.receiptId == receiptId)[0];\n donation_data = JSON.parse(atob(receipt.status[\"SuccessValue\"]));\n }\n console.log(\"action and recv\", actionName, receiverId);\n\n console.log(\"result arg...:\", donation_data);\n let donated_at = new Date(\n donation_data.donated_at || donation_data.donated_at_ms\n );\n await context.db.Account.upsert({ id: donation_data.donor_id }, [\"id\"], []);\n let endpoint = `${GECKO_URL}/coins/${\n donation_data.ft_id || \"near\"\n }/history?date=${formatDate(donated_at)}&localization=false`;\n let unit_price;\n try {\n let response = await fetch(endpoint);\n let data = await response.json();\n unit_price = data.market_data?.current_price.usd;\n let hist_data = {\n token_id: donation_data.ft_id || \"near\",\n last_updated: created_at,\n historical_price: unit_price,\n };\n await context.db.TokenHistoricalData.upsert(\n hist_data,\n [\"token_id\"],\n [\"historical_price\"]\n );\n } catch (err) {\n console.log(\"api rate limi?::\", err);\n let historica_price = await context.db.TokenHistoricalData.select({\n token_id: donation_data.ft_id || \"near\",\n });\n unit_price = historica_price[0].historical_price;\n }\n\n let total_amount = donation_data.total_amount;\n let net_amount = donation_data.net_amount;\n if (donation_data.referrer_fee) {\n net_amount = (\n BigInt(net_amount) - BigInt(donation_data.referrer_fee)\n ).toString();\n }\n\n let totalnearAmount = formatToNear(total_amount);\n let netnearAmount = formatToNear(net_amount);\n let total_amount_usd = unit_price * totalnearAmount;\n let net_amount_usd = unit_price * netnearAmount;\n let donation = {\n donor_id: donation_data.donor_id,\n total_amount,\n total_amount_usd,\n net_amount_usd,\n net_amount,\n ft_id: donation_data.ft_id || \"near\",\n message: donation_data.message,\n donated_at,\n matching_pool: donation_data.matching_pool || false,\n recipient_id: donation_data.project_id || donation_data.recipient_id,\n protocol_fee: donation_data.protocol_fee,\n referrer_id: donation_data.referrer_id,\n referrer_fee: donation_data.referrer_fee,\n tx_hash: receiptId,\n };\n await context.db.Donation.insert(donation);\n\n if (actionName != \"direct\") {\n // update pot data such as public donations and matchingpool\n let pot = (await context.db.Pot.select({ id: receiverId }))[0];\n donation[\"pot_id\"] = pot.id;\n let potUpdate = {\n total_public_donations_usd:\n pot.total_public_donations_usd || 0 + total_amount_usd,\n total_public_donations: pot.total_public_donations || 0 + total_amount,\n };\n if (donation_data.matching_pool) {\n potUpdate[\"total_matching_pool_usd\"] =\n pot.total_matching_pool_usd || 0 + total_amount_usd;\n potUpdate[\"total_matching_pool\"] =\n pot.total_matching_pool || 0 + total_amount;\n potUpdate[\"matching_pool_donations_count\"] =\n pot.matching_pool_donations_count || 0 + 1;\n let accountUpdate = {};\n } else {\n potUpdate[\"public_donations_count\"] =\n pot.public_donations_count || 0 + 1;\n }\n await context.db.Pot.update({ id: pot.id }, potUpdate);\n }\n\n let recipient = donation_data.project_id || donation_data.recipient_id;\n\n if (recipient) {\n let acct = (await context.db.Account.select({ id: recipient }))[0];\n console.log(\"selected acct\", acct);\n let acctUpdate = {\n total_donations_usd:\n acct.total_donations_received_usd || 0 + total_amount_usd,\n donors_count: acct.donors_count || 0 + 1,\n };\n await context.db.Account.update({ id: recipient }, acctUpdate);\n }\n\n let activity = {\n signer_id: signerId,\n receiver_id: receiverId,\n timestamp: donation.donated_at,\n type:\n actionName == \"direct\"\n ? \"Donate_Direct\"\n : donation.matching_pool\n ? \"Donate_Pot_Matching_Pool\"\n : \"Donate_Pot_Public\",\n action_result: JSON.stringify(donation),\n tx_hash: receiptId,\n };\n\n await context.db.Activity.insert(activity);\n }\n\n // map through the successful actions and swittch on the methodName called for each, then call the designated handlerFunction.\n await Promise.all(\n matchingActions.flatMap((action) => {\n action.operations.map(async (operation) => {\n console.log(\"see the contents here...:,==\", operation[\"FunctionCall\"]);\n let call = operation[\"FunctionCall\"];\n if (call) {\n const args = atob(call.args); // decode function call argument\n switch (call.methodName) {\n case \"new\":\n // new can be called on a couple of things, if the recever id matches factory pattern, then it's a new factory, else if it matches the registry account id, then it's a registry contract initialization, else, it's a new pot initialization.\n matchVersionPattern(action.receiverId)\n ? await handleNewFactory(\n args,\n action.receiverId,\n action.signerId,\n action.receiptId\n )\n : await handleNewPot(\n args,\n action.receiverId,\n action.signerId,\n action.predecessorId,\n action.receiptId\n );\n break;\n // this is the callback after user applies to a certain pot, it can either be this or handle_apply\n case \"assert_can_apply_callback\":\n console.log(\"application case:\", JSON.parse(args));\n await handlePotApplication(\n args,\n action.receiverId,\n action.signerId,\n action.receiptId\n );\n break;\n case \"apply\":\n console.log(\"application case 2:\", JSON.parse(args));\n await handlePotApplication(\n args,\n action.receiverId,\n action.signerId,\n action.receiptId\n );\n break;\n\n // if function call is donate, call the handle new donations function\n case \"donate\":\n console.log(\"donatons to project incoming:\", JSON.parse(args));\n await handleNewDonations(\n args,\n action.receiverId,\n action.signerId,\n \"direct\",\n action.receiptId\n );\n break;\n\n // this is a form of donation where user calls donate on a pot\n case \"handle_protocol_fee_callback\":\n console.log(\"donations to pool incoming:\", JSON.parse(args));\n await handleNewDonations(\n args,\n action.receiverId,\n action.signerId,\n \"pot\",\n action.receiptId\n );\n break;\n // this handles project/list registration\n case \"register_batch\":\n console.log(\"registrations incoming:\", JSON.parse(args));\n if (action.receiverId != \"lists.potlock.near\") {\n break;\n }\n await handleNewProject(\n args,\n action.receiverId,\n action.signerId,\n action.receiptId\n );\n break;\n\n // chefs approve/decline ... etc a projects application to a pot\n case \"chef_set_application_status\":\n console.log(\n \"application status change incoming:\",\n JSON.parse(args)\n );\n await handleApplicationStatusChange(\n args,\n action.receiverId,\n action.signerId,\n action.receiptId\n );\n break;\n\n // registries can have default status for projects\n case \"admin_set_default_project_status\":\n console.log(\n \"registry default status setting incoming:\",\n JSON.parse(args)\n );\n await handleDefaultListStatusChange(\n args,\n action.receiverId,\n action.signerId,\n action.receiptId\n );\n break;\n\n // admins can set a project's status\n case \"admin_set_project_status\":\n console.log(\n \"project registration status update incoming:\",\n JSON.parse(args)\n );\n await handleProjectRegistrationUpdate(\n args,\n action.receiverId,\n action.signerId,\n action.receiptId\n );\n break;\n\n // fires when chef set payouts\n case \"chef_set_payouts\":\n console.log(\"setting payout....:\", JSON.parse(args));\n await handleSettingPayout(\n args,\n action.receiverId,\n action.signerId,\n action.receiptId\n );\n break;\n\n // fires when there is a payout challenge\n case \"challenge_payouts\":\n console.log(\"challenge payout:\", JSON.parse(args));\n await handlePayoutChallenge(\n args,\n action.receiverId,\n action.signerId,\n action.receiptId\n );\n break;\n // fires when fulfilling payouts\n case \"transfer_payout_callback\":\n console.log(\"fulfilling payouts.....\", JSON.parse(args));\n await handlePayout(\n args,\n action.receiverId,\n action.signerId,\n action.receiptId\n );\n break;\n case \"owner_remove_admins\":\n console.log(\"attempting to remove admins....:\", JSON.parse(args));\n if (action.receiverId != \"lists.potlock.near\") {\n break;\n }\n await handleListAdminRemoval(\n args,\n action.receiverId,\n action.signerId,\n action.receiptId\n );\n break;\n case \"create_list\":\n console.log(\"creating list...\", JSON.parse(args));\n if (action.receiverId != \"lists.potlock.near\") {\n break;\n }\n await handleRegistry(\n args,\n action.receiverId,\n action.signerId,\n action.receiptId\n );\n break;\n case \"upvote\":\n console.log(\"up voting...\", JSON.parse(args));\n if (action.receiverId != \"lists.potlock.near\") {\n break;\n }\n await handleUpVoting(\n args,\n action.receiverId,\n action.signerId,\n action.receiptId\n );\n }\n }\n });\n })\n );\n", "schema": "CREATE TABLE\n account (\n id VARCHAR PRIMARY KEY,\n total_donations_received_usd DECIMAL(10, 2),\n total_donated_usd DECIMAL(10, 2),\n total_matching_pool_allocations_usd DECIMAL(10, 2),\n donors_count INT\n );\n\nCREATE TABLE\n list (\n id BIGINT PRIMARY KEY,\n owner_id VARCHAR NOT NULL,\n name VARCHAR NOT NULL,\n description TEXT,\n cover_image_url VARCHAR,\n admin_only_registrations BOOLEAN NOT NULL DEFAULT FALSE,\n default_registration_status ENUM(\n 'Pending',\n 'Approved',\n 'Rejected',\n 'Graylisted',\n 'Blacklisted'\n ) NOT NULL,\n created_at TIMESTAMP NOT NULL,\n updated_at TIMESTAMP,\n FOREIGN KEY (owner_id) REFERENCES account (id)\n );\n\nCREATE TABLE\n list_admin (\n list_id BIGINT NOT NULL,\n admin_id VARCHAR NOT NULL,\n PRIMARY KEY (list_id, admin_id),\n FOREIGN KEY (list_id) REFERENCES list (id),\n FOREIGN KEY (admin_id) REFERENCES account (id)\n );\n\nCREATE TABLE\n list_upvotes (\n list_id BIGINT NOT NULL,\n account_id VARCHAR NOT NULL,\n created_at TIMESTAMP NOT NULL DEFAULT NOW(),\n PRIMARY KEY (list_id, account_id),\n FOREIGN KEY (list_id) REFERENCES list (id),\n FOREIGN KEY (account_id) REFERENCES account (id)\n );\n\nCREATE TABLE\n list_registration (\n id INT PRIMARY KEY,\n registrant_id VARCHAR NOT NULL,\n registered_by VARCHAR NOT NULL,\n status ENUM(\n 'Pending',\n 'Approved',\n 'Rejected',\n 'Graylisted',\n 'Blacklisted'\n ) NOT NULL,\n submitted_at TIMESTAMP NOT NULL,\n updated_at TIMESTAMP,\n registrant_notes TEXT,\n admin_notes TEXT,\n tx_hash VARCHAR NOT NULL,\n FOREIGN KEY (registrant_id) REFERENCES account (id)\n );\n\nCREATE TABLE\n pot_factory (\n id VARCHAR PRIMARY KEY,\n owner_id VARCHAR NOT NULL,\n deployed_at TIMESTAMP NOT NULL,\n source_metadata JSONB NOT NULL,\n protocol_fee_basis_points INT NOT NULL,\n protocol_fee_recipient_account VARCHAR NOT NULL,\n require_whitelist BOOLEAN NOT NULL,\n FOREIGN KEY (owner_id) REFERENCES account (id),\n FOREIGN KEY (protocol_fee_recipient_account) REFERENCES account (id)\n );\n\nCREATE TABLE\n pot_factory_admin (\n pot_factory_id INT NOT NULL,\n admin_id VARCHAR NOT NULL,\n PRIMARY KEY (pot_factory_id, admin_id),\n FOREIGN KEY (pot_factory_id) REFERENCES pot_factory (id),\n FOREIGN KEY (admin_id) REFERENCES account (id)\n );\n\nCREATE TABLE\n pot_factory_whitelisted_deployer (\n pot_factory_id INT NOT NULL,\n whitelisted_deployer_id VARCHAR NOT NULL,\n PRIMARY KEY (pot_factory_id, whitelisted_deployer_id),\n FOREIGN KEY (pot_factory_id) REFERENCES pot_factory (id),\n FOREIGN KEY (whitelisted_deployer_id) REFERENCES account (id)\n );\n\nCREATE TABLE\n pot (\n id VARCHAR PRIMARY KEY,\n pot_factory_id INT NOT NULL,\n deployer_id VARCHAR NOT NULL,\n deployed_at TIMESTAMP NOT NULL,\n source_metadata VARCHAR NOT NULL,\n owner_id VARCHAR NOT NULL,\n chef_id VARCHAR,\n name TEXT NOT NULL,\n description TEXT NOT NULL,\n max_approved_applicants INT NOT NULL,\n base_currency VARCHAR,\n application_start TIMESTAMP NOT NULL,\n application_end TIMESTAMP NOT NULL,\n matching_round_start TIMESTAMP NOT NULL,\n matching_round_end TIMESTAMP NOT NULL,\n registry_provider VARCHAR,\n min_matching_pool_donation_amount VARCHAR NOT NULL,\n sybil_wrapper_provider VARCHAR,\n custom_sybil_checks VARCHAR,\n custom_min_threshold_score INT NULL,\n referral_fee_matching_pool_basis_points INT NOT NULL,\n referral_fee_public_round_basis_points INT NOT NULL,\n chef_fee_basis_points INT NOT NULL,\n total_matching_pool VARCHAR NOT NULL,\n total_matching_pool_usd DECIMAL(10, 2) NULL,\n matching_pool_balance VARCHAR NOT NULL,\n matching_pool_donations_count INT NOT NULL,\n total_public_donations VARCHAR NOT NULL,\n total_public_donations_usd DECIMAL(10, 2) NULL,\n public_donations_count INT NOT NULL,\n cooldown_end TIMESTAMP,\n cooldown_period_ms INT NOT NULL,\n FOREIGN KEY (account_id) REFERENCES account (id),\n all_paid_out BOOLEAN NOT NULL,\n protocol_config_provider VARCHAR,\n FOREIGN KEY (pot_factory_id) REFERENCES pot_factory (id),\n FOREIGN KEY (deployer_id) REFERENCES account (id),\n FOREIGN KEY (owner_id) REFERENCES account (id),\n FOREIGN KEY (chef_id) REFERENCES account (id),\n FOREIGN KEY (base_currency) REFERENCES account (id)\n );\n\n-- Table pot_application\nCREATE TABLE\n pot_application (\n id SERIAL PRIMARY KEY,\n pot_id INT NOT NULL,\n applicant_id VARCHAR NOT NULL,\n message TEXT,\n status ENUM('Pending', 'Approved', 'Rejected', 'InReview') NOT NULL,\n submitted_at TIMESTAMP NOT NULL,\n last_updated_at TIMESTAMP,\n tx_hash VARCHAR NOT NULL,\n FOREIGN KEY (pot_id) REFERENCES pot (id),\n FOREIGN KEY (applicant_id) REFERENCES account (id)\n );\n\n-- Table pot_application_review\nCREATE TABLE\n pot_application_review (\n id SERIAL PRIMARY KEY,\n application_id INT NOT NULL,\n reviewer_id VARCHAR NOT NULL,\n notes TEXT,\n status ENUM('Pending', 'Approved', 'Rejected', 'InReview') NOT NULL,\n reviewed_at TIMESTAMP NOT NULL,\n tx_hash VARCHAR NOT NULL,\n FOREIGN KEY (application_id) REFERENCES pot_application (id),\n FOREIGN KEY (reviewer_id) REFERENCES account (id)\n );\n\n-- Table pot_payout\nCREATE TABLE\n pot_payout (\n id SERIAL PRIMARY KEY,\n recipient_id VARCHAR NOT NULL,\n amount VARCHAR NOT NULL,\n amount_paid_usd DECIMAL(10, 2),\n ft_id VARCHAR NOT NULL NOT NULL,\n paid_at TIMESTAMP,\n tx_hash VARCHAR NOT NULL,\n FOREIGN KEY (recipient_id) REFERENCES account (id),\n FOREIGN KEY (ft_id) REFERENCES account (id)\n );\n\n-- Table pot_payout_challenge\nCREATE TABLE\n pot_payout_challenge (\n id SERIAL PRIMARY KEY,\n challenger_id VARCHAR NOT NULL,\n pot_id INT NOT NULL,\n created_at TIMESTAMP NOT NULL,\n message TEXT NOT NULL,\n FOREIGN KEY (challenger_id) REFERENCES account (id),\n FOREIGN KEY (pot_id) REFERENCES pot (id)\n );\n\n-- Table pot_payout_challenge_admin_response\nCREATE TABLE\n pot_payout_challenge_admin_response (\n id SERIAL PRIMARY KEY,\n challenge_id INT NOT NULL,\n admin_id VARCHAR NOT NULL,\n created_at TIMESTAMP NOT NULL,\n message TEXT,\n resolved BOOL NOT NULL,\n tx_hash VARCHAR NOT NULL,\n FOREIGN KEY (challenge_id) REFERENCES pot_payout_challenge (id),\n FOREIGN KEY (admin_id) REFERENCES account (id)\n );\n\n-- Table donation\nCREATE TABLE\n donation (\n id INT PRIMARY KEY,\n donor_id VARCHAR NOT NULL,\n total_amount VARCHAR NOT NULL,\n total_amount_usd DECIMAL(10, 2),\n net_amount VARCHAR NOT NULL,\n net_amount_usd DECIMAL(10, 2),\n ft_id VARCHAR NOT NULL,\n pot_id INT,\n matching_pool BOOLEAN NOT NULL,\n message TEXT,\n donated_at TIMESTAMP NOT NULL,\n recipient_id VARCHAR,\n protocol_fee VARCHAR NOT NULL,\n protocol_fee_usd DECIMAL(10, 2),\n referrer_id VARCHAR,\n referrer_fee VARCHAR,\n referrer_fee_usd DECIMAL(10, 2),\n chef_id VARCHAR,\n chef_fee VARCHAR,\n chef_fee_usd DECIMAL(10, 2),\n tx_hash VARCHAR NOT NULL,\n FOREIGN KEY (donor_id) REFERENCES account (id),\n FOREIGN KEY (pot_id) REFERENCES pot (id),\n FOREIGN KEY (recipient_id) REFERENCES account (id),\n FOREIGN KEY (ft_id) REFERENCES account (id),\n FOREIGN KEY (referrer_id) REFERENCES account (id),\n FOREIGN KEY (chef_id) REFERENCES account (id)\n );\n\n-- Table activity\nCREATE TABLE\n activity (\n id SERIAL PRIMARY KEY,\n signer_id VARCHAR NOT NULL,\n receiver_id VARCHAR NOT NULL,\n timestamp TIMESTAMP NOT NULL,\n action_result JSONB,\n tx_hash VARCHAR NOT NULL,\n type\n ENUM(\n 'Donate_Direct',\n 'Donate_Pot_Public',\n 'Donate_Pot_Matching_Pool',\n 'Register',\n 'Register_Batch',\n 'Deploy_Pot',\n 'Process_Payouts',\n 'Challenge_Payout',\n 'Submit_Application',\n 'Update_Pot_Config',\n 'Add_List_Admin',\n 'Remove_List_Admin'\n ) NOT NULL\n );\n\nCREATE TABLE\n pot_admin (\n pot_id INT NOT NULL,\n admin_id VARCHAR NOT NULL,\n PRIMARY KEY (pot_id, admin_id),\n FOREIGN KEY (pot_id) REFERENCES pot (id),\n FOREIGN KEY (admin_id) REFERENCES account (id)\n );\n\nCREATE TABLE\n token_historical_data (\n token_id VARCHAR PRIMARY KEY,\n last_updated TIMESTAMP NOT NULL,\n historical_price VARCHAR NOT NULL\n );\n\n-- account index\nCREATE INDEX\n idx_acct_donations_donors ON account (\n total_donations_received_usd,\n total_matching_pool_allocations_usd,\n total_donated_usd,\n donors_count\n );\n\n-- list index\nCREATE INDEX\n idx_list_stamps ON list (created_at, updated_at);\n\nCREATE INDEX\n idx_list_id_status ON list_registration (list_id, status);\n\n-- pot index\nCREATE INDEX\n \"deploy_time_idx\" ON pot (deployed_at);\n\nCREATE INDEX\n \"idx_pot_deployer_id\" ON pot (deployer_id);\n\n-- pot application index\nCREATE INDEX\n idx_pot_application_pot_id ON pot_application (pot_id);\n\nCREATE INDEX\n idx_pot_application_applicant_id ON pot_application (applicant_id);\n\nCREATE INDEX\n idx_pot_application_submitted_at ON pot_application (submitted_at);\n\nCREATE INDEX\n idx_application_period ON pot (application_start, application_end);\n\nCREATE INDEX\n idx_matching_period ON pot (matching_round_start, matching_round_end);\n\n-- payout index\nCREATE INDEX\n idx_pot_payout_recipient_id ON pot_payout (recipient_id);\n\n-- donation index\nCREATE INDEX\n idx_donation_donor_id ON donation (donor_id);\n\nCREATE INDEX\n idx_donation_pot_id ON donation (pot_id);\n\nCREATE INDEX\n idx_donation_donated_at ON donation (donated_at);\n\n-- activity index\nCREATE INDEX\n idx_activity_timestamp ON activity (timestamp);\n\n-- CREATE INDEX idx_pot_payout_recipient_id ON pot_payout (recipient_id);\n-- CREATE INDEX idx_pot_payout_ft_id ON pot_payout (ft_id);\nCREATE INDEX\n idx_pot_payout_paid_at ON pot_payout (paid_at);\n", "start_block": { "HEIGHT": 112618275 }, "rule": { "kind": "ACTION_ANY", "affected_account_id": "*.potlock.near", "status": "SUCCESS" } }

Transaction Execution Plan

Convert Transaction To Receipt
Gas Burned:
2 Tgas
Tokens Burned:
0.00025 
Receipt:
Predecessor ID:
Receiver ID:
Gas Burned:
7 Tgas
Tokens Burned:
0.00074 
Called method: 'register' in contract: query…tform.near
Arguments:
{ "function_name": "index_potlock_test", "code": "\n const BASE_ACCOUNT_ID = \"potlock.near\"; // potlock base id to match all actions\n // this function helps match factories, deployed in the manner `version.ptofactory....` where version can be v1,v2,vn\n function matchVersionPattern(text) {\n const pattern = /^v\\d+\\.potfactory\\.potlock\\.near$/;\n return pattern.test(text);\n }\n\n // filter receipts in this block to make sure we're inly indexing successful actions\n const receiptStatusMap = block\n .receipts()\n .filter(\n (receipt) =>\n receipt.receiverId.endsWith(BASE_ACCOUNT_ID) &&\n (receipt.status.hasOwnProperty(\"SuccessValue\") ||\n receipt.status.hasOwnProperty(\"SuccessReceiptId\"))\n )\n .map((receipt) => receipt.receiptId);\n\n console.log(\"let us see...\", receiptStatusMap);\n\n // filter actions in this block whose receipts can be found in the list of successful receipts\n\n console.log(\"txises:\", block.transactions);\n\n // filter actions in this block whose receipts can be found in the list of successful receipts\n const matchingActions = block\n .actions()\n .filter(\n (action) =>\n action.receiverId.endsWith(BASE_ACCOUNT_ID) &&\n receiptStatusMap.includes(action.receiptId)\n );\n\n console.log(\"macthing actions rambo=====\", matchingActions);\n\n // if there are no actions matching our conditions, then we have nothing to index in this block, unto the next.\n if (!matchingActions.length) {\n console.log(\"nothin concerns us here\");\n return;\n }\n\n const created_at = new Date(\n Number(BigInt(block.header().timestampNanosec) / BigInt(1000000))\n );\n\n async function handleNewPot(\n args,\n receiverId,\n signerId,\n predecessorId,\n receiptId\n ) {\n let data = JSON.parse(args);\n console.log(\"new pot data::\", { ...data }, receiverId, signerId);\n await context.db.Account.upsert({ id: data.owner }, [\"id\"], []);\n await context.db.Account.upsert({ id: signerId }, [\"id\"], []);\n\n if (data.chef) {\n await context.db.Account.upsert({ id: data.chef }, [\"id\"], []);\n }\n\n if (data.admins) {\n for (const admin in data.admins) {\n await context.db.Account.upsert({ id: admin }, [\"id\"], []);\n let pot_admin = {\n pot_id: receiverId,\n admin_id: admin,\n };\n await context.db.PotAdmin.insert(pot_admin);\n }\n }\n\n const potObject = {\n id: receiverId,\n pot_factory_id: predecessorId,\n deployer_id: signerId,\n deployed_at: created_at,\n source_metadata: JSON.stringify(data.source_metadata),\n owner_id: data.owner,\n chef_id: data.chef,\n name: data.pot_name,\n description: data.pot_description,\n max_approved_applicants: data.max_projects,\n base_currency: \"near\",\n application_start: new Date(data.application_start_ms),\n application_end: new Date(data.application_end_ms),\n matching_round_start: new Date(data.public_round_start_ms),\n matching_round_end: new Date(data.public_round_end_ms),\n registry_provider: data.registry_provider,\n min_matching_pool_donation_amount: data.min_matching_pool_donation_amount,\n sybil_wrapper_provider: data.sybil_wrapper_provider,\n custom_sybil_checks: data.custom_sybil_checks\n ? JSON.stringify(data.custom_sybil_checks)\n : null,\n custom_min_threshold_score: data.custom_min_threshold_score,\n referral_fee_matching_pool_basis_points:\n data.referral_fee_matching_pool_basis_points,\n referral_fee_public_round_basis_points:\n data.referral_fee_public_round_basis_points,\n chef_fee_basis_points: data.chef_fee_basis_points,\n total_matching_pool: \"0\",\n total_matching_pool_usd: data.total_matching_pool_usd,\n matching_pool_balance: \"0\",\n matching_pool_donations_count: 0,\n total_public_donations: \"0\",\n total_public_donations_usd: data.total_public_donations_usd,\n public_donations_count: 0,\n cooldown_period_ms: null,\n all_paid_out: false,\n protocol_config_provider: data.protocol_config_provider,\n };\n\n await context.db.Pot.insert(potObject);\n\n let activity = {\n signer_id: signerId,\n receiver_id: receiverId,\n timestamp: created_at,\n type: \"Deploy_Pot\",\n action_result: JSON.stringify(potObject),\n tx_hash: receiptId,\n };\n\n await context.db.Activity.insert(activity);\n }\n\n async function handleNewFactory(args, receiverId, signerId, receiptId) {\n let data = JSON.parse(args);\n console.log(\"new factory data::\", { ...data }, receiverId);\n // try saving concerned accounts\n await context.db.Account.upsert({ id: data.owner }, [\"id\"], []);\n await context.db.Account.upsert(\n { id: data.protocol_fee_recipient_account },\n [\"id\"],\n []\n );\n if (data.admins) {\n for (const admin in data.admins) {\n await context.db.Account.upsert({ id: admin }, [\"id\"], []);\n let factory_admin = {\n pot_factory_id: receiverId,\n admin_id: admin,\n };\n await context.db.PotFactoryAdmin.insert(factory_admin);\n }\n }\n\n if (data.whitelisted_deployers) {\n for (const deployer in data.whitelisted_deployers) {\n await context.db.Account.upsert({ id: deployer }, [\"id\"], []);\n let factory_deployer = {\n pot_factory_id: receiverId,\n whitelisted_deployer_id: deployer,\n };\n await context.db.PotFactoryWhitelistedDeployer.insert(factory_deployer);\n }\n }\n const factory = {\n id: receiverId,\n owner_id: data.owner,\n deployed_at: created_at,\n source_metadata: JSON.stringify(data.source_metadata),\n protocol_fee_basis_points: data.protocol_fee_basis_points,\n protocol_fee_recipient_account: data.protocol_fee_recipient_account,\n require_whitelist: data.require_whitelist,\n };\n console.log(\"factory..\", factory);\n await context.db.PotFactory.insert(factory);\n }\n\n // function tracks registry contracts, where projects are registered\n async function handleRegistry(args, receiverId, signerId, receiptId) {\n let receipt = block\n .receipts()\n .filter((receipt) => receipt.receiptId == receiptId)[0];\n let data = JSON.parse(atob(receipt.status[\"SuccessValue\"]));\n console.log(\"new Registry data::\", { ...data }, receiverId);\n\n if (data.admins) {\n for (const admin in data.admins) {\n await context.db.Account.upsert({ id: data.admins[admin] }, [\"id\"], []);\n let list_admin = {\n list_id: data.id,\n admin_id: admin,\n };\n await context.db.ListAdmin.insert(list_admin);\n }\n }\n\n let regv = {\n id: data.id,\n owner_id: data.owner,\n default_registration_status: data.default_registration_status, // the first registry contract has approved as default, and the later changed through the admin set function call, which we also listen to, so it should self correct.\n name: data.name,\n description: data.description,\n cover_image_url: data.cover_image_url,\n admin_only_registrations: data.admin_only_registrations,\n tx_hash: receiptId,\n created_at: data.created_at,\n updated_at: data.updated_at,\n };\n\n await context.db.Account.upsert({ id: data.owner }, [\"id\"], []);\n\n await context.db.List.insert(regv);\n }\n\n // function tracks register function calls on the registry conract\n async function handleNewProject(args, receiverId, signerId, receiptId) {\n let data = JSON.parse(args);\n console.log(\"new Project data::\", { ...data }, receiverId);\n let receipt = block\n .receipts()\n .filter((receipt) => receipt.receiptId == receiptId)[0];\n let reg_data = JSON.parse(atob(receipt.status[\"SuccessValue\"]));\n // let array_data = Array.isArray(reg_data) ? reg_data : [reg_data]\n let project_list = [];\n let insert_data = reg_data.map((dt) => {\n project_list.push({ id: dt.registrant_id });\n return {\n id: dt.id,\n registrant_id: dt.registrant_id,\n list_id: dt.list_id,\n status: dt.status,\n submitted_at: dt.submitted_ms,\n updated_at: dt.updated_ms,\n registered_by: dt.registered_by,\n admin_notes: dt.admin_notes,\n registrant_notes: dt.registrant_notes,\n tx_hash: receiptId,\n };\n });\n await context.db.Account.upsert(project_list, [\"id\"], []);\n await context.db.Account.upsert({ id: signerId }, [\"id\"], []);\n\n await context.db.ListRegistration.insert(insert_data);\n let activity = {\n signer_id: signerId,\n receiver_id: receiverId,\n timestamp: insert_data[0].submitted_at,\n type: \"Register_Batch\",\n action_result: JSON.stringify(reg_data),\n tx_hash: receiptId,\n };\n\n await context.db.Activity.insert(activity);\n }\n\n async function handleProjectRegistrationUpdate(\n args,\n receiverId,\n signerId,\n receiptId\n ) {\n let data = JSON.parse(args);\n console.log(\"new Project data::\", { ...data }, receiverId);\n let regUpdate = {\n status: data.status,\n admin_notes: data.review_notes,\n updated_at: created_at,\n };\n\n await context.db.ListRegistration.update(\n { registrant_id: data.project_id },\n regUpdate\n );\n }\n\n async function handlePotApplication(args, receiverId, signerId, receiptId) {\n let data = JSON.parse(args);\n let receipt = block\n .receipts()\n .filter((receipt) => receipt.receiptId == receiptId)[0];\n let result = receipt.status[\"SuccessValue\"];\n if (!result) {\n return;\n }\n let appl_data = JSON.parse(atob(receipt.status[\"SuccessValue\"]));\n console.log(\"new pot application data::\", { ...data }, appl_data);\n await context.db.Account.upsert({ id: data.project_id }, [\"id\"], []);\n let application = {\n pot_id: receiverId,\n applicant_id: appl_data.project_id,\n message: appl_data.message,\n submitted_at: appl_data.submitted_at,\n status: appl_data.status,\n tx_hash: receiptId,\n };\n await context.db.PotApplication.insert(application);\n\n let activity = {\n signer_id: signerId,\n receiver_id: receiverId,\n timestamp: application.submitted_at,\n type: \"Submit_Application\",\n action_result: JSON.stringify(appl_data), // result points to the pot application created.\n tx_hash: receiptId, // should we have receipt on both action and activity?\n };\n\n await context.db.Activity.insert(activity);\n }\n\n async function handleApplicationStatusChange(\n args,\n receiverId,\n signerId,\n receiptId\n ) {\n let data = JSON.parse(args);\n console.log(\"pot application update data::\", { ...data }, receiverId);\n\n let receipt = block\n .receipts()\n .filter((receipt) => receipt.receiptId == receiptId)[0];\n let update_data = JSON.parse(atob(receipt.status[\"SuccessValue\"]));\n let appl = (\n await context.db.PotApplication.select({ applicant_id: data.project_id })\n )[0];\n\n let applicationReview = {\n application_id: appl.id,\n reviewer_id: signerId,\n notes: update_data.notes,\n status: update_data.status,\n reviewed_at: update_data.updated_at,\n tx_hash: receiptId,\n };\n let applicationUpdate = {\n current_status: update_data.status,\n last_updated_at: update_data.updated_at,\n };\n\n await context.db.PotApplicationReview.insert(applicationReview);\n await context.db.PotApplication.update({ id: appl.id }, applicationUpdate);\n }\n\n async function handleDefaultListStatusChange(\n args,\n receiverId,\n signerId,\n receiptId\n ) {\n let data = JSON.parse(args);\n console.log(\"update project data::\", { ...data }, receiverId);\n\n let listUpdate = {\n default_registration_status: data.status,\n };\n\n await context.db.List.update(\n { id: data.list_id || receiverId },\n listUpdate\n );\n }\n\n async function handleUpVoting(args, receiverId, signerId, receiptId) {\n let data = JSON.parse(args);\n console.log(\"upvote list::\", { ...data }, receiverId);\n\n let listUpVote = {\n list_id: data.list_id,\n account_id: signerId,\n created_at,\n };\n\n let activity = {\n signer_id: signerId,\n receiver_id: receiverId,\n timestamp: created_at,\n type: \"Upvote\",\n action_result: JSON.stringify(data),\n tx_hash: receiptId,\n };\n\n await context.db.List.update(\n { id: data.list_id || receiverId },\n listUpVote\n );\n await context.db.Activity.insert(activity);\n }\n\n async function handleSettingPayout(args, receiverId, signerId, receiptId) {\n let data = JSON.parse(args);\n console.log(\"set payout data::\", { ...data }, receiverId);\n let payouts = data.payouts;\n for (const payout in payouts) {\n // general question: should we register projects as accounts?\n let potPayout = {\n recipient_id: payout[\"project_id\"],\n amount: payout[\"amount\"],\n ft_id: payout[\"ft_id\"] || \"near\",\n tx_hash: receiptId,\n };\n await context.db.PotPayout.insert(potPayout);\n }\n }\n\n async function handlePayout(args, receiverId, signerId, receiptId) {\n let data = JSON.parse(args);\n data = data.payout;\n console.log(\"fulfill payout data::\", { ...data }, receiverId);\n let payout = {\n recipient_id: data.project_id,\n amount: data.amount,\n paid_at: data.paid_at || created_at,\n tx_hash: receiptId,\n };\n await context.db.PotPayout.update(\n { recipient_id: data.project_id },\n payout\n );\n }\n\n async function handlePayoutChallenge(args, receiverId, signerId, receiptId) {\n let data = JSON.parse(args);\n console.log(\"challenging payout..: \", { ...data }, receiverId);\n let created_at = new Date(\n Number(BigInt(block.header().timestampNanosec) / BigInt(1000000)) // convert to ms then date\n );\n let payoutChallenge = {\n challenger_id: signerId,\n pot_id: receiverId,\n created_at,\n message: data.reason,\n tx_hash: receiptId,\n };\n await context.db.PotPayoutChallenge.insert(payoutChallenge);\n\n let activity = {\n signer_id: signerId,\n receiver_id: receiverId,\n timestamp: created_at,\n type: \"Challenge_Payout\",\n action_result: JSON.stringify(payoutChallenge),\n tx_hash: receiptId,\n };\n\n await context.db.Activity.insert(activity);\n }\n\n async function handleListAdminRemoval(args, receiverId, signerId, receiptId) {\n let data = JSON.parse(args);\n console.log(\"removing admin...: \", { ...data }, receiverId);\n let list = await context.db.List.select({ id: data.list_id });\n\n for (const acct in data.admins) {\n await context.db.ListAdmin.delete({\n list_id: list[0].id,\n admin_id: acct,\n });\n }\n\n let activity = {\n signer_id: signerId,\n receiver_id: receiverId,\n timestamp: created_at,\n type: \"Remove_List_Admin\",\n tx_hash: receiptId,\n };\n\n await context.db.Activity.insert(activity);\n }\n\n const GECKO_URL = \"https://api.coingecko.com/api/v3\";\n function formatDate(date) {\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, \"0\");\n const day = String(date.getDate()).padStart(2, \"0\");\n\n return `${day}-${month}-${year}`;\n }\n\n // helper function to format\n function formatToNear(yoctoAmount) {\n const nearAmount = yoctoAmount / 10 ** 24;\n return nearAmount;\n }\n\n async function handleNewDonations(\n args,\n receiverId,\n signerId,\n actionName,\n receiptId\n ) {\n let donation_data;\n if (actionName == \"direct\") {\n console.log(\"calling donate on projects...\");\n let event = block\n .events()\n .filter((evt) => evt.relatedReceiptId == receiptId);\n if (!event.length) {\n return;\n }\n const event_data = event[0].rawEvent.standard;\n console.log(\"pioper..\", event_data);\n donation_data = JSON.parse(event_data).data[0].donation;\n console.log(\"DODONDAWA..\", donation_data);\n } else {\n let receipt = block\n .receipts()\n .filter((receipt) => receipt.receiptId == receiptId)[0];\n donation_data = JSON.parse(atob(receipt.status[\"SuccessValue\"]));\n }\n console.log(\"action and recv\", actionName, receiverId);\n\n console.log(\"result arg...:\", donation_data);\n let donated_at = new Date(\n donation_data.donated_at || donation_data.donated_at_ms\n );\n await context.db.Account.upsert({ id: donation_data.donor_id }, [\"id\"], []);\n let endpoint = `${GECKO_URL}/coins/${\n donation_data.ft_id || \"near\"\n }/history?date=${formatDate(donated_at)}&localization=false`;\n let unit_price;\n try {\n let response = await fetch(endpoint);\n let data = await response.json();\n unit_price = data.market_data?.current_price.usd;\n let hist_data = {\n token_id: donation_data.ft_id || \"near\",\n last_updated: created_at,\n historical_price: unit_price,\n };\n await context.db.TokenHistoricalData.upsert(\n hist_data,\n [\"token_id\"],\n [\"historical_price\"]\n );\n } catch (err) {\n console.log(\"api rate limi?::\", err);\n let historica_price = await context.db.TokenHistoricalData.select({\n token_id: donation_data.ft_id || \"near\",\n });\n unit_price = historica_price[0].historical_price;\n }\n\n let total_amount = donation_data.total_amount;\n let net_amount = donation_data.net_amount;\n if (donation_data.referrer_fee) {\n net_amount = (\n BigInt(net_amount) - BigInt(donation_data.referrer_fee)\n ).toString();\n }\n\n let totalnearAmount = formatToNear(total_amount);\n let netnearAmount = formatToNear(net_amount);\n let total_amount_usd = unit_price * totalnearAmount;\n let net_amount_usd = unit_price * netnearAmount;\n let donation = {\n donor_id: donation_data.donor_id,\n total_amount,\n total_amount_usd,\n net_amount_usd,\n net_amount,\n ft_id: donation_data.ft_id || \"near\",\n message: donation_data.message,\n donated_at,\n matching_pool: donation_data.matching_pool || false,\n recipient_id: donation_data.project_id || donation_data.recipient_id,\n protocol_fee: donation_data.protocol_fee,\n referrer_id: donation_data.referrer_id,\n referrer_fee: donation_data.referrer_fee,\n tx_hash: receiptId,\n };\n await context.db.Donation.insert(donation);\n\n if (actionName != \"direct\") {\n // update pot data such as public donations and matchingpool\n let pot = (await context.db.Pot.select({ id: receiverId }))[0];\n donation[\"pot_id\"] = pot.id;\n let potUpdate = {\n total_public_donations_usd:\n pot.total_public_donations_usd || 0 + total_amount_usd,\n total_public_donations: pot.total_public_donations || 0 + total_amount,\n };\n if (donation_data.matching_pool) {\n potUpdate[\"total_matching_pool_usd\"] =\n pot.total_matching_pool_usd || 0 + total_amount_usd;\n potUpdate[\"total_matching_pool\"] =\n pot.total_matching_pool || 0 + total_amount;\n potUpdate[\"matching_pool_donations_count\"] =\n pot.matching_pool_donations_count || 0 + 1;\n let accountUpdate = {};\n } else {\n potUpdate[\"public_donations_count\"] =\n pot.public_donations_count || 0 + 1;\n }\n await context.db.Pot.update({ id: pot.id }, potUpdate);\n }\n\n let recipient = donation_data.project_id || donation_data.recipient_id;\n\n if (recipient) {\n let acct = (await context.db.Account.select({ id: recipient }))[0];\n console.log(\"selected acct\", acct);\n let acctUpdate = {\n total_donations_usd:\n acct.total_donations_received_usd || 0 + total_amount_usd,\n donors_count: acct.donors_count || 0 + 1,\n };\n await context.db.Account.update({ id: recipient }, acctUpdate);\n }\n\n let activity = {\n signer_id: signerId,\n receiver_id: receiverId,\n timestamp: donation.donated_at,\n type:\n actionName == \"direct\"\n ? \"Donate_Direct\"\n : donation.matching_pool\n ? \"Donate_Pot_Matching_Pool\"\n : \"Donate_Pot_Public\",\n action_result: JSON.stringify(donation),\n tx_hash: receiptId,\n };\n\n await context.db.Activity.insert(activity);\n }\n\n // map through the successful actions and swittch on the methodName called for each, then call the designated handlerFunction.\n await Promise.all(\n matchingActions.flatMap((action) => {\n action.operations.map(async (operation) => {\n console.log(\"see the contents here...:,==\", operation[\"FunctionCall\"]);\n let call = operation[\"FunctionCall\"];\n if (call) {\n const args = atob(call.args); // decode function call argument\n switch (call.methodName) {\n case \"new\":\n // new can be called on a couple of things, if the recever id matches factory pattern, then it's a new factory, else if it matches the registry account id, then it's a registry contract initialization, else, it's a new pot initialization.\n matchVersionPattern(action.receiverId)\n ? await handleNewFactory(\n args,\n action.receiverId,\n action.signerId,\n action.receiptId\n )\n : await handleNewPot(\n args,\n action.receiverId,\n action.signerId,\n action.predecessorId,\n action.receiptId\n );\n break;\n // this is the callback after user applies to a certain pot, it can either be this or handle_apply\n case \"assert_can_apply_callback\":\n console.log(\"application case:\", JSON.parse(args));\n await handlePotApplication(\n args,\n action.receiverId,\n action.signerId,\n action.receiptId\n );\n break;\n case \"apply\":\n console.log(\"application case 2:\", JSON.parse(args));\n await handlePotApplication(\n args,\n action.receiverId,\n action.signerId,\n action.receiptId\n );\n break;\n\n // if function call is donate, call the handle new donations function\n case \"donate\":\n console.log(\"donatons to project incoming:\", JSON.parse(args));\n await handleNewDonations(\n args,\n action.receiverId,\n action.signerId,\n \"direct\",\n action.receiptId\n );\n break;\n\n // this is a form of donation where user calls donate on a pot\n case \"handle_protocol_fee_callback\":\n console.log(\"donations to pool incoming:\", JSON.parse(args));\n await handleNewDonations(\n args,\n action.receiverId,\n action.signerId,\n \"pot\",\n action.receiptId\n );\n break;\n // this handles project/list registration\n case \"register_batch\":\n console.log(\"registrations incoming:\", JSON.parse(args));\n if (action.receiverId != \"lists.potlock.near\") {\n break;\n }\n await handleNewProject(\n args,\n action.receiverId,\n action.signerId,\n action.receiptId\n );\n break;\n\n // chefs approve/decline ... etc a projects application to a pot\n case \"chef_set_application_status\":\n console.log(\n \"application status change incoming:\",\n JSON.parse(args)\n );\n await handleApplicationStatusChange(\n args,\n action.receiverId,\n action.signerId,\n action.receiptId\n );\n break;\n\n // registries can have default status for projects\n case \"admin_set_default_project_status\":\n console.log(\n \"registry default status setting incoming:\",\n JSON.parse(args)\n );\n await handleDefaultListStatusChange(\n args,\n action.receiverId,\n action.signerId,\n action.receiptId\n );\n break;\n\n // admins can set a project's status\n case \"admin_set_project_status\":\n console.log(\n \"project registration status update incoming:\",\n JSON.parse(args)\n );\n await handleProjectRegistrationUpdate(\n args,\n action.receiverId,\n action.signerId,\n action.receiptId\n );\n break;\n\n // fires when chef set payouts\n case \"chef_set_payouts\":\n console.log(\"setting payout....:\", JSON.parse(args));\n await handleSettingPayout(\n args,\n action.receiverId,\n action.signerId,\n action.receiptId\n );\n break;\n\n // fires when there is a payout challenge\n case \"challenge_payouts\":\n console.log(\"challenge payout:\", JSON.parse(args));\n await handlePayoutChallenge(\n args,\n action.receiverId,\n action.signerId,\n action.receiptId\n );\n break;\n // fires when fulfilling payouts\n case \"transfer_payout_callback\":\n console.log(\"fulfilling payouts.....\", JSON.parse(args));\n await handlePayout(\n args,\n action.receiverId,\n action.signerId,\n action.receiptId\n );\n break;\n case \"owner_remove_admins\":\n console.log(\"attempting to remove admins....:\", JSON.parse(args));\n if (action.receiverId != \"lists.potlock.near\") {\n break;\n }\n await handleListAdminRemoval(\n args,\n action.receiverId,\n action.signerId,\n action.receiptId\n );\n break;\n case \"create_list\":\n console.log(\"creating list...\", JSON.parse(args));\n if (action.receiverId != \"lists.potlock.near\") {\n break;\n }\n await handleRegistry(\n args,\n action.receiverId,\n action.signerId,\n action.receiptId\n );\n break;\n case \"upvote\":\n console.log(\"up voting...\", JSON.parse(args));\n if (action.receiverId != \"lists.potlock.near\") {\n break;\n }\n await handleUpVoting(\n args,\n action.receiverId,\n action.signerId,\n action.receiptId\n );\n }\n }\n });\n })\n );\n", "schema": "CREATE TABLE\n account (\n id VARCHAR PRIMARY KEY,\n total_donations_received_usd DECIMAL(10, 2),\n total_donated_usd DECIMAL(10, 2),\n total_matching_pool_allocations_usd DECIMAL(10, 2),\n donors_count INT\n );\n\nCREATE TABLE\n list (\n id BIGINT PRIMARY KEY,\n owner_id VARCHAR NOT NULL,\n name VARCHAR NOT NULL,\n description TEXT,\n cover_image_url VARCHAR,\n admin_only_registrations BOOLEAN NOT NULL DEFAULT FALSE,\n default_registration_status ENUM(\n 'Pending',\n 'Approved',\n 'Rejected',\n 'Graylisted',\n 'Blacklisted'\n ) NOT NULL,\n created_at TIMESTAMP NOT NULL,\n updated_at TIMESTAMP,\n FOREIGN KEY (owner_id) REFERENCES account (id)\n );\n\nCREATE TABLE\n list_admin (\n list_id BIGINT NOT NULL,\n admin_id VARCHAR NOT NULL,\n PRIMARY KEY (list_id, admin_id),\n FOREIGN KEY (list_id) REFERENCES list (id),\n FOREIGN KEY (admin_id) REFERENCES account (id)\n );\n\nCREATE TABLE\n list_upvotes (\n list_id BIGINT NOT NULL,\n account_id VARCHAR NOT NULL,\n created_at TIMESTAMP NOT NULL DEFAULT NOW(),\n PRIMARY KEY (list_id, account_id),\n FOREIGN KEY (list_id) REFERENCES list (id),\n FOREIGN KEY (account_id) REFERENCES account (id)\n );\n\nCREATE TABLE\n list_registration (\n id INT PRIMARY KEY,\n registrant_id VARCHAR NOT NULL,\n registered_by VARCHAR NOT NULL,\n status ENUM(\n 'Pending',\n 'Approved',\n 'Rejected',\n 'Graylisted',\n 'Blacklisted'\n ) NOT NULL,\n submitted_at TIMESTAMP NOT NULL,\n updated_at TIMESTAMP,\n registrant_notes TEXT,\n admin_notes TEXT,\n tx_hash VARCHAR NOT NULL,\n FOREIGN KEY (registrant_id) REFERENCES account (id)\n );\n\nCREATE TABLE\n pot_factory (\n id VARCHAR PRIMARY KEY,\n owner_id VARCHAR NOT NULL,\n deployed_at TIMESTAMP NOT NULL,\n source_metadata JSONB NOT NULL,\n protocol_fee_basis_points INT NOT NULL,\n protocol_fee_recipient_account VARCHAR NOT NULL,\n require_whitelist BOOLEAN NOT NULL,\n FOREIGN KEY (owner_id) REFERENCES account (id),\n FOREIGN KEY (protocol_fee_recipient_account) REFERENCES account (id)\n );\n\nCREATE TABLE\n pot_factory_admin (\n pot_factory_id INT NOT NULL,\n admin_id VARCHAR NOT NULL,\n PRIMARY KEY (pot_factory_id, admin_id),\n FOREIGN KEY (pot_factory_id) REFERENCES pot_factory (id),\n FOREIGN KEY (admin_id) REFERENCES account (id)\n );\n\nCREATE TABLE\n pot_factory_whitelisted_deployer (\n pot_factory_id INT NOT NULL,\n whitelisted_deployer_id VARCHAR NOT NULL,\n PRIMARY KEY (pot_factory_id, whitelisted_deployer_id),\n FOREIGN KEY (pot_factory_id) REFERENCES pot_factory (id),\n FOREIGN KEY (whitelisted_deployer_id) REFERENCES account (id)\n );\n\nCREATE TABLE\n pot (\n id VARCHAR PRIMARY KEY,\n pot_factory_id INT NOT NULL,\n deployer_id VARCHAR NOT NULL,\n deployed_at TIMESTAMP NOT NULL,\n source_metadata VARCHAR NOT NULL,\n owner_id VARCHAR NOT NULL,\n chef_id VARCHAR,\n name TEXT NOT NULL,\n description TEXT NOT NULL,\n max_approved_applicants INT NOT NULL,\n base_currency VARCHAR,\n application_start TIMESTAMP NOT NULL,\n application_end TIMESTAMP NOT NULL,\n matching_round_start TIMESTAMP NOT NULL,\n matching_round_end TIMESTAMP NOT NULL,\n registry_provider VARCHAR,\n min_matching_pool_donation_amount VARCHAR NOT NULL,\n sybil_wrapper_provider VARCHAR,\n custom_sybil_checks VARCHAR,\n custom_min_threshold_score INT NULL,\n referral_fee_matching_pool_basis_points INT NOT NULL,\n referral_fee_public_round_basis_points INT NOT NULL,\n chef_fee_basis_points INT NOT NULL,\n total_matching_pool VARCHAR NOT NULL,\n total_matching_pool_usd DECIMAL(10, 2) NULL,\n matching_pool_balance VARCHAR NOT NULL,\n matching_pool_donations_count INT NOT NULL,\n total_public_donations VARCHAR NOT NULL,\n total_public_donations_usd DECIMAL(10, 2) NULL,\n public_donations_count INT NOT NULL,\n cooldown_end TIMESTAMP,\n cooldown_period_ms INT NOT NULL,\n FOREIGN KEY (account_id) REFERENCES account (id),\n all_paid_out BOOLEAN NOT NULL,\n protocol_config_provider VARCHAR,\n FOREIGN KEY (pot_factory_id) REFERENCES pot_factory (id),\n FOREIGN KEY (deployer_id) REFERENCES account (id),\n FOREIGN KEY (owner_id) REFERENCES account (id),\n FOREIGN KEY (chef_id) REFERENCES account (id),\n FOREIGN KEY (base_currency) REFERENCES account (id)\n );\n\n-- Table pot_application\nCREATE TABLE\n pot_application (\n id SERIAL PRIMARY KEY,\n pot_id INT NOT NULL,\n applicant_id VARCHAR NOT NULL,\n message TEXT,\n status ENUM('Pending', 'Approved', 'Rejected', 'InReview') NOT NULL,\n submitted_at TIMESTAMP NOT NULL,\n last_updated_at TIMESTAMP,\n tx_hash VARCHAR NOT NULL,\n FOREIGN KEY (pot_id) REFERENCES pot (id),\n FOREIGN KEY (applicant_id) REFERENCES account (id)\n );\n\n-- Table pot_application_review\nCREATE TABLE\n pot_application_review (\n id SERIAL PRIMARY KEY,\n application_id INT NOT NULL,\n reviewer_id VARCHAR NOT NULL,\n notes TEXT,\n status ENUM('Pending', 'Approved', 'Rejected', 'InReview') NOT NULL,\n reviewed_at TIMESTAMP NOT NULL,\n tx_hash VARCHAR NOT NULL,\n FOREIGN KEY (application_id) REFERENCES pot_application (id),\n FOREIGN KEY (reviewer_id) REFERENCES account (id)\n );\n\n-- Table pot_payout\nCREATE TABLE\n pot_payout (\n id SERIAL PRIMARY KEY,\n recipient_id VARCHAR NOT NULL,\n amount VARCHAR NOT NULL,\n amount_paid_usd DECIMAL(10, 2),\n ft_id VARCHAR NOT NULL NOT NULL,\n paid_at TIMESTAMP,\n tx_hash VARCHAR NOT NULL,\n FOREIGN KEY (recipient_id) REFERENCES account (id),\n FOREIGN KEY (ft_id) REFERENCES account (id)\n );\n\n-- Table pot_payout_challenge\nCREATE TABLE\n pot_payout_challenge (\n id SERIAL PRIMARY KEY,\n challenger_id VARCHAR NOT NULL,\n pot_id INT NOT NULL,\n created_at TIMESTAMP NOT NULL,\n message TEXT NOT NULL,\n FOREIGN KEY (challenger_id) REFERENCES account (id),\n FOREIGN KEY (pot_id) REFERENCES pot (id)\n );\n\n-- Table pot_payout_challenge_admin_response\nCREATE TABLE\n pot_payout_challenge_admin_response (\n id SERIAL PRIMARY KEY,\n challenge_id INT NOT NULL,\n admin_id VARCHAR NOT NULL,\n created_at TIMESTAMP NOT NULL,\n message TEXT,\n resolved BOOL NOT NULL,\n tx_hash VARCHAR NOT NULL,\n FOREIGN KEY (challenge_id) REFERENCES pot_payout_challenge (id),\n FOREIGN KEY (admin_id) REFERENCES account (id)\n );\n\n-- Table donation\nCREATE TABLE\n donation (\n id INT PRIMARY KEY,\n donor_id VARCHAR NOT NULL,\n total_amount VARCHAR NOT NULL,\n total_amount_usd DECIMAL(10, 2),\n net_amount VARCHAR NOT NULL,\n net_amount_usd DECIMAL(10, 2),\n ft_id VARCHAR NOT NULL,\n pot_id INT,\n matching_pool BOOLEAN NOT NULL,\n message TEXT,\n donated_at TIMESTAMP NOT NULL,\n recipient_id VARCHAR,\n protocol_fee VARCHAR NOT NULL,\n protocol_fee_usd DECIMAL(10, 2),\n referrer_id VARCHAR,\n referrer_fee VARCHAR,\n referrer_fee_usd DECIMAL(10, 2),\n chef_id VARCHAR,\n chef_fee VARCHAR,\n chef_fee_usd DECIMAL(10, 2),\n tx_hash VARCHAR NOT NULL,\n FOREIGN KEY (donor_id) REFERENCES account (id),\n FOREIGN KEY (pot_id) REFERENCES pot (id),\n FOREIGN KEY (recipient_id) REFERENCES account (id),\n FOREIGN KEY (ft_id) REFERENCES account (id),\n FOREIGN KEY (referrer_id) REFERENCES account (id),\n FOREIGN KEY (chef_id) REFERENCES account (id)\n );\n\n-- Table activity\nCREATE TABLE\n activity (\n id SERIAL PRIMARY KEY,\n signer_id VARCHAR NOT NULL,\n receiver_id VARCHAR NOT NULL,\n timestamp TIMESTAMP NOT NULL,\n action_result JSONB,\n tx_hash VARCHAR NOT NULL,\n type\n ENUM(\n 'Donate_Direct',\n 'Donate_Pot_Public',\n 'Donate_Pot_Matching_Pool',\n 'Register',\n 'Register_Batch',\n 'Deploy_Pot',\n 'Process_Payouts',\n 'Challenge_Payout',\n 'Submit_Application',\n 'Update_Pot_Config',\n 'Add_List_Admin',\n 'Remove_List_Admin'\n ) NOT NULL\n );\n\nCREATE TABLE\n pot_admin (\n pot_id INT NOT NULL,\n admin_id VARCHAR NOT NULL,\n PRIMARY KEY (pot_id, admin_id),\n FOREIGN KEY (pot_id) REFERENCES pot (id),\n FOREIGN KEY (admin_id) REFERENCES account (id)\n );\n\nCREATE TABLE\n token_historical_data (\n token_id VARCHAR PRIMARY KEY,\n last_updated TIMESTAMP NOT NULL,\n historical_price VARCHAR NOT NULL\n );\n\n-- account index\nCREATE INDEX\n idx_acct_donations_donors ON account (\n total_donations_received_usd,\n total_matching_pool_allocations_usd,\n total_donated_usd,\n donors_count\n );\n\n-- list index\nCREATE INDEX\n idx_list_stamps ON list (created_at, updated_at);\n\nCREATE INDEX\n idx_list_id_status ON list_registration (list_id, status);\n\n-- pot index\nCREATE INDEX\n \"deploy_time_idx\" ON pot (deployed_at);\n\nCREATE INDEX\n \"idx_pot_deployer_id\" ON pot (deployer_id);\n\n-- pot application index\nCREATE INDEX\n idx_pot_application_pot_id ON pot_application (pot_id);\n\nCREATE INDEX\n idx_pot_application_applicant_id ON pot_application (applicant_id);\n\nCREATE INDEX\n idx_pot_application_submitted_at ON pot_application (submitted_at);\n\nCREATE INDEX\n idx_application_period ON pot (application_start, application_end);\n\nCREATE INDEX\n idx_matching_period ON pot (matching_round_start, matching_round_end);\n\n-- payout index\nCREATE INDEX\n idx_pot_payout_recipient_id ON pot_payout (recipient_id);\n\n-- donation index\nCREATE INDEX\n idx_donation_donor_id ON donation (donor_id);\n\nCREATE INDEX\n idx_donation_pot_id ON donation (pot_id);\n\nCREATE INDEX\n idx_donation_donated_at ON donation (donated_at);\n\n-- activity index\nCREATE INDEX\n idx_activity_timestamp ON activity (timestamp);\n\n-- CREATE INDEX idx_pot_payout_recipient_id ON pot_payout (recipient_id);\n-- CREATE INDEX idx_pot_payout_ft_id ON pot_payout (ft_id);\nCREATE INDEX\n idx_pot_payout_paid_at ON pot_payout (paid_at);\n", "start_block": { "HEIGHT": 112618275 }, "rule": { "kind": "ACTION_ANY", "affected_account_id": "*.potlock.near", "status": "SUCCESS" } }
Empty result
Registering function index_potlock_test for account 0xprometheus.near
Receipt:
Predecessor ID:
Receiver ID:
Gas Burned:
223 Ggas
Tokens Burned:
0 
Transferred 0.06934  to 0xprometheus.near
Empty result
No logs