diff --git a/replacements.dev.json b/replacements.dev.json index 300e26a6a..0e49e0969 100644 --- a/replacements.dev.json +++ b/replacements.dev.json @@ -4,5 +4,6 @@ "REPL_DEVHUB_CONTRACT": "thomaspreview.testnet", "REPL_NEAR": "discom.testnet", "REPL_MOB": "eugenethedream", - "REPL_EFIZ": "efiz.testnet" + "REPL_EFIZ": "efiz.testnet", + "REPL_SOCIAL_CONTRACT": "v1.social08.testnet" } diff --git a/replacements.mainnet.json b/replacements.mainnet.json index 463f96a69..0e6027863 100644 --- a/replacements.mainnet.json +++ b/replacements.mainnet.json @@ -4,5 +4,6 @@ "REPL_DEVHUB_CONTRACT": "devgovgigs.near", "REPL_NEAR": "near", "REPL_MOB": "mob.near", - "REPL_EFIZ": "efiz.near" + "REPL_EFIZ": "efiz.near", + "REPL_SOCIAL_CONTRACT": "social.near" } diff --git a/replacements.testnet.json b/replacements.testnet.json index d2e0e56e7..d8e38d2d3 100644 --- a/replacements.testnet.json +++ b/replacements.testnet.json @@ -4,5 +4,6 @@ "REPL_DEVHUB_CONTRACT": "thomaselliot.testnet", "REPL_NEAR": "discom.testnet", "REPL_MOB": "eugenethedream", - "REPL_EFIZ": "efiz.testnet" + "REPL_EFIZ": "efiz.testnet", + "REPL_SOCIAL_CONTRACT": "v1.social08.testnet" } diff --git a/src/core/lib/common.jsx b/src/core/lib/common.jsx new file mode 100644 index 000000000..f9af877f7 --- /dev/null +++ b/src/core/lib/common.jsx @@ -0,0 +1,16 @@ +// https://docs.rs/near-sdk/latest/near_sdk/env/constant.STORAGE_PRICE_PER_BYTE.html +const STORAGE_PRICE_PER_BYTE = "10000000000000000000"; +// https://github.com/NearSocial/social-db/blob/d28c647252ce25a06c70c3b7f4930ccdcd217fd9/contract/src/account.rs#L8C5-L8C50 +const MIN_STORAGE_BYTES = "2000"; +const MIN_STORAGE_COST = Big(STORAGE_PRICE_PER_BYTE).times(MIN_STORAGE_BYTES); + +// in case the user is new and doesn't have min storage cost, increasing the deposit +function getDepositAmountForWriteAccess(userStorageDeposit) { + const depositAmt = Big(userStorageDeposit?.available).gt(MIN_STORAGE_COST) + ? Big(10).pow(22) + : Big(MIN_STORAGE_COST).plus(Big(10).pow(22)); + + return depositAmt; +} + +return { getDepositAmountForWriteAccess }; diff --git a/src/devhub/entity/post/Post.jsx b/src/devhub/entity/post/Post.jsx index 01a6c99bb..43b696ca7 100644 --- a/src/devhub/entity/post/Post.jsx +++ b/src/devhub/entity/post/Post.jsx @@ -1,7 +1,11 @@ // Ideally, this would be a page const { href } = VM.require("${REPL_DEVHUB}/widget/core.lib.url"); +const { getDepositAmountForWriteAccess } = VM.require( + "${REPL_DEVHUB}/widget/core.lib.common" +); +getDepositAmountForWriteAccess || (getDepositAmountForWriteAccess = () => {}); const { draftState, onDraftStateChange } = VM.require( "${REPL_DEVHUB}/widget/devhub.entity.post.draft" ); @@ -262,12 +266,24 @@ const containsLike = props.isPreview const likeBtnClass = containsLike ? fillIcons.Like : emptyIcons.Like; // This must be outside onLike, because Near.view returns null at first, and when the view call finished, it returns true/false. // If checking this inside onLike, it will give `null` and we cannot tell the result is true or false. -let grantNotify = Near.view("social.near", "is_write_permission_granted", { - predecessor_id: "${REPL_DEVHUB_CONTRACT}", - key: context.accountId + "/index/notify", -}); +let grantNotify = Near.view( + "${REPL_SOCIAL_CONTRACT}", + "is_write_permission_granted", + { + predecessor_id: "${REPL_DEVHUB_CONTRACT}", + key: context.accountId + "/index/notify", + } +); + +const userStorageDeposit = Near.view( + "${REPL_SOCIAL_CONTRACT}", + "storage_balance_of", + { + account_id: context.accountId, + } +); -if (grantNotify === null) { +if (grantNotify === null || userStorageDeposit === null) { return; } @@ -289,14 +305,14 @@ const onLike = () => { if (grantNotify === false) { likeTxn.unshift({ - contractName: "social.near", + contractName: "${REPL_SOCIAL_CONTRACT}", methodName: "grant_write_permission", args: { predecessor_id: "${REPL_DEVHUB_CONTRACT}", keys: [context.accountId + "/index/notify"], }, gas: Big(10).pow(14), - deposit: Big(10).pow(22), + deposit: getDepositAmountForWriteAccess(userStorageDeposit), }); } diff --git a/src/devhub/entity/post/PostEditor.jsx b/src/devhub/entity/post/PostEditor.jsx index 8fb798e93..da795dc8e 100644 --- a/src/devhub/entity/post/PostEditor.jsx +++ b/src/devhub/entity/post/PostEditor.jsx @@ -1,5 +1,9 @@ const { normalize } = VM.require("${REPL_DEVHUB}/widget/core.lib.stringUtils"); +const { getDepositAmountForWriteAccess } = VM.require( + "${REPL_DEVHUB}/widget/core.lib.common" +); +getDepositAmountForWriteAccess || (getDepositAmountForWriteAccess = () => {}); normalize || (normalize = () => {}); const CenteredMessage = styled.div` @@ -33,6 +37,14 @@ if (!context.accountId) { ); } +const userStorageDeposit = Near.view( + "${REPL_SOCIAL_CONTRACT}", + "storage_balance_of", + { + account_id: context.accountId, + } +); + const cleanDescription = (description) => { return description ? description.replace( @@ -256,11 +268,15 @@ const typeSwitch = (optionName) => { // This must be outside onClick, because Near.view returns null at first, and when the view call finished, it returns true/false. // If checking this inside onClick, it will give `null` and we cannot tell the result is true or false. -let grantNotify = Near.view("social.near", "is_write_permission_granted", { - predecessor_id: "${REPL_DEVHUB_CONTRACT}", - key: context.accountId + "/index/notify", -}); -if (grantNotify === null) { +let grantNotify = Near.view( + "${REPL_SOCIAL_CONTRACT}", + "is_write_permission_granted", + { + predecessor_id: "${REPL_DEVHUB_CONTRACT}", + key: context.accountId + "/index/notify", + } +); +if (grantNotify === null || userStorageDeposit === null) { return; } @@ -356,14 +372,14 @@ const onSubmit = () => { if (mode == "Create" || mode == "Edit") { if (grantNotify === false) { txn.unshift({ - contractName: "social.near", + contractName: "${REPL_SOCIAL_CONTRACT}", methodName: "grant_write_permission", args: { predecessor_id: "${REPL_DEVHUB_CONTRACT}", keys: [context.accountId + "/index/notify"], }, gas: Big(10).pow(14), - deposit: Big(10).pow(22), + deposit: getDepositAmountForWriteAccess(userStorageDeposit), }); } Near.call(txn);