const accountId = context.accountId; const daoId = props.daoId ?? "onboarddao.sputnik-dao.near"; const role = props.role ?? "council"; if (!accountId) { return "Please connect your NEAR wallet :)"; } const handleProposal = () => { const gas = 200000000000000; const deposit = 100000000000000000000000; Near.call([ { contractName: daoId, methodName: "add_proposal", args: { proposal: { description: "potential member", kind: { AddMemberToRole: { member_id: accountId, role: role, }, }, }, }, gas: gas, deposit: deposit, }, ]); }; const proposalKinds = { ChangeConfig: "config", ChangePolicy: "policy", AddMemberToRole: "add_member_to_role", RemoveMemberFromRole: "remove_member_from_role", FunctionCall: "call", UpgradeSelf: "upgrade_self", UpgradeRemote: "upgrade_remote", Transfer: "transfer", SetStakingContract: "set_vote_token", AddBounty: "add_bounty", BountyDone: "bounty_done", Vote: "vote", FactoryInfoUpdate: "factory_info_update", ChangePolicyAddOrUpdateRole: "policy_add_or_update_role", ChangePolicyRemoveRole: "policy_remove_role", ChangePolicyUpdateDefaultVotePolicy: "policy_update_default_vote_policy", ChangePolicyUpdateParameters: "policy_update_parameters", }; const actions = { AddProposal: "AddProposal", VoteApprove: "VoteApprove", VoteReject: "VoteReject", VoteRemove: "VoteRemove", }; // -- Get all the roles from the DAO policy let roles = Near.view(daoId, "get_policy"); roles = roles === null ? [] : roles.roles; const isUserAllowedTo = (user, kind, action) => { // -- Filter the user roles const userRoles = []; for (const role of roles) { if (role.kind === "Everyone") { userRoles.push(role); continue; } if (!role.kind.Group) continue; if (user && role.kind.Group && role.kind.Group.includes(user)) { userRoles.push(role); } } // -- Check if the user is allowed to perform the action let allowed = false; userRoles .filter(({ permissions }) => { const allowedRole = permissions.includes(`${kind.toString()}:${action.toString()}`) || permissions.includes(`${kind.toString()}:*`) || permissions.includes(`*:${action.toString()}`) || permissions.includes("*:*"); allowed = allowed || allowedRole; return allowedRole; }) .map((role) => role.name); return allowed; }; const canProposeAddMember = isUserAllowedTo( context.accountId, proposalKinds.AddMemberToRole, actions.AddProposal ); const Wrapper = styled.div` .join-button { display: inline-flex; align-items: center; justify-content: center; gap: 8px; padding: 8px 16px; height: 32px; border-radius: 100px; font-weight: 600; font-size: 12px; line-height: 15px; text-align: center; cursor: pointer; background: #FBFCFD; border: 1px solid #D7DBDF; color: ${props.primary ? "#006ADC" : "#11181C"} !important; white-space: nowrap; &:hover, &:focus { background: #ECEDEE; text-decoration: none; outline: none; } i { display: inline-block; transform: rotate(90deg); color: #7E868C; } } `; return ( <> {canProposeAddMember && ( <Wrapper> <button className="join-button" onClick={handleProposal}> Ask to Join </button> </Wrapper> )} </> );