mirror of
https://github.com/MAGICGrants/campaign-site.git
synced 2026-01-09 12:27:59 -05:00
feat: add different color schemes for each fund and some fixes
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
APP_URL="http://localhost:3000"
|
||||
DATABASE_URL="postgresql://docker:docker@localhost:5432/monerofund?schema=public"
|
||||
DATABASE_URL="postgresql://docker:docker@localhost:5432/magic?schema=public"
|
||||
|
||||
NEXTAUTH_URL="http://localhost:3000"
|
||||
NEXTAUTH_URL_INTERNAL="http://localhost:3000"
|
||||
@@ -19,6 +19,7 @@ STRIPE_PRIVACY_GUIDES_WEBHOOK_SECRET=""
|
||||
STRIPE_GENERAL_SECRET_KEY=""
|
||||
STRIPE_GENERAL_WEBHOOK_SECRET=""
|
||||
|
||||
KEYCLOAK_URL="http://localhost:8080"
|
||||
KEYCLOAK_CLIENT_ID="app"
|
||||
KEYCLOAK_CLIENT_SECRET=""
|
||||
KEYCLOAK_REALM_NAME="magic"
|
||||
|
||||
@@ -7,10 +7,7 @@ const CustomLink = ({
|
||||
href,
|
||||
className,
|
||||
...rest
|
||||
}: DetailedHTMLProps<
|
||||
AnchorHTMLAttributes<HTMLAnchorElement>,
|
||||
HTMLAnchorElement
|
||||
>) => {
|
||||
}: DetailedHTMLProps<AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>) => {
|
||||
const isInternalLink = href && href.startsWith('/')
|
||||
const isAnchorLink = href && href.startsWith('#')
|
||||
|
||||
@@ -19,10 +16,7 @@ const CustomLink = ({
|
||||
return (
|
||||
<Link
|
||||
href={href}
|
||||
className={cn(
|
||||
'text-primary hover:text-primary-DEFAULT_HOVER',
|
||||
className
|
||||
)}
|
||||
className={cn('text-primary hover:text-primary-hover', className)}
|
||||
{...rest}
|
||||
/>
|
||||
)
|
||||
@@ -30,14 +24,7 @@ const CustomLink = ({
|
||||
|
||||
if (isAnchorLink) {
|
||||
return (
|
||||
<a
|
||||
href={href}
|
||||
className={cn(
|
||||
'text-primary hover:text-primary-DEFAULT_HOVER',
|
||||
className
|
||||
)}
|
||||
{...rest}
|
||||
/>
|
||||
<a href={href} className={cn('text-primary hover:text-primary-hover', className)} {...rest} />
|
||||
)
|
||||
}
|
||||
|
||||
@@ -45,7 +32,7 @@ const CustomLink = ({
|
||||
<a
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className={cn('text-primary hover:text-primary-DEFAULT_HOVER', className)}
|
||||
className={cn('text-primary hover:text-primary-hover', className)}
|
||||
href={href}
|
||||
{...rest}
|
||||
/>
|
||||
|
||||
@@ -134,8 +134,8 @@ const DonationFormModal: React.FC<Props> = ({ project }) => {
|
||||
className="rounded-xl"
|
||||
/>
|
||||
<div className="flex flex-col">
|
||||
<h2 className="font-sans font-bold">{project.title}</h2>
|
||||
<h3 className="text-textgray font-sans">Pledge your support</h3>
|
||||
<h2 className="font-semibold">{project.title}</h2>
|
||||
<h3 className="text-gray-500">Pledge your support</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -193,7 +193,7 @@ const DonationFormModal: React.FC<Props> = ({ project }) => {
|
||||
{[50, 100, 250, 500].map((value, index) => (
|
||||
<Button
|
||||
key={`amount-button-${index}`}
|
||||
variant="outline"
|
||||
variant="light"
|
||||
size="sm"
|
||||
type="button"
|
||||
onClick={() =>
|
||||
|
||||
@@ -6,14 +6,14 @@ function Footer() {
|
||||
return (
|
||||
<footer>
|
||||
<div className="mb-4 mt-16 flex flex-col items-center">
|
||||
<div className="space-x-4 text-center text-xs text-gray-500 dark:text-gray-400">
|
||||
MAGIC Grants is a 501(c)(3) non-profit organization. All gifts and
|
||||
donations are tax-deductible to the full extent of the law.
|
||||
<div className="space-x-4 text-center text-xs text-gray-500">
|
||||
MAGIC Grants is a 501(c)(3) non-profit organization. All gifts and donations are
|
||||
tax-deductible to the full extent of the law.
|
||||
</div>
|
||||
<div className="mb-2 flex space-x-2 text-xs text-gray-500 dark:text-gray-400"></div>
|
||||
<div className="space-x-4 text-center text-xs text-gray-500 dark:text-gray-400">
|
||||
© {new Date().getFullYear()} MAGIC Grants. This website builds upon
|
||||
technology by Open Sats.
|
||||
<div className="mb-2 flex space-x-2 text-xs text-gray-500"></div>
|
||||
<div className="space-x-4 text-center text-xs text-gray-500">
|
||||
© {new Date().getFullYear()} MAGIC Grants. This website builds upon technology by Open
|
||||
Sats.
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
@@ -22,6 +22,8 @@ import {
|
||||
DropdownMenuTrigger,
|
||||
} from './ui/dropdown-menu'
|
||||
import { useFundSlug } from '../utils/use-fund-slug'
|
||||
import CustomLink from './CustomLink'
|
||||
import { funds } from '../utils/funds'
|
||||
|
||||
const Header = () => {
|
||||
const [registerIsOpen, setRegisterIsOpen] = useState(false)
|
||||
@@ -37,27 +39,35 @@ const Header = () => {
|
||||
}
|
||||
}, [router.query.loginEmail])
|
||||
|
||||
if (!fundSlug) return <></>
|
||||
|
||||
const fund = funds[fundSlug]
|
||||
|
||||
return (
|
||||
<header className="flex items-center justify-between py-10">
|
||||
<div>
|
||||
<Link href="/" aria-label="Monero Fund" className="flex items-center mr-3 gap-4">
|
||||
<Link
|
||||
href={`/${fundSlug}`}
|
||||
aria-label={fund.title}
|
||||
className="flex items-center mr-3 gap-4"
|
||||
>
|
||||
<Logo className="w-12 h-12" />
|
||||
<span className="text-foreground text-lg font-bold">MAGIC Monero Fund</span>
|
||||
<span className="text-foreground text-lg font-bold">{fund.title}</span>
|
||||
</Link>
|
||||
</div>
|
||||
<div className="flex gap-2 items-center text-base leading-5">
|
||||
{headerNavLinks.map((link) => (
|
||||
<Link
|
||||
<CustomLink
|
||||
key={link.title}
|
||||
href={`/${fundSlug}/${link.href}`}
|
||||
className={
|
||||
link.isButton
|
||||
? 'rounded border border-orange-500 bg-transparent px-4 py-2 font-semibold text-orange-500 hover:border-transparent hover:bg-orange-500 hover:text-white'
|
||||
: 'hidden p-1 font-medium text-gray-900 dark:text-gray-100 sm:p-4 md:inline-block'
|
||||
? 'rounded border border-primary bg-transparent px-4 py-2 font-semibold text-primary hover:border-transparent hover:bg-primary hover:text-white'
|
||||
: 'hidden p-1 font-medium text-gray-900 sm:p-4 md:inline-block'
|
||||
}
|
||||
>
|
||||
{link.title}
|
||||
</Link>
|
||||
</CustomLink>
|
||||
))}
|
||||
|
||||
{session.status !== 'authenticated' && (
|
||||
@@ -91,7 +101,7 @@ const Header = () => {
|
||||
</>
|
||||
)}
|
||||
|
||||
<ThemeSwitch />
|
||||
{/* <ThemeSwitch /> */}
|
||||
|
||||
{session.status === 'authenticated' && (
|
||||
<DropdownMenu>
|
||||
@@ -105,24 +115,14 @@ const Header = () => {
|
||||
<DropdownMenuContent>
|
||||
<DropdownMenuLabel>My Account</DropdownMenuLabel>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItem>
|
||||
<Link
|
||||
href={`/${fundSlug}/account/my-donations`}
|
||||
className="text-foreground hover:text-foreground"
|
||||
>
|
||||
My Donations
|
||||
</Link>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem>
|
||||
<Link
|
||||
href={`/${fundSlug}/account/my-memberships`}
|
||||
className="text-foreground hover:text-foreground"
|
||||
>
|
||||
My Memberships
|
||||
</Link>
|
||||
</DropdownMenuItem>
|
||||
<CustomLink href={`/${fundSlug}/account/my-donations`} className="text-foreground">
|
||||
<DropdownMenuItem>My Donations</DropdownMenuItem>
|
||||
</CustomLink>
|
||||
<CustomLink href={`/${fundSlug}/account/my-memberships`} className="text-foreground">
|
||||
<DropdownMenuItem>My Memberships</DropdownMenuItem>
|
||||
</CustomLink>
|
||||
<DropdownMenuItem>Settings</DropdownMenuItem>
|
||||
<DropdownMenuItem onClick={() => signOut({ callbackUrl: '/' })}>
|
||||
<DropdownMenuItem onClick={() => signOut({ callbackUrl: `/${fundSlug}` })}>
|
||||
Logout
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
|
||||
@@ -16,9 +16,7 @@ const inter = Inter({
|
||||
const LayoutWrapper = ({ children }: Props) => {
|
||||
return (
|
||||
<SectionContainer>
|
||||
<div
|
||||
className={`${inter.className} flex h-screen flex-col justify-between font-sans`}
|
||||
>
|
||||
<div className={`${inter.className} flex h-screen flex-col justify-between`}>
|
||||
<Header />
|
||||
<main className="grow">{children}</main>
|
||||
<Footer />
|
||||
|
||||
@@ -11,6 +11,7 @@ import { Input } from './ui/input'
|
||||
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from './ui/form'
|
||||
import { Button } from './ui/button'
|
||||
import { useToast } from './ui/use-toast'
|
||||
import { useFundSlug } from '../utils/use-fund-slug'
|
||||
|
||||
const schema = z.object({
|
||||
email: z.string().email(),
|
||||
@@ -28,6 +29,7 @@ type Props = {
|
||||
function LoginFormModal({ close, openPasswordResetModal, openRegisterModal }: Props) {
|
||||
const { toast } = useToast()
|
||||
const router = useRouter()
|
||||
const fundSlug = useFundSlug()
|
||||
const form = useForm<LoginFormInputs>({
|
||||
resolver: zodResolver(schema),
|
||||
defaultValues: { email: '', password: '' },
|
||||
@@ -35,10 +37,11 @@ function LoginFormModal({ close, openPasswordResetModal, openRegisterModal }: Pr
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
if (!fundSlug) return
|
||||
if (router.query.loginEmail) {
|
||||
form.setValue('email', router.query.loginEmail as string)
|
||||
setTimeout(() => form.setFocus('password'), 100)
|
||||
router.replace('/')
|
||||
router.replace(`/${fundSlug}`)
|
||||
}
|
||||
}, [router.query.loginEmail])
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -29,7 +29,7 @@ const MobileNav = () => {
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 20 20"
|
||||
fill="currentColor"
|
||||
className="h-8 w-8 text-gray-900 dark:text-gray-100"
|
||||
className="h-8 w-8 text-gray-900"
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
@@ -39,7 +39,7 @@ const MobileNav = () => {
|
||||
</svg>
|
||||
</button>
|
||||
<div
|
||||
className={`fixed left-0 top-0 z-10 h-full w-full transform bg-gray-200 opacity-95 duration-300 ease-in-out dark:bg-gray-800 ${
|
||||
className={`fixed left-0 top-0 z-10 h-full w-full transform bg-gray-200 opacity-95 duration-300 ease-in-out ${
|
||||
navShow ? 'translate-x-0' : 'translate-x-full'
|
||||
}`}
|
||||
>
|
||||
@@ -53,7 +53,7 @@ const MobileNav = () => {
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 20 20"
|
||||
fill="currentColor"
|
||||
className="h-8 w-8 text-gray-900 dark:text-gray-100"
|
||||
className="h-8 w-8 text-gray-900"
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
@@ -68,7 +68,7 @@ const MobileNav = () => {
|
||||
<div key={link.title} className="px-12 py-4">
|
||||
<CustomLink
|
||||
href={link.href}
|
||||
className="text-2xl font-bold tracking-tight text-gray-900 dark:text-gray-100"
|
||||
className="text-2xl font-bold tracking-tight text-gray-900"
|
||||
onClick={onToggleNav}
|
||||
>
|
||||
{link.title}
|
||||
|
||||
@@ -13,7 +13,7 @@ interface Props {
|
||||
|
||||
export default function PageHeading({ project, children }: Props) {
|
||||
return (
|
||||
<div className="divide-y divide-gray-200 dark:divide-gray-700">
|
||||
<div className="divide-y divide-gray-200">
|
||||
<div className="items-start space-y-2 pb-8 pt-6 md:space-y-5 xl:grid xl:grid-cols-3 xl:gap-x-8">
|
||||
<Image
|
||||
src={project.coverImage}
|
||||
@@ -23,7 +23,7 @@ export default function PageHeading({ project, children }: Props) {
|
||||
className="h-60 w-60 mx-auto my-auto object-contain row-span-3 hidden xl:block"
|
||||
/>
|
||||
|
||||
<h1 className="text-3xl font-extrabold leading-9 tracking-tight text-gray-900 dark:text-gray-100 sm:text-4xl sm:leading-10 md:text-6xl md:leading-14 xl:col-span-2">
|
||||
<h1 className="text-3xl font-extrabold leading-9 tracking-tight text-gray-900 sm:text-4xl sm:leading-10 md:text-6xl md:leading-14 xl:col-span-2">
|
||||
{project.title}
|
||||
</h1>
|
||||
|
||||
@@ -33,18 +33,12 @@ export default function PageHeading({ project, children }: Props) {
|
||||
|
||||
<div className="flex space-x-3 items-center">
|
||||
<p>
|
||||
by{' '}
|
||||
<a className="text-orange-500" href={project.personalWebsite}>
|
||||
{project.nym}
|
||||
</a>
|
||||
by <CustomLink href={project.personalWebsite}>{project.nym}</CustomLink>
|
||||
</p>
|
||||
|
||||
<SocialIcon kind="website" href={project.website} />
|
||||
{project.twitter && (
|
||||
<SocialIcon
|
||||
kind="twitter"
|
||||
href={`https://twitter.com/${project.twitter}`}
|
||||
/>
|
||||
<SocialIcon kind="twitter" href={`https://twitter.com/${project.twitter}`} />
|
||||
)}
|
||||
<SocialIcon kind="github" href={project.git} />
|
||||
{/* {nostr && (
|
||||
|
||||
@@ -4,8 +4,8 @@ type ProgressProps = {
|
||||
|
||||
const Progress = ({ percent }: ProgressProps) => {
|
||||
return (
|
||||
<div className="w-full flex flex-col items-center">
|
||||
<div className="w-full bg-gray-200 rounded-full h-4">
|
||||
<div className="w-full flex flex-col items-center space-y-2">
|
||||
<div className="w-full bg-primary/15 rounded-full h-4">
|
||||
<div
|
||||
className="bg-green-500 h-4 rounded-full text-xs"
|
||||
style={{ width: `${percent}%` }}
|
||||
|
||||
@@ -38,8 +38,7 @@ const ProjectCard: React.FC<ProjectCardProps> = ({ project, customImageStyles })
|
||||
// cardStyle =
|
||||
// 'h-full space-y-4 rounded-xl border-b-4 border-orange-400 bg-stone-100 dark:border-orange-400 dark:bg-stone-900'
|
||||
// } else {
|
||||
cardStyle =
|
||||
'h-full space-y-4 rounded-xl border-b-4 border-orange-500 bg-stone-100 dark:bg-stone-900'
|
||||
cardStyle = 'h-full space-y-4 rounded-xl border-b-4 border-primary bg-primary/5'
|
||||
// }
|
||||
|
||||
return (
|
||||
|
||||
@@ -4,7 +4,6 @@ import ProjectCard from './ProjectCard'
|
||||
import Link from 'next/link'
|
||||
import { ProjectItem } from '../utils/types'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { FundSlug } from '../utils/funds'
|
||||
|
||||
type ProjectListProps = {
|
||||
header?: string
|
||||
|
||||
@@ -24,6 +24,7 @@ import {
|
||||
import { Button } from './ui/button'
|
||||
import { useToast } from './ui/use-toast'
|
||||
import { trpc } from '../utils/trpc'
|
||||
import { useFundSlug } from '../utils/use-fund-slug'
|
||||
|
||||
const schema = z
|
||||
.object({
|
||||
@@ -44,11 +45,14 @@ type Props = { close: () => void; openLoginModal: () => void }
|
||||
function RegisterFormModal({ close, openLoginModal }: Props) {
|
||||
const { toast } = useToast()
|
||||
const form = useForm<RegisterFormInputs>({ resolver: zodResolver(schema) })
|
||||
const fundSlug = useFundSlug()
|
||||
const registerMutation = trpc.auth.register.useMutation()
|
||||
|
||||
async function onSubmit(data: RegisterFormInputs) {
|
||||
if (!fundSlug) return
|
||||
|
||||
try {
|
||||
await registerMutation.mutateAsync(data)
|
||||
await registerMutation.mutateAsync({ ...data, fundSlug })
|
||||
|
||||
toast({
|
||||
title: 'Please check your email to verify your account.',
|
||||
|
||||
@@ -27,11 +27,7 @@ type Props = {
|
||||
}
|
||||
|
||||
const SocialIcon = ({ kind, href, size = 5 }: Props) => {
|
||||
if (
|
||||
!href ||
|
||||
(kind === 'mail' &&
|
||||
!/^mailto:\w+([.-]?\w+)@\w+([.-]?\w+)(.\w{2,3})+$/.test(href))
|
||||
)
|
||||
if (!href || (kind === 'mail' && !/^mailto:\w+([.-]?\w+)@\w+([.-]?\w+)(.\w{2,3})+$/.test(href)))
|
||||
return <></>
|
||||
|
||||
const SocialSvg = components[kind]
|
||||
@@ -44,9 +40,7 @@ const SocialIcon = ({ kind, href, size = 5 }: Props) => {
|
||||
href={href}
|
||||
>
|
||||
<span className="sr-only">{kind}</span>
|
||||
<SocialSvg
|
||||
className={`fill-current text-gray-700 hover:text-orange-500 dark:text-gray-200 dark:hover:text-orange-500 h-${size} w-${size}`}
|
||||
/>
|
||||
<SocialSvg className={`fill-current text-gray-700 hover:text-primary h-${size} w-${size}`} />
|
||||
</a>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -9,10 +9,7 @@ const Avatar = React.forwardRef<
|
||||
>(({ className, ...props }, ref) => (
|
||||
<AvatarPrimitive.Root
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full',
|
||||
className
|
||||
)}
|
||||
className={cn('relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full', className)}
|
||||
{...props}
|
||||
/>
|
||||
))
|
||||
@@ -37,7 +34,7 @@ const AvatarFallback = React.forwardRef<
|
||||
<AvatarPrimitive.Fallback
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'flex h-full w-full items-center justify-center rounded-full bg-muted',
|
||||
'flex h-full w-full items-center justify-center rounded-full bg-primary/10',
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
|
||||
@@ -5,25 +5,22 @@ import { cva, type VariantProps } from 'class-variance-authority'
|
||||
import { cn } from '../../utils/cn'
|
||||
|
||||
const buttonVariants = cva(
|
||||
'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50',
|
||||
'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md font-semibold text-sm transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50',
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
default:
|
||||
'bg-primary text-primary-foreground shadow hover:bg-primary/90',
|
||||
destructive:
|
||||
'bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90',
|
||||
default: 'bg-primary text-primary-foreground shadow hover:bg-primary-hover',
|
||||
light: 'text-primary bg-primary/10 hover:bg-primary hover:text-primary-foreground',
|
||||
destructive: 'bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90',
|
||||
outline:
|
||||
'border border-primary bg-background shadow-sm hover:bg-primary hover:text-primary-foreground',
|
||||
secondary:
|
||||
'bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80',
|
||||
ghost: 'hover:bg-accent hover:text-accent-foreground',
|
||||
'text-primary border border-primary bg-background shadow-sm hover:bg-primary hover:text-primary-foreground',
|
||||
ghost: 'hover:bg-primary/20 hover:text-primary-foreground',
|
||||
link: 'text-primary underline-offset-4 hover:underline',
|
||||
},
|
||||
size: {
|
||||
default: 'h-9 px-4 py-2',
|
||||
sm: 'h-8 rounded-md px-3 text-xs',
|
||||
lg: 'h-10 rounded-md px-8',
|
||||
lg: 'h-10 rounded-md px-10 text-md',
|
||||
icon: 'h-9 w-9',
|
||||
},
|
||||
},
|
||||
@@ -44,11 +41,7 @@ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
||||
({ className, variant, size, asChild = false, ...props }, ref) => {
|
||||
const Comp = asChild ? Slot : 'button'
|
||||
return (
|
||||
<Comp
|
||||
className={cn(buttonVariants({ variant, size, className }))}
|
||||
ref={ref}
|
||||
{...props}
|
||||
/>
|
||||
<Comp className={cn(buttonVariants({ variant, size, className }))} ref={ref} {...props} />
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
@@ -39,7 +39,7 @@ const DialogContent = React.forwardRef<
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
<DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground">
|
||||
<DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-background data-[state=open]:text-muted-foreground">
|
||||
<Cross2Icon className="h-4 w-4" />
|
||||
<span className="sr-only">Close</span>
|
||||
</DialogPrimitive.Close>
|
||||
@@ -48,29 +48,14 @@ const DialogContent = React.forwardRef<
|
||||
))
|
||||
DialogContent.displayName = DialogPrimitive.Content.displayName
|
||||
|
||||
const DialogHeader = ({
|
||||
className,
|
||||
...props
|
||||
}: React.HTMLAttributes<HTMLDivElement>) => (
|
||||
<div
|
||||
className={cn(
|
||||
'flex flex-col space-y-1.5 text-center sm:text-left',
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
const DialogHeader = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (
|
||||
<div className={cn('flex flex-col space-y-1.5 text-center sm:text-left', className)} {...props} />
|
||||
)
|
||||
DialogHeader.displayName = 'DialogHeader'
|
||||
|
||||
const DialogFooter = ({
|
||||
className,
|
||||
...props
|
||||
}: React.HTMLAttributes<HTMLDivElement>) => (
|
||||
const DialogFooter = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (
|
||||
<div
|
||||
className={cn(
|
||||
'flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2',
|
||||
className
|
||||
)}
|
||||
className={cn('flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2', className)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
@@ -82,10 +67,7 @@ const DialogTitle = React.forwardRef<
|
||||
>(({ className, ...props }, ref) => (
|
||||
<DialogPrimitive.Title
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'text-lg font-semibold leading-none tracking-tight',
|
||||
className
|
||||
)}
|
||||
className={cn('text-lg font-semibold leading-none tracking-tight', className)}
|
||||
{...props}
|
||||
/>
|
||||
))
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
import * as React from 'react'
|
||||
import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu'
|
||||
import {
|
||||
CheckIcon,
|
||||
ChevronRightIcon,
|
||||
DotFilledIcon,
|
||||
} from '@radix-ui/react-icons'
|
||||
import { CheckIcon, ChevronRightIcon, DotFilledIcon } from '@radix-ui/react-icons'
|
||||
|
||||
import { cn } from '../../utils/cn'
|
||||
|
||||
@@ -29,7 +25,7 @@ const DropdownMenuSubTrigger = React.forwardRef<
|
||||
<DropdownMenuPrimitive.SubTrigger
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent',
|
||||
'flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-primary/10 data-[state=open]:bg-primary',
|
||||
inset && 'pl-8',
|
||||
className
|
||||
)}
|
||||
@@ -39,8 +35,7 @@ const DropdownMenuSubTrigger = React.forwardRef<
|
||||
<ChevronRightIcon className="ml-auto h-4 w-4" />
|
||||
</DropdownMenuPrimitive.SubTrigger>
|
||||
))
|
||||
DropdownMenuSubTrigger.displayName =
|
||||
DropdownMenuPrimitive.SubTrigger.displayName
|
||||
DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName
|
||||
|
||||
const DropdownMenuSubContent = React.forwardRef<
|
||||
React.ElementRef<typeof DropdownMenuPrimitive.SubContent>,
|
||||
@@ -49,14 +44,13 @@ const DropdownMenuSubContent = React.forwardRef<
|
||||
<DropdownMenuPrimitive.SubContent
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
|
||||
'z-50 min-w-[8rem] overflow-hidden rounded-md border bg-white p-1 text-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
))
|
||||
DropdownMenuSubContent.displayName =
|
||||
DropdownMenuPrimitive.SubContent.displayName
|
||||
DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName
|
||||
|
||||
const DropdownMenuContent = React.forwardRef<
|
||||
React.ElementRef<typeof DropdownMenuPrimitive.Content>,
|
||||
@@ -67,7 +61,7 @@ const DropdownMenuContent = React.forwardRef<
|
||||
ref={ref}
|
||||
sideOffset={sideOffset}
|
||||
className={cn(
|
||||
'z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md',
|
||||
'z-50 min-w-[8rem] overflow-hidden rounded-md shadow-sm bg-white p-1 text-foreground',
|
||||
'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
|
||||
className
|
||||
)}
|
||||
@@ -86,7 +80,7 @@ const DropdownMenuItem = React.forwardRef<
|
||||
<DropdownMenuPrimitive.Item
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
|
||||
'relative flex select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-primary/10 focus:text-primary data-[disabled]:pointer-events-none data-[disabled]:opacity-50 cursor-pointer',
|
||||
inset && 'pl-8',
|
||||
className
|
||||
)}
|
||||
@@ -102,7 +96,7 @@ const DropdownMenuCheckboxItem = React.forwardRef<
|
||||
<DropdownMenuPrimitive.CheckboxItem
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
|
||||
'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-primary/10 focus:text-primary-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
|
||||
className
|
||||
)}
|
||||
checked={checked}
|
||||
@@ -116,8 +110,7 @@ const DropdownMenuCheckboxItem = React.forwardRef<
|
||||
{children}
|
||||
</DropdownMenuPrimitive.CheckboxItem>
|
||||
))
|
||||
DropdownMenuCheckboxItem.displayName =
|
||||
DropdownMenuPrimitive.CheckboxItem.displayName
|
||||
DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName
|
||||
|
||||
const DropdownMenuRadioItem = React.forwardRef<
|
||||
React.ElementRef<typeof DropdownMenuPrimitive.RadioItem>,
|
||||
@@ -126,7 +119,7 @@ const DropdownMenuRadioItem = React.forwardRef<
|
||||
<DropdownMenuPrimitive.RadioItem
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
|
||||
'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-primary/10 focus:text-primary-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
@@ -149,11 +142,7 @@ const DropdownMenuLabel = React.forwardRef<
|
||||
>(({ className, inset, ...props }, ref) => (
|
||||
<DropdownMenuPrimitive.Label
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'px-2 py-1.5 text-sm font-semibold',
|
||||
inset && 'pl-8',
|
||||
className
|
||||
)}
|
||||
className={cn('px-2 py-1.5 text-sm font-semibold', inset && 'pl-8', className)}
|
||||
{...props}
|
||||
/>
|
||||
))
|
||||
@@ -165,22 +154,14 @@ const DropdownMenuSeparator = React.forwardRef<
|
||||
>(({ className, ...props }, ref) => (
|
||||
<DropdownMenuPrimitive.Separator
|
||||
ref={ref}
|
||||
className={cn('-mx-1 my-1 h-px bg-muted', className)}
|
||||
className={cn('-mx-1 my-1 h-px bg-border', className)}
|
||||
{...props}
|
||||
/>
|
||||
))
|
||||
DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName
|
||||
|
||||
const DropdownMenuShortcut = ({
|
||||
className,
|
||||
...props
|
||||
}: React.HTMLAttributes<HTMLSpanElement>) => {
|
||||
return (
|
||||
<span
|
||||
className={cn('ml-auto text-xs tracking-widest opacity-60', className)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
const DropdownMenuShortcut = ({ className, ...props }: React.HTMLAttributes<HTMLSpanElement>) => {
|
||||
return <span className={cn('ml-auto text-xs tracking-widest opacity-60', className)} {...props} />
|
||||
}
|
||||
DropdownMenuShortcut.displayName = 'DropdownMenuShortcut'
|
||||
|
||||
|
||||
@@ -3,8 +3,7 @@ import { LucideIcon } from 'lucide-react'
|
||||
|
||||
import { cn } from '../../utils/cn'
|
||||
|
||||
export interface InputProps
|
||||
extends React.InputHTMLAttributes<HTMLInputElement> {
|
||||
export interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
|
||||
leftIcon?: LucideIcon
|
||||
rightIcon?: LucideIcon
|
||||
}
|
||||
@@ -18,14 +17,14 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>(
|
||||
<div className="relative">
|
||||
{LeftIcon && (
|
||||
<div className="absolute left-1.5 top-1/2 transform -translate-y-1/2">
|
||||
<LeftIcon size={18} className="text-muted-foreground" />
|
||||
<LeftIcon size={18} className="text-primary" />
|
||||
</div>
|
||||
)}
|
||||
|
||||
<input
|
||||
type={type}
|
||||
className={cn(
|
||||
'flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50',
|
||||
'flex h-9 w-full rounded-md border bg-white px-3 py-1 text-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:border-primary/70 disabled:cursor-not-allowed disabled:opacity-50',
|
||||
leftIcon ? 'pl-8' : '',
|
||||
rightIcon ? 'pr-8' : '',
|
||||
className
|
||||
@@ -36,7 +35,7 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>(
|
||||
|
||||
{RightIcon && (
|
||||
<div className="absolute right-3 top-1/2 transform -translate-y-1/2">
|
||||
<RightIcon className="text-muted-foreground" size={18} />
|
||||
<RightIcon className="text-primary" size={18} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -1,18 +1,13 @@
|
||||
import * as React from 'react'
|
||||
import { cn } from '../../utils/cn'
|
||||
|
||||
const Table = React.forwardRef<
|
||||
HTMLTableElement,
|
||||
React.HTMLAttributes<HTMLTableElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<div className="relative w-full overflow-auto">
|
||||
<table
|
||||
ref={ref}
|
||||
className={cn('w-full caption-bottom text-sm', className)}
|
||||
{...props}
|
||||
/>
|
||||
</div>
|
||||
))
|
||||
const Table = React.forwardRef<HTMLTableElement, React.HTMLAttributes<HTMLTableElement>>(
|
||||
({ className, ...props }, ref) => (
|
||||
<div className="relative w-full overflow-auto">
|
||||
<table ref={ref} className={cn('w-full caption-bottom text-sm', className)} {...props} />
|
||||
</div>
|
||||
)
|
||||
)
|
||||
Table.displayName = 'Table'
|
||||
|
||||
const TableHeader = React.forwardRef<
|
||||
@@ -27,11 +22,7 @@ const TableBody = React.forwardRef<
|
||||
HTMLTableSectionElement,
|
||||
React.HTMLAttributes<HTMLTableSectionElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<tbody
|
||||
ref={ref}
|
||||
className={cn('[&_tr:last-child]:border-0', className)}
|
||||
{...props}
|
||||
/>
|
||||
<tbody ref={ref} className={cn('[&_tr:last-child]:border-0', className)} {...props} />
|
||||
))
|
||||
TableBody.displayName = 'TableBody'
|
||||
|
||||
@@ -41,28 +32,24 @@ const TableFooter = React.forwardRef<
|
||||
>(({ className, ...props }, ref) => (
|
||||
<tfoot
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'border-t bg-muted/50 font-medium [&>tr]:last:border-b-0',
|
||||
className
|
||||
)}
|
||||
className={cn('border-t bg-muted/50 font-medium [&>tr]:last:border-b-0', className)}
|
||||
{...props}
|
||||
/>
|
||||
))
|
||||
TableFooter.displayName = 'TableFooter'
|
||||
|
||||
const TableRow = React.forwardRef<
|
||||
HTMLTableRowElement,
|
||||
React.HTMLAttributes<HTMLTableRowElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<tr
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted',
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
))
|
||||
const TableRow = React.forwardRef<HTMLTableRowElement, React.HTMLAttributes<HTMLTableRowElement>>(
|
||||
({ className, ...props }, ref) => (
|
||||
<tr
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'border-b transition-colors hover:bg-muted/20 data-[state=selected]:bg-muted/20',
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
)
|
||||
TableRow.displayName = 'TableRow'
|
||||
|
||||
const TableHead = React.forwardRef<
|
||||
@@ -99,21 +86,8 @@ const TableCaption = React.forwardRef<
|
||||
HTMLTableCaptionElement,
|
||||
React.HTMLAttributes<HTMLTableCaptionElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<caption
|
||||
ref={ref}
|
||||
className={cn('mt-4 text-sm text-muted-foreground', className)}
|
||||
{...props}
|
||||
/>
|
||||
<caption ref={ref} className={cn('mt-4 text-sm text-muted-foreground', className)} {...props} />
|
||||
))
|
||||
TableCaption.displayName = 'TableCaption'
|
||||
|
||||
export {
|
||||
Table,
|
||||
TableHeader,
|
||||
TableBody,
|
||||
TableFooter,
|
||||
TableHead,
|
||||
TableRow,
|
||||
TableCell,
|
||||
TableCaption,
|
||||
}
|
||||
export { Table, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption }
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
const headerNavLinks = [
|
||||
{title: 'Apply', href: '/apply', isButton: false},
|
||||
{title: 'FAQs', href: '/faq', isButton: false},
|
||||
{title: 'About', href: '/about', isButton: false}
|
||||
{ title: 'Apply', href: 'apply', isButton: false },
|
||||
{ title: 'FAQs', href: 'faq', isButton: false },
|
||||
{ title: 'About', href: 'about', isButton: false },
|
||||
]
|
||||
|
||||
export default headerNavLinks
|
||||
export default headerNavLinks
|
||||
|
||||
@@ -1,16 +1,135 @@
|
||||
version: '3'
|
||||
services:
|
||||
btcpayserver:
|
||||
image: 'btcpayserver/monero'
|
||||
restart: unless-stopped
|
||||
container_name: generated_btcpayserver_1
|
||||
image: ${BTCPAY_IMAGE:-btcpayserver/btcpayserver:1.13.3-altcoins}
|
||||
expose:
|
||||
- '49392'
|
||||
environment:
|
||||
- BTCPAY_HOST=localhost
|
||||
- BTCPAYGEN_CRYPTO1=xmr
|
||||
- BTCPAY_ENABLE_XMR=true
|
||||
- XMR_RPC_URL=https://xmr-node.cakewallet.com:18081
|
||||
# - XMR_WALLET_RPC_URL=https://xmr-node.cakewallet.com:18083
|
||||
# - XMR_WALLET_RPC_USER=myrpcuser
|
||||
# - XMR_WALLET_RPC_PASSWORD=myrpcpassword
|
||||
BTCPAY_POSTGRES: User ID=postgres;Host=postgres;Port=5432;Application Name=btcpayserver;Database=btcpayserver${NBITCOIN_NETWORK:-regtest}
|
||||
BTCPAY_EXPLORERPOSTGRES: User ID=postgres;Host=postgres;Port=5432;Application Name=btcpayserver;MaxPoolSize=80;Database=nbxplorer${NBITCOIN_NETWORK:-regtest}
|
||||
BTCPAY_NETWORK: ${NBITCOIN_NETWORK:-regtest}
|
||||
BTCPAY_BIND: 0.0.0.0:49392
|
||||
BTCPAY_ROOTPATH: ${BTCPAY_ROOTPATH:-/}
|
||||
BTCPAY_SSHCONNECTION: 'root@host.docker.internal'
|
||||
BTCPAY_SSHTRUSTEDFINGERPRINTS: ${BTCPAY_SSHTRUSTEDFINGERPRINTS}
|
||||
BTCPAY_SSHKEYFILE: ${BTCPAY_SSHKEYFILE}
|
||||
BTCPAY_SSHAUTHORIZEDKEYS: ${BTCPAY_SSHAUTHORIZEDKEYS}
|
||||
BTCPAY_DEBUGLOG: btcpay.log
|
||||
BTCPAY_UPDATEURL: https://api.github.com/repos/btcpayserver/btcpayserver/releases/latest
|
||||
BTCPAY_DOCKERDEPLOYMENT: 'true'
|
||||
BTCPAY_CHAINS: 'xmr'
|
||||
BTCPAY_XMR_DAEMON_URI: http://xmr-node.cakewallet.com:18081
|
||||
BTCPAY_XMR_WALLET_DAEMON_URI: http://monerod_wallet:18082
|
||||
BTCPAY_XMR_WALLET_DAEMON_WALLETDIR: /root/xmr_wallet
|
||||
# HIDDENSERVICE_NAME: BTCPayServer
|
||||
# HIDDENSERVICE_REVERSEPROXY: nginx
|
||||
# BTCPAY_TORRCFILE: /usr/local/etc/tor/torrc-2
|
||||
# BTCPAY_SOCKSENDPOINT: tor:9050
|
||||
labels:
|
||||
traefik.enable: 'true'
|
||||
traefik.http.routers.btcpayserver.rule: Host(`${BTCPAY_HOST}`)
|
||||
extra_hosts:
|
||||
- 'host.docker.internal:host-gateway'
|
||||
|
||||
links:
|
||||
- postgres
|
||||
volumes:
|
||||
- 'btcpay_datadir:/datadir'
|
||||
- 'nbxplorer_datadir:/root/.nbxplorer'
|
||||
- 'btcpay_pluginsdir:/root/.btcpayserver/Plugins'
|
||||
- 'xmr_wallet:/root/xmr_wallet'
|
||||
- 'tor_servicesdir:/var/lib/tor/hidden_services'
|
||||
- 'tor_torrcdir:/usr/local/etc/tor/'
|
||||
ports:
|
||||
- '80:80'
|
||||
# volumes:
|
||||
# - ./btcpayserver_datadir:/data
|
||||
# - /var/run/docker.sock:/var/run/docker.sock
|
||||
- '${NOREVERSEPROXY_HTTP_PORT:-80}:49392'
|
||||
# monerod:
|
||||
# restart: unless-stopped
|
||||
# container_name: btcpayserver_monerod
|
||||
# image: btcpayserver/monero:0.18.3.3
|
||||
# entrypoint: monerod --rpc-bind-ip=0.0.0.0 --confirm-external-bind --rpc-bind-port=18081 --non-interactive --block-notify="/bin/sh ./scripts/notifier.sh -X GET http://btcpayserver:49392/monerolikedaemoncallback/block?cryptoCode=xmr&hash=%s" --hide-my-port --prune-blockchain --enable-dns-blocklist
|
||||
# expose:
|
||||
# - "18081"
|
||||
# volumes:
|
||||
# - "xmr_data:/home/monero/.bitmonero"
|
||||
monerod_wallet:
|
||||
restart: unless-stopped
|
||||
container_name: btcpayserver_monero_wallet
|
||||
image: btcpayserver/monero:0.18.3.3
|
||||
entrypoint: monero-wallet-rpc --rpc-bind-ip=0.0.0.0 --disable-rpc-login --confirm-external-bind --rpc-bind-port=18082 --non-interactive --trusted-daemon --daemon-address=xmr-node.cakewallet.com:18081 --wallet-file=/wallet/wallet --password-file /wallet/password --tx-notify="/bin/sh ./scripts/notifier.sh -X GET http://btcpayserver:49392/monerolikedaemoncallback/tx?cryptoCode=xmr&hash=%s"
|
||||
expose:
|
||||
- '18082'
|
||||
ports:
|
||||
- 18082:18082
|
||||
volumes:
|
||||
- 'xmr_wallet:/wallet'
|
||||
# depends_on:
|
||||
# - monerod
|
||||
# tor:
|
||||
# restart: unless-stopped
|
||||
# image: btcpayserver/tor:0.4.8.10
|
||||
# container_name: tor
|
||||
# environment:
|
||||
# TOR_PASSWORD: btcpayserver
|
||||
# TOR_ADDITIONAL_CONFIG: /usr/local/etc/tor/torrc-2
|
||||
# TOR_EXTRA_ARGS: |
|
||||
# CookieAuthentication 1
|
||||
# expose:
|
||||
# - "9050"
|
||||
# - "9051"
|
||||
# volumes:
|
||||
# - "tor_datadir:/home/tor/.tor"
|
||||
# - "tor_torrcdir:/usr/local/etc/tor"
|
||||
# - "tor_servicesdir:/var/lib/tor/hidden_services"
|
||||
# tor-gen:
|
||||
# restart: unless-stopped
|
||||
# image: btcpayserver/docker-gen:0.10.7
|
||||
# container_name: tor-gen
|
||||
# volumes:
|
||||
# - "/var/run/docker.sock:/tmp/docker.sock:ro"
|
||||
# - "./torrc.tmpl:/etc/docker-gen/templates/torrc.tmpl:ro"
|
||||
# - "tor_torrcdir:/usr/local/etc/tor"
|
||||
# entrypoint: /usr/local/bin/docker-gen -notify-sighup tor -watch -wait 5s:30s /etc/docker-gen/templates/torrc.tmpl /usr/local/etc/tor/torrc-2
|
||||
# links:
|
||||
# - tor
|
||||
nbxplorer:
|
||||
restart: unless-stopped
|
||||
container_name: generated_nbxplorer_1
|
||||
image: nicolasdorier/nbxplorer:2.5.2
|
||||
expose:
|
||||
- '32838'
|
||||
environment:
|
||||
NBXPLORER_NETWORK: ${NBITCOIN_NETWORK:-regtest}
|
||||
NBXPLORER_BIND: 0.0.0.0:32838
|
||||
NBXPLORER_TRIMEVENTS: 10000
|
||||
NBXPLORER_SIGNALFILESDIR: /datadir
|
||||
NBXPLORER_POSTGRES: User ID=postgres;Host=postgres;Port=5432;Application Name=nbxplorer;MaxPoolSize=20;Database=nbxplorer${NBITCOIN_NETWORK:-regtest}
|
||||
NBXPLORER_AUTOMIGRATE: 1
|
||||
NBXPLORER_NOMIGRATEEVTS: 1
|
||||
NBXPLORER_DELETEAFTERMIGRATION: 1
|
||||
links:
|
||||
- postgres
|
||||
volumes:
|
||||
- 'nbxplorer_datadir:/datadir'
|
||||
postgres:
|
||||
restart: unless-stopped
|
||||
container_name: generated_postgres_1
|
||||
shm_size: 256mb
|
||||
image: btcpayserver/postgres:13.13
|
||||
command: ['-c', 'random_page_cost=1.0', '-c', 'shared_preload_libraries=pg_stat_statements']
|
||||
environment:
|
||||
POSTGRES_HOST_AUTH_METHOD: trust
|
||||
volumes:
|
||||
- 'postgres_datadir:/var/lib/postgresql/data'
|
||||
volumes:
|
||||
btcpay_datadir:
|
||||
btcpay_pluginsdir:
|
||||
xmr_wallet:
|
||||
xmr_data:
|
||||
tor_datadir:
|
||||
tor_torrcdir:
|
||||
tor_servicesdir:
|
||||
nbxplorer_datadir:
|
||||
postgres_datadir:
|
||||
networks: {}
|
||||
|
||||
24
docs/firo/about_us.md
Normal file
24
docs/firo/about_us.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# About the MAGIC Monero Fund
|
||||
|
||||
MAGIC (Multidisciplinary Academic Grants in Cryptocurrencies) Grants is a 501(c)(3) U.S. nonprofit that focuses on building strong cryptocurrency communities and networks. [The MAGIC Monero Fund](https://magicgrants.org/funds/monero) is a subentity of MAGIC Grants guided by a five-member committee elected by [Monero community members](https://magicgrants.org/funds/monero/monero_fund_voters/).
|
||||
|
||||
### MAGIC Monero Fund Vision and Goals:
|
||||
|
||||
* Improve the Monero ecosystem.
|
||||
* Support Monero development and research.
|
||||
* Create Monero educational resources.
|
||||
* Fund Monero security audits.
|
||||
* Run essential services that support the Monero ecosystem.
|
||||
|
||||
### Committee Members
|
||||
|
||||
* [Rucknium](https://github.com/Rucknium) is a Monero Research Lab researcher and economist who has focused on statistical obfuscation on Monero and Bitcoin Cash.
|
||||
|
||||
* [kayabaNerve](https://twitter.com/kayabaNerve) is a Monero-ecosystem developer and security researcher who was the first to implement Monero atomic swaps with ASMR.
|
||||
|
||||
* [monerobull](https://twitter.com/monerobull) is a distributor of marketing materials for Monero Outreach and moderates various communication channels of the Monero community.
|
||||
|
||||
* [artlimber](https://github.com/artlimber) is a Monero user and community supporter who believes privacy is a human right.
|
||||
|
||||
* [kowalabearhugs](https://twitter.com/kowalabearhugs) is a Monero community member, photographer, artist, seasonal farmer, and offseason wanderer.
|
||||
|
||||
80
docs/firo/apply_research.md
Normal file
80
docs/firo/apply_research.md
Normal file
@@ -0,0 +1,80 @@
|
||||
# MAGIC Monero Fund Request for Research Proposals
|
||||
|
||||
## Mission
|
||||
|
||||
The MAGIC Monero Fund is offering a grant program to support actionable Monero research, especially research relating to privacy, security, user experience, and efficiency. Proposals can be related to the Monero protocol directly, or they can be related to other areas of the Monero ecosystem.
|
||||
|
||||
## Target Research Areas
|
||||
|
||||
We are interested in Monero's [open research questions](https://github.com/monero-project/research-lab/issues/94), along with the following:
|
||||
|
||||
- Security proofs around Monero's existing constructions
|
||||
- Arithmetic-circuit-based membership proofs, specifically ones without a trusted setup based on battle-tested cryptographic assumptions
|
||||
|
||||
While the above topics are especially encouraged, the Fund is open to funding other topics as well.
|
||||
|
||||
The proposal's chance to be approved will be increased if it also helps support one or more of the additional mission areas of the MAGIC Monero Fund: Development, Security (including audits); Critical Infrastructure; Community Building and Community Infrastructure; Interoperability; Feature Enhancements; Efficiency Improvements; Educational Materials.
|
||||
|
||||
## Funding Amount
|
||||
|
||||
The MAGIC Monero Fund anticipates funding requests of the equivalent of 5,000 to 20,000 USD at this time.
|
||||
|
||||
## Deadline
|
||||
|
||||
The MAGIC Monero Fund accepts applications on a rolling basis. Applications will be notified of the committee's vote on approval within three weeks of submission except in extraordinary circumstances.
|
||||
|
||||
## Proposal Format
|
||||
|
||||
Applicants must submit their applications on the web form [here](/apply). Alternatively, applicants can submit a PDF file by email to MoneroFund@magicgrants.org . Applicants are free to use their legal name or a pseudonym at this step, although note the "Eligibility" section below.
|
||||
|
||||
The research plan should be 3-5 pages (not counting citations, any images, and biographical sketch) and include the following:
|
||||
|
||||
* The research question you seek to answer, and how the Monero Project benefits from the research.
|
||||
|
||||
* A literature review of existing work and how your proposal improves upon it.
|
||||
|
||||
* Any preliminary work you have already completed.
|
||||
|
||||
* Description of the plan to carry out the research.
|
||||
|
||||
* A plan to work with Monero's developers and/or researchers to integrate the results of the research into Monero's protocol or ecosystem.
|
||||
|
||||
* A budget, likely consisting mostly of labor costs for the researcher(s). This should include the desired payment schedule, which should be no more frequent than monthly. Any additional budgetary item such as equipment should be included as well. Specify the desired form of payment, which can be cryptocurrency or fiat currency.
|
||||
|
||||
* OPTIONAL: A biographical sketch such as a resume or CV. Alternatively, a list of contributions to open source projects.
|
||||
|
||||
|
||||
## Computing Resources Available
|
||||
|
||||
Computing and data storage resources can be made available to applicants depending on research requirements, resource availability, and vetting by a third party. These resources include a research computing server with a 64-thread Threadripper CPU, 256 GB RAM, 2TB SSD, and 12TB RAID1 HDD.
|
||||
|
||||
## Proposal Evaluation Criteria
|
||||
|
||||
Submitted proposals will be evaluated by the committee based on the following criteria:
|
||||
|
||||
* Impact on Monero's privacy, scaling, decentralization, and/or user experience
|
||||
|
||||
* Feasibility of research plan
|
||||
|
||||
* Prior work and qualifications of applicant(s)
|
||||
|
||||
* Clear plan to integrate research findings into Monero's protocol and/or ecosystem
|
||||
|
||||
|
||||
## Eligibility
|
||||
|
||||
All competent researchers are eligible to apply, regardless of educational attainment or occupation. However, as a nonprofit organization registered under U.S. tax laws, MAGIC Grants is required to comply with certain laws when disbursing funds to grant recipients.
|
||||
|
||||
Grant recipients must complete a Due Diligence checklist, which are the last two pages of [this document](https://magicgrants.org/funds/MAGIC%20Fund%20Grant%20Disbursement%20Process%20and%20Requirements.pdf). This includes the collection of your ID and tax information. We will conduct sanctions checks.
|
||||
|
||||
## Vulnerability Research
|
||||
|
||||
If your proposal seek to uncover weaknesses in the privacy and/or security features of Monero as it exists today, then the Committee will require that you share any significant weaknesses with the Committee (and any critical vulnerabilities with [Monero's official Vulnerability Response Process](https://github.com/monero-project/meta/blob/master/VULNERABILITY_RESPONSE_PROCESS.md)) 90 days before publishing the research so that action can be taken to mitigate the vulnerabilities.
|
||||
|
||||
## How to Submit an Application
|
||||
|
||||
Applicants must submit their applications on the web form [here](/apply). Alternatively, applicants can submit a PDF file by email to MoneroFund@magicgrants.org
|
||||
|
||||
## Contact
|
||||
|
||||
Contact MoneroFund@magicgrants.org for further questions.
|
||||
75
docs/firo/faq.md
Normal file
75
docs/firo/faq.md
Normal file
@@ -0,0 +1,75 @@
|
||||
# FAQ
|
||||
|
||||
## What is the mission statement of the Monero Fund?
|
||||
|
||||
- We are a committee of a 501(c)(3) public charity that funds Monero-related open source software, research and associated educational initiatives.
|
||||
|
||||
|
||||
## How are funds distributed?
|
||||
|
||||
- Donations to the **general fund** are disbursed by our committee as needs arise. For projects listed on our site, we review and approve submissions carefully to ensure donated funds are positively impacting the Monero ecosystem. To hold researchers and developers accountable, payment schedules are aligned with approved project milestones.
|
||||
|
||||
|
||||
## How much of my donation goes towards individuals and projects supported by the Monero Fund?
|
||||
|
||||
- We set up campaigns to closely match the amount needed to pay these individuals and projects. There are some credit card processing fees and other related fees that we try to estimate. Typically, we add a buffer of 3% to the project campaign to account for these.
|
||||
- If there are any proceeds are retained by the MAGIC Monero Fund, and will be used on related projects.
|
||||
- If a campaign fails to raise the full amount of funds, then the committee will work with the intended recipient to revise the scope of the project, or the raised funds will be used on related projects.
|
||||
|
||||
## Can an individual or project be funded by both the Monero Community Crowdfunding System (CCS) and the Monero Fund?
|
||||
|
||||
- Yes. There is no expectation of exclusivity, but a proposer cannot raise funds elsewhere for the exact same work that a MAGIC Monero Fund proposal is intended to cover. This allows a proposer to maintain multiple, simultaneous funding options, so long as the scope of work included in the proposal is unique.
|
||||
|
||||
## Do you distribute grants in Monero, Bitcoin or fiat?
|
||||
|
||||
- We distribute grants in the currency of the researchers choosing. We prefer to pay in XMR but will gladly distribute funds in BTC, USD, or other crypto or fiat currencies that are highly liquid.
|
||||
|
||||
## How do you collect Monero donations?
|
||||
|
||||
- We use BTCPay Server to receive all cryptocurrency donations. For fiat donations, we leverage Stripe Payments.
|
||||
|
||||
|
||||
## Can you provide the view key to verify the Fund's incoming Monero donations?
|
||||
|
||||
- Yes. You can create a view-only Monero wallet with this information:
|
||||
- Main address:
|
||||
```
|
||||
4458gM5iAPuJBeVf5u9DwS4Hj82qNPzAcgD7wF9VrRCRb4M635UtmZNPPDonqXkBsb2RmKjUSRLXtJNZCjZgnNFKKW3SxBz
|
||||
```
|
||||
- Secret view key:
|
||||
```
|
||||
2595ab540844231f66c2266f12b174461f81c09b39010dc42697a6a58a7d680c
|
||||
```
|
||||
- Restore height: 2724728
|
||||
|
||||
|
||||
## How can I communicate with you?
|
||||
|
||||
- You can reach the committee via [Discord](https://discord.gg/yEuhhdtbHN), Matrix or [email](mailto:MoneroFund@magicgrants.org).
|
||||
- Applications are reviewed as submitted. Research approval depends on several factors, including funding availability. Projects that align with our mission statement are encouraged to apply. Committee members evaluate each application based on technical merit, potential impact, and the team's ability to execute.
|
||||
- All projects should be free and open source and related to Monero or an ancillary technology (like Tor, etc.) which helps Monero use. Your project must align with the mission of our charity to be eligible for donations.
|
||||
- To reach MAGIC Grants, please [email us](mailto:info@magicgrants.org).
|
||||
|
||||
|
||||
## How can I submit a project for fundraising?
|
||||
|
||||
- Any project that is free and open source and is aligned with the Monero Fund mission are free to [submit an application](/apply) for their project to be listed on the [Monero Fund](/projects) project page.
|
||||
- All applications which fulfill the criteria will be evaluated by the Monero Fund Committee. Upon approval, projects will be listed on the MoneroFund project portal. Donors will be able to contribute funds directly to the these pre-approved, mission-aligned projects.
|
||||
- If you are helping Monero and Free and Open Source Software (FOSS), please [submit an application](/apply) to be listed on our site.
|
||||
|
||||
|
||||
## Are my donations tax deductible?
|
||||
|
||||
- Yes. MAGIC Monero Fund is committee under Multidisciplinary Academic Grants in Cryptocurrencies (MAGIC Grants), a 501(c)(3) non-profit organization. All gifts and donations are tax-deductible in the USA.
|
||||
- If you would like to receive a tax deduction, we may need to collect supplementary information such as your name and email for required record keeping. If you donate over $500 with cryptocurrencies, you will need to fill out [Form 8283](https://www.irs.gov/pub/irs-pdf/f8283.pdf) and email that form to [info@maigcgrants.org](mailto:info@magicgrants.org) for us to sign Part V.
|
||||
|
||||
The Monero Fund relies on donors like you to help promote and support a sustainable ecosystem of contributors to the Monero ecosystem. We greatly appreciate your contributions.
|
||||
|
||||
# Can I join the committee?
|
||||
|
||||
- MAGIC Monero Fund committee elections happen annually. Learn more on the [MAGIC Grants website](https://magicgrants.org/funds/monero).
|
||||
|
||||
# Can I donate with bank transfer / wire?
|
||||
|
||||
- Yes! [Email us](mailto:MoneroFund@magicgrants.org), and we will send you the bank details and manually add your donation. We can accept domestic and international wire transfers. Wires are appreciated for large donations, so that ~3% more of your donation can go to the recipient instead of credit card fees.
|
||||
|
||||
186
docs/firo/privacy.md
Normal file
186
docs/firo/privacy.md
Normal file
@@ -0,0 +1,186 @@
|
||||
# Privacy Policy
|
||||
|
||||
**Last Updated: November 5, 2021**
|
||||
|
||||
Open Sats Initiative's core purpose is to foster an ecosystem that supports the collaborative and public development of free and open-source software projects (each, a "Project"). This privacy policy ("Privacy Policy") describes our policies and procedures about the collection, use, disclosure and sharing, or other processing of your personal information when you use our websites (e.g., opensats.org) or participate in or use our project sites (collectively, the "Sites"), as well as when you interact with or participate in our educations and training programs and events. (collectively, the "Services"). This Privacy Policy applies to activities by Open Sats Initiative and its affiliates, subsidiaries and related entities (collectively "Open Sats" "we" or "us"), including activities that we perform for other entities through third party agreements.
|
||||
|
||||
For purposes of the General Data Protection Regulation ("GDPR"), Open Sats is the controller of your personal information. Where processing of personal information is undertaken by our affiliates, subsidiaries and related entities, they are a joint controller with Open Sats Initiative for your personal information.
|
||||
|
||||
Capitalized terms that are not defined in this Privacy Policy have the meaning given them in our Terms and Conditions (the "Terms"). In this Privacy Policy, "personal information" includes references to "personal data" as defined under applicable laws. Your use of our Sites and Services, and any dispute over privacy, is subject to this Policy and the relevant Terms, including the applicable limitations on damages and the resolution of disputes. The Terms are incorporated by reference into this Policy.
|
||||
|
||||
## Personal Information That Open Sats Collects
|
||||
|
||||
We collect personal information directly from individuals, from third parties, and automatically through the Sites and Services. You do not have to provide us your personal information. However, if you choose not to disclose certain information, we will not be able to provide you with access to certain services or features, including registering on the Sites, registration for training, events, or other programs, or participation in certain aspects of our open-source projects.
|
||||
|
||||
_Registration Information._ We collect personal information when you register for an account or register to participate in an Open Sats event or Program:
|
||||
|
||||
_Account and Profile Information._ Users may sign up for, request, or order our Services and may register to receive materials on our Sites. Users may also create a login, which is a single sign-on account which is used for common access to many of our Services. Personal information collected on the Sites includes community forum content, profiles, photographs, names, unique identifiers, information about your current and past employment affiliations, contact information (address, telephone number, email address, preferred pronoun, etc.), and transaction information (to the extent you share that information). In order to access certain personalized services on the Sites, you may be asked to also create and store a username and password for an account from Open Sats. In order to improve the functioning of the website and our subsequent communications to users we may also ask users to provide additional optional information regarding your interests, demographics, experience and detailed contact preferences.
|
||||
|
||||
_Donations._ To register for and participate in the Open Sats Projects and related Services, users must have an active login ID and account (see above for information collected related to account registration). Open Sats may collect the following information related to financial contributions and :Depending on the Community Bridge Services in which users participate, we may also collect additional information relating to their use of those Services, including:
|
||||
|
||||
- _Donations_: We collect information about financial contributions made, as well as and funds received through the Sites. Open Sats generally only records the result of the transaction and any references to the transaction record provided by the third-party site. For example, when users make financial contributions to projects, we collect and process the donation amount, allocation to certain projects, and identifiers used to associate that donation with the donor and project in the project's open and transparent public ledger (unless otherwise agreed to by the donor and Open Sats. We also collect disbursement amount and category, recipient name and email, and identifiers related to disbursements of project funds for projects. Further, we use third-party services including Stripe to facilitate funding and disbursements. If applicable, the third-party site may collect payment information directly to facilitate a transaction.
|
||||
|
||||
_Events Registration._ When you register for an Open Sats event (training, conference, or other event) to participate as an attendee, a speaker or a sponsor, we collect personal information that includes name, company, contact information, and other information. We may also collect other optional personal information such as likes, interests, preferred pronoun, dietary restriction, size preferences for conference attire gifts and other background information. In addition, if you provide it, we may collect (1) personal information about disabilities, medical conditions and allergies in order to provide appropriate accommodations for attendees, and (2) personal information about your citizenship, date of birth, and passport details if you request assistance from us with obtaining a visa letter to travel to one of our events.
|
||||
|
||||
For in-person events requiring attendees to be vaccinated against COVID-19, in order to provide a safer environment for attendees and staff, we may collect information to verify your identity and COVID-19 vaccination status. We may collect this information via direct verification of identity and vaccination status documents by Open Sats staff or third-party contractors, and/or through the use of third-party vaccination status apps and service providers.
|
||||
|
||||
_Training and Certification Exam Registration_. When you participate in one of our training or certification programs, we collect registration-related personal information that includes name, company, certifications, contact information, and other information depending on the circumstances.
|
||||
|
||||
_Registration for Projects._ You can register to receive access to various information provided by Open Sats and its free and open-source Projects relating to the open-source ecosystem, open source project development, collaboration and best practices. This includes providing us with personal information such as your email address and name to receive newsletters, mailing list postings and social media postings, to view webinars, and to access other resources made available by Open Sats and its Projects.
|
||||
|
||||
**Your Contributions to Open Source Projects**.
|
||||
|
||||
_Project Integrity and Credit for Attribution_. When you contribute source code, documentation or other content to one of our Projects (whether on your own behalf or through a third party entity), we collect and store the information and content that you contribute. This includes the contents of those contributions, as well as information required to confirm the provenance of intellectual property contained in those contributions, and personal information that you make publicly available in the record of the contribution pursuant to sign-offs under the a Certificate of Origin as Follows:
|
||||
|
||||
_Developer's Certificate of Origin:_
|
||||
|
||||
By making a contribution to this project, I certify that:
|
||||
|
||||
(a) The contribution was created in whole or in part by me and I have the right to submit it under the open-source license indicated in the file; or
|
||||
|
||||
(b) The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate open-source license and I have the right under that license to submit that work with modifications, whether created in whole or in part by me, under the same open source license (unless I am permitted to submit under a different license), as indicated in the file; or
|
||||
|
||||
(c) The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not modified it.
|
||||
|
||||
(d) I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the open source license(s) involved. [end]
|
||||
|
||||
Some Projects require additional agreements or information pursuant to their intellectual property policies; in such cases we collect and store information related to your acceptance of those agreements. We may also collect information relating to your participation in technical, governance, or other Project-related meetings.
|
||||
|
||||
_Other Project-related Content._ The content you provide in relation to Projects also includes materials that you make publicly available in connection with Project development, collaboration and communication, such as on mailing lists, blogs, Project pages and issue trackers, and related services.
|
||||
|
||||
_Your Content_. We collect and store the information and content that you post to the Sites, including your questions, answers, comments, forum postings, and responses to surveys.
|
||||
|
||||
_Communications_. When you communicate with us (via email, phone, through the Sites or otherwise), we may maintain a record of your communication.
|
||||
|
||||
_Payment Information._ To participate in or purchase Services (including registering for events, training and certification exams), users may be asked to be directed to a third-party site, such as Stripe, to pay for their purchases. If applicable, the third-party site may collect payment information directly to facilitate a transaction. Open Sats generally only records the result of the transaction and any references to the transaction record provided by the third-party site.
|
||||
|
||||
_Automatically Collected Information._ In addition, Open Sats may automatically collect the following information about users' use of the Sites or Services through cookies, web beacons, and other technologies: your domain name; your browser type and operating system; web pages you view; when you open certain emails we send; links you click; your IP address; your country of location; the length of time you visit our Sites and or use our Services; and the referring URL, or the webpage that led you to our Sites. We may combine this information with other information that we have collected about you, including, where applicable, your user name, name, and other personal information.
|
||||
|
||||
**Basis for Use of Personal Information:**
|
||||
|
||||
**Purposes and Legitimate Interests**
|
||||
|
||||
Open Sats uses the personal information we collect for our legitimate non-proft and charitable business interests, which include the following purposes:
|
||||
|
||||
- _Providing our Sites and Services_. To provide the Services and our Sites, to communicate with you about your use of our Sites and Services, to respond to your inquiries, provide support and maintenance of the Sites and for other purposes to support users and the community.
|
||||
- _Operating our Open-Source Projects_. To enable communication between and among open source developers in the community; to facilitate and document Project governance and technical decision-making; to maintain, and make publicly available on a perpetual basis, records regarding intellectual property provenance and license compliance for Project contributions; and for related activities to further Open Sats's core purpose of fostering an ecosystem that supports the collaborative and public development of free and open source software projects. See the "Project Integrity and Credit for Attribution" section above for more information.
|
||||
- _Maintain our Training and Certification Programs_. To maintain records about who has attended or registered to attend educational or training programs.
|
||||
- _Event Administration_. To plan, organize, and facilitate access to events and related services and activities, and to carry out informative and safe events for participants, including attendees, speakers and sponsors. If you provide us information about disabilities, medical conditions and allergies, we will use this information in order to provide appropriate accommodations for attendees and to ensure their health and safety; we will not use this information for other purposes, unless required by law or as necessary to defend our legal rights. For in-person events requiring attendees to be vaccinated against COVID-19, we use information regarding your COVID-19 vaccination status to provide a safer environment for attendees and staff, in order to confirm vaccination status before permitting access to the event venue space.
|
||||
- _Personalization_. To tailor the content and information that we may send or display to you on our Sites and in our Services, to offer location customization and personalized help and instructions and to otherwise personalize your experiences.
|
||||
- _Marketing and Promotions_. For marketing and promotional purposes, such as to send you news and newsletters, special offers, and promotions, or to otherwise contact you about Projects, Services, events, trainings or other information we think may interest you related to Open Sats, and, subject to applicable law, our affiliates, subsidiaries and managed services entities.
|
||||
- _Advertising_. For targeting advertising to you on our Sites and third-party sites and measuring the effectiveness and reach of ads and services (through third-party ad networks and services).
|
||||
- _Analytics_. To gather metrics to better understand how users access and use our Sites and Services and participate in our Projects; to evaluate and improve the Sites, including personalization, to develop new services; and to understand metrics regarding the community health of our Projects. If a user voluntary provides and explicitly consents to our processing of personal information regarding their demographics and socioeconomics, we process such personal information for the specific purposes for which you have consented, which may include for the purpose of compiling, analyzing and disclosing aggregate statistics regarding diversity of participation in open source projects and communities.
|
||||
- _Compliance_. To comply with legal obligations and requests. For example, to comply with laws that compel us to disclose information to public authorities, courts, law enforcement or regulators, maintain records for a certain period, or maintain records demonstrating enforcement and sublicensing of our trademarks and those of our Projects.
|
||||
- _Business and Legal Operations_. As part of our general charitable and non-profit business and legal operations (e.g., accounting, record keeping, and for other business administration purposes), and as necessary to establish, exercise and defend (actual and potential) legal claims.
|
||||
- _Prevent Misuse_. Where we believe necessary to investigate, prevent or take action regarding illegal activities, suspected fraud, situations involving potential threats to the safety of any person or violations of the relevant Terms and Conditions or this Privacy Policy.
|
||||
|
||||
**Sharing of Personal Information**
|
||||
|
||||
We disclose personal information as set forth below, and where individuals have otherwise consented:
|
||||
|
||||
- _Publicly Available Information, including Your Contributions to Open-Source Projects._ User names, other user ids, email addresses and other attribution information related to the information and contributions that a user posts in conjunction with or subject to an Open Source license are publicly available in the relevant Project source code repositories. Your contributions to Open-Source Projects, and certain of your other Content such as comments and messages posted to public forums, are available to other participants and users of our Projects and of our Services, and may be viewed publicly. In some cases you may be able to provide Project or contribution-related information directly to third-party sites and services; these third parties are independent data controllers and their use of your personal information is subject to their own policies.
|
||||
- _Service Providers._ We may share your information with third party service providers who use this information to perform services for us, such as payment processors, hosting providers, auditors, advisors, contractors and consultants.
|
||||
- _Affiliates._ The information collected about you may be accessed by or shared with subsidiaries and affiliates of Open Sats, whose use and disclosure of your personal information is subject to this Privacy Policy, unless an affiliate has its own separate privacy policy.
|
||||
- _Event Participants_. If you register for an event, we may ask for your consent to share your personal information with third party sponsors and other participants. We will not share your event information with third parties without your consent. For in-person events requiring attendees to be vaccinated against COVID-19, we may use third-party service providers to validate your identity and COVID-19 vaccination status.
|
||||
- _Training and Program Sponsors_. If you participate in one of our education, certification, or training programs that a third party has sponsored or engaged us to provide to you and others (for example, your employers), we may receive attendee list information from them and may share information about your completion of the program, including confirmation of your participation and your certification exam results, as applicable; these third parties are independent data controllers and their use of your personal information is subject to their own policies. You may also elect to provide third parties (e.g., your employers or your prospective employers) with information that will enable them to look up your certification exam status; if you do so, we may share your certification exam status with such third parties.
|
||||
- _Legally Required._ We may disclose your information if we are required to do so by law (including to law enforcement in the U.S. and other jurisdictions).
|
||||
- _Protection of Rights._ We may disclose information where we believe it necessary to respond to claims asserted against us or, comply with legal process (e.g., subpoenas or warrants), enforce or administer our agreements and terms, for fraud prevention, risk assessment, investigation, and protect the rights, property or safety of Open Sats, its Users, participants in its events or Projects, or others.
|
||||
- _Anonymized and Aggregated Information._ We may share aggregated information with third parties for research, marketing, analytics and other purposes, provided such information does not identify a particular individual.
|
||||
|
||||
**Cookies, Tracking, and Interest-Based Ads**
|
||||
|
||||
We and our third-party providers use cookies, pixel tags, JavaScript, log files, and other mechanisms to automatically collect and record information about your usage and browsing activities on our Site and across third party sites or online services. We may combine this information with other information we collect about users. Below, we provide a brief summary these activities.
|
||||
|
||||
- _Cookies._ These are small files with a unique identifier that are transferred to your browser through our websites. They allow us to remember users who are logged in, to understand how users navigate through and use the Sites, and to display personalized content and targeted ads (including on third party sites and applications).
|
||||
- _Pixels, web beacons, clear GIFs_ These are tiny graphics with a unique identifier, similar in function to cookies, which we track browsing activities.
|
||||
- _Analytics Tools._ We may use internal and third-party analytics tools. The third-party analytics companies we work with may combine the information collected with other information they have independently collected from other websites and/or other online products and services. Their collection and use of information is subject to their own privacy policies.
|
||||
|
||||
**Targeted Ads.** As discussed in our Cookie Policy, we may work with third-party advertisers to display more relevant ads on our website and on third party sites; these third parties may display ads to you based on your visit to our Sites and other third-party sites.
|
||||
|
||||
**Data Security**
|
||||
|
||||
We have implemented commercially reasonable precautions designed to protect the information we collect from loss, misuse, and unauthorized access, disclosure, alteration, and destruction. Please be aware that despite our best efforts, Open Sats provides no guarantee that any security measure will be completely and totally secure.
|
||||
|
||||
We are not responsible for any lost, stolen, or compromised passwords or for any activity on your account via unauthorized password activity. We ask you to promptly notify us if you become aware that any information provided by or submitted to our Sites or through our Services is lost, stolen, or used without permission at info@opensats.org.
|
||||
|
||||
**Marketing Choices**
|
||||
|
||||
You may opt out of or withdraw your consent to receive direct marketing emails from us by using the unsubscribe or opt out mechanisms included in our marketing emails or by emailing info@opensats.org. You may also unsubscribe from mailing lists via the applicable mailing list's subscription website or, in some cases, by using the unsubscribe mechanisms included in such emails.
|
||||
|
||||
**Retention of Your Personal Information**
|
||||
|
||||
We generally keep personal information only for as long as required to fulfill the purposes for which it was collected. However, in some circumstances, we may retain personal information for other periods of time, for instance where we are required to do so in accordance with legal, tax and accounting requirements, or if required to do so by a legal process, legal authority, or other governmental entity having authority to make the request, for so long as required. In specific circumstances, we may also retain your personal information for longer periods of time corresponding to a statute of limitation, so that we have an accurate record of your dealings with us in the event of any complaints or challenges.
|
||||
|
||||
**International Information:**
|
||||
|
||||
**Scope**. This section applies to individuals in the European Union "EU" (for these purposes, reference to the EU also includes the European Economic Area countries of Iceland, Liechtenstein and Norway and, to the extent applicable, Switzerland).
|
||||
|
||||
**Data Controller**. Open Sats is the data controller for the processing of Personal data related to donor and non-profit accounts and information on our Sites. You can find our contact information below.
|
||||
|
||||
Open Sats is the data processor with respect to processing personal information related to donations and any interaction with Projects. If you wish to exercise one of the below rights with respect to your contribution (whether financial or to a Project) please contact us.
|
||||
|
||||
**Your Rights**. Pursuant to the GDPR, to the extent Open Sats is a data controller of your Personal data, you have the following rights in relation to your personal data, under certain circumstances:
|
||||
|
||||
**Right of access** : If you ask us, we will confirm whether we are processing your personal data and, if so, provide you with a copy of that personal data along with certain other details. If you require additional copies, we may need to charge a reasonable fee.
|
||||
|
||||
**Right to rectification** : If your personal data is inaccurate or incomplete, you are entitled to ask that we correct or complete it. If we shared your personal data with others, we will tell them about the correction where possible. If you ask us, and where possible and lawful to do so, we will also tell you with whom we shared your Personal data so you can contact them directly.
|
||||
|
||||
**Right to erasure** : You may ask us to delete or remove your personal data, such as where you withdraw your consent. If we shared your data with others, we will tell them about the erasure where possible. If you ask us, and where possible and lawful to do so, we will also tell you with whom we shared your Personal data with so you can contact them directly.
|
||||
|
||||
**Right to restrict processing** : You may ask us to restrict or 'block' the processing of your personal data in certain circumstances, such as where you contest the accuracy of the data or object to us processing it (please read below for information on your right to object). We will tell you before we lift any restriction on processing. If we shared your Personal data with others, we will tell them about the restriction where possible. If you ask us, and where possible and lawful to do so, we will also tell you with whom we shared your Personal data so you can contact them directly.
|
||||
|
||||
**Right to data portability** : You have the right to obtain your personal data from us that you consented to give us or that was provided to us as necessary in connection with our contract with you, and that is processed by automated means. We will give you your personal data in a structured, commonly used and machine-readable format. You may reuse it elsewhere.
|
||||
|
||||
**Right to object** : You may ask us at any time to stop processing your personal data, and we will do so:
|
||||
|
||||
If we are relying on a legitimate interest to process your personal data (unless we demonstrate compelling legitimate grounds for the processing or if we are processing your personal data for direct marketing) and if we are processing your personal data for direct marketing, we may keep minimum information about you in a suppression list in order to ensure your choices are respected in the future and to comply with data protection laws (such processing is necessary for our and your legitimate interest in pursuing the purposes described above).
|
||||
|
||||
**Right to withdraw consent** : If we rely on your consent to process your personal data, you have the right to withdraw that consent at any time. Withdrawal of consent will not affect any processing of your data before we received notice that you wished to withdraw consent.
|
||||
|
||||
**Right to lodge a complaint with the data protection authority** : If you have a concern about our privacy practices, including the way we handled your personal data, you can report it to the data protection authority that is authorized to hear those concerns.
|
||||
|
||||
Please see the section below with our contact information on how to reach Open Sats to exercise your rights.
|
||||
|
||||
**Legitimate Interest**. "Legitimate interests" means our interests in conducting our charitable business and developing a relationship with you. This Privacy Policy describes when we process your Personal data for our legitimate interests, what these interests are and your rights. We will not use your Personal data for activities where the impact on you overrides our interests, unless we have your consent, or those activities are otherwise required or permitted by law.
|
||||
|
||||
**International Transfers of Personal Data**. Because Open Sats is a non-profit organization that is not subject to the jurisdiction of the United States Federal Trade Commission, it is not eligible for certification under the EU-U.S. and Swiss-U.S. Privacy Shield frameworks ("Frameworks") as set forth by the U.S. Department of Commerce regarding the processing of personal data transferred from the EU, United Kingdom, and Switzerland to the U.S. (for these purposes, reference to the EU also includes the European Economic Area countries of Iceland, Liechtenstein and Norway). However, Open Sats commits to process Personal data transferred from the EU to the United States in accordance with the principles of Notice, Choice, Accountability for Onward Transfer, Security, Data Integrity and Purpose Limitation, Access, and Recourse, Enforcement and Liability, as described below.
|
||||
|
||||
**Notice and Choice**. This Privacy Policy provides notice of the personal data collected and transferred to the United States and the choices that you have with respect to such personal data. It also provides information about the protections applicable to transferred data below.
|
||||
|
||||
**Accountability for Onward Transfers**. We may be accountable for the personal data transfer to third-party service providers. If we are and our third-party service providers process personal data in a manner inconsistent with these principles, we are responsible and liable for the harm caused, unless we prove that we are not responsible for the event giving rise to the damage.
|
||||
|
||||
**Security**. We maintain security measures to protect personal data as described in the "Data Security" section of this Privacy Policy.
|
||||
|
||||
**Data Integrity and Purpose Limitation**. We take reasonable steps to ensure that personal data is reliable for its intended use, and that it is accurate, complete and current for as long as we retain it. We will retain the data as long as necessary for the following purposes: delivering the Services, engaging in customer service, complying with legal obligations, auditing, performing security and fraud prevention, responding to legal and regulatory inquiries, and preserving or defending our legal rights or those of other users or third parties.
|
||||
|
||||
**Access**. EU users have certain rights to access, correct, amend, or delete personal data where it is inaccurate, or has been processed in violation of these principles. Please see the "Your Rights" section above for more information on the rights of users in the EU (and, to the extent applicable, users in Switzerland).
|
||||
|
||||
**Recourse, Enforcement, Liability**. Open Sats commits to resolve complaints about our processing of your personal data. European Union, United Kingdom, and Swiss users with inquiries or complaints regarding our processing of Personal data should first contact Open Sats as follows:
|
||||
|
||||
Email: info@opensats.org
|
||||
|
||||
Attention: Information Security
|
||||
|
||||
We will respond to such inquiries or complaints within thirty (30) days.
|
||||
|
||||
**Children's Privacy**
|
||||
|
||||
Open Sats does not knowingly collect or solicit personal information from anyone under the age of sixteen (16), or knowingly allow such persons to register. If we become aware that we have collected personal information from a child under the relevant age without parental consent, we take steps to delete that information. Where we specifically indicate that we collect personal information from children under sixteen (16), we will obtain the parent or guardian's consent and provide adequate notice.
|
||||
|
||||
**Links to Third Party Sites and Services**
|
||||
|
||||
The Sites may contain links to third party sites or online services. Please refer to the privacy policies of the relevant third-party websites or services to find out more about how they process and handle personal information.
|
||||
|
||||
**California Privacy Rights**
|
||||
|
||||
Only to the extent that Open Sats meets the minimum thresholds as required under California law to be subject to the California Privacy Rights Act of 2020, residents of California will be able to request and obtain from us once a year, free of charge, a list of the third parties to whom we have disclosed their personal information (if any) for their direct marketing purposes in the prior calendar year, as well as the types of personal information disclosed to those parties. If you are a California resident and would like to request this information, please submit your request in an email to [info@opensats.org](mailto:info@opensats.org). We reserve the right to ask for verification of your California residence and deny this request if Open Sats believes it is not subject to this requirement.
|
||||
|
||||
**Contact Us**
|
||||
|
||||
If you have any questions about our practices or this Privacy Policy, please contact us at [info@opensats.org](mailto:info@opensats.org), or write to us at: Open Sats Initiative, Attn: Legal Department, 3605 Glenwood Ave., Suite 500, Raleigh, North Carolina, 27612, USA.
|
||||
|
||||
**Changes to the Privacy Policy**
|
||||
|
||||
This Policy is current as of the effective date set forth above. If we change our privacy policies and procedures, we will post those changes on this page and/or continue to provide access to a copy of the prior version. If we make any changes to this Privacy Policy that materially change how we treat your personal information, we will endeavor to provide you with reasonable notice of such changes, such as via prominent notice on our Sites or to your email address of record, and where required by law, we will obtain your consent or give you the opportunity to opt out of such changes.
|
||||
|
||||
3564707v1.AWB.31306.G51883
|
||||
49
docs/firo/projects/eae_attack_and_churning.md
Normal file
49
docs/firo/projects/eae_attack_and_churning.md
Normal file
@@ -0,0 +1,49 @@
|
||||
---
|
||||
title: 'Firo Example Campaign'
|
||||
summary: "The EAE attack is one of Monero's privacy weak points. Churning may be a solution."
|
||||
nym: 'Dr. Nathan Borggren'
|
||||
website: 'https://github.com/nborggren'
|
||||
coverImage: '/img/project/EAE_diagram.png'
|
||||
git: 'https://github.com/nborggren'
|
||||
twitter: 'magicgrants'
|
||||
personalTwitter: 'magicgrants'
|
||||
personalWebsite: 'https://github.com/nborggren'
|
||||
type: 'Other Free and Open Source Project'
|
||||
date: '2023-06-08'
|
||||
staticXMRaddress: '87LZA8XLDvhVKLi974MaxUANcvkWdL6n986R7WNgKLXY16y31t69Z8228EWcg8THQq3tuAWfQ7Np35Tt3AhPrjzcNbm8Jr5'
|
||||
goal: 29260
|
||||
isFunded: false
|
||||
numdonationsxmr: 27
|
||||
totaldonationsinfiatxmr: 29260
|
||||
totaldonationsxmr: 220
|
||||
numdonationsbtc: 0
|
||||
totaldonationsinfiatbtc: 0
|
||||
totaldonationsbtc: 0
|
||||
fiatnumdonations: 0
|
||||
fiattotaldonationsinfiat: 0
|
||||
fiattotaldonations: 0
|
||||
---
|
||||
|
||||
### Funded Goal: 220 XMR (86 XMR contributed from MAGIC Monero Fund general fund)
|
||||
|
||||
### Start: June 2023
|
||||
|
||||
### End: September 2023
|
||||
|
||||
### Result: [Research paper](/pdf/Borggren-Sept-2023-Probing-the-Attacks-on-the-Privacy-of-the-Monero-Blockchain.pdf)
|
||||
|
||||
The EAE (Eve-Alice-Eve) attack is a threat to Monero user privacy. When a Monero user sends and/or receives funds repeatedly with an entity (Eve) that aims to trace funds, enough information in the local transaction graph and ring signatures may be available to make a probabalistic guess about the true destination or source of funds. There are different names for this attack and related attacks, which mostly differ in how many colluding entities are involved and how much information they may possess: EABE, poisoned outputs, Overseer, Flashlight, Tainted Dust, and Knacc attacks. One of the videos of the Breaking Monero series [discusses the EAE attack in detail](https://www.monerooutreach.org/breaking-monero/poisoned-outputs.html).
|
||||
|
||||
The EAE attack has been a concern of the Monero Research Lab for years, but rigorous measurement of the possible risk of this attack and possible defenses against it have not been successfully researched. "Churning", the practice of users sending funds to themselves, has been suggested as a possible defense, but neither its effectiveness nor details about best churning procedures have been determined by research to date.
|
||||
|
||||
Dr. Nathan Borggren has stepped up to investigate these important research questions about how to best protect Monero user privacy. Dr. Borggren is lead author of two papers about possible statistical threats to Monero user privacy: Borggren & Yao (2020) ["Correlations of Multi-input Monero Transactions"](https://moneroresearch.info/index.php?action=resource_RESOURCEVIEW_CORE&id=57) and Borggren et al. (2020) ["Simulated Blockchains for Machine Learning Traceability and Transaction Values in the Monero Network"](https://moneroresearch.info/index.php?action=resource_RESOURCEVIEW_CORE&id=58). His work analyzing transparent blockchains includes Borggren et al. (2017) "Deanonymizing Shapeshift: Linking Transactions Across Multiple Blockchains" and Borggren (2017) "Deep Learning of Entity Behavior in the Bitcoin Economy".
|
||||
|
||||
Dr. Borggren has proposed using Topological Data Analysis and Bayesian statistical methods to analyze the EAE attack and related attacks on Monero user privacy. The false positive and false negative rate of the EAE attack will be investigated through simulations and possibly analysis of Monero's mainnet blockchain. The full details of the plan are in [the research proposal](https://github.com/MAGICGrants/Monero-Fund/blob/main/projects/borggren_research-MAGIC-submission.pdf).
|
||||
|
||||
> "I think that the EAE attack is one of Monero's biggest _practical_ attack surfaces currently, and I see value in quantification plus real world data-informed best practices."
|
||||
|
||||
— [isthmus](https://github.com/Mitchellpkt), Monero Research Lab researcher and lead author of ["Fingerprinting a flood: Forensic statistical analysis of the mid-2021 Monero transaction volume anomaly"](https://mitchellpkt.medium.com/fingerprinting-a-flood-forensic-statistical-analysis-of-the-mid-2021-monero-transaction-volume-a19cbf41ce60)
|
||||
|
||||
> "Borggren has previously released fascinating papers quantifying Monero privacy pitfalls and I'm excited he is looking to continue."
|
||||
|
||||
— [ACK-J](https://github.com/ACK-J), author of ["Lord of the Rings: An Empirical Analysis of Monero's Ring Signature Resilience to Artifically Intelligent Attacks"](https://raw.githubusercontent.com/ACK-J/Monero-Dataset-Pipeline/main/Lord_of_the_Rings__An_Empirical_Analysis_of_Monero_s_Ring_Signature_Resilience_to_Artificially_Intelligent_Attacks.pdf)
|
||||
97
docs/firo/terms.md
Normal file
97
docs/firo/terms.md
Normal file
@@ -0,0 +1,97 @@
|
||||
# Open Sats Initiative terms of use
|
||||
|
||||
**Last updated: November 14, 2021**
|
||||
|
||||
Welcome to the Opensats.org website and/or mobile application (individually and collectively, the "Site"). Your access and use of the Site and of features, software, products and services provided by Open Sats Initiative ("Open Sats," "we," "us," or "our") through the Site, (individually and collectively, the "Service") is subject to the terms and conditions in this Terms of Use ("Terms of Use" or "Terms").
|
||||
|
||||
You must agree to the Terms in order to use the Site and/or the Service. If you use the Site and/or the Service, or click to accept or agree to the Terms if presented to you in a user interface for the Service, this is your acceptance of the Terms and your agreement to all of its terms and conditions. By accepting the Terms or using the Site and/or the Service, you represent and warrant that you are at least 18 years of age and have the legal capacity to enter a contract in the jurisdiction where you reside. If you do not accept the Terms, then you may not use the Site or the Service. If you are using the Site or the Service on behalf of another entity, you represent and warrant that you have full legal authority to bind such other entity to the Terms. If you do not have such authority, then you may not use the Site or the Service and you must discontinue all use of the Site and the Service immediately.
|
||||
|
||||
1. Our Services. The purpose of the Service is to promote the use of open source software to enhance blockchain technology and to promote the development of the Bitcoin infrastructure along with other free and open source software projects. As a non-profit organization ourselves, Open Sats Initiative does accept donations on the opensats.org website.
|
||||
2. Privacy Policy. By clicking on the Terms of Use and Privacy Policy box or using the Site or the Service, you represent that you have read and consent to our Privacy Policy located at [/privacy](/privacy) in addition to the Terms. Open Sats may revise the Privacy Policy at any time, and the new versions will be available on the Site. If at any point you do not agree to any portion of the Privacy Policy, you must immediately stop using the Site and/or Service.
|
||||
3. Terms of Use Updates. Open Sats may update the Terms at any time, and Open Sats will post the updated version of the Terms on the Site. You understand and agree that you will be deemed to have accepted the updated Terms if you use the Site or the Service after the updated Terms are posted on the Site. If at any point you do not agree to any portion of the Terms then in effect, you must immediately stop using the Site and the Service.
|
||||
4. Provision of the Services. You understand that all information, data, text, software, graphics or other materials ("Content"), whether publicly posted or privately transmitted, are the sole responsibility of the person from whom such Content originated. This means that you, and not Open Sats, is/are entirely responsible for all Content that you upload, post, email, transmit or otherwise make available via Services. Open Sats does not control the Content posted and, as such, does not guarantee the accuracy, integrity or quality of such Content. Under no circumstances will Open Sats be liable in any way for any Content, including, but not limited to, any errors or omissions in any Content, or any loss or damage of any kind incurred as a result of the use of any Content posted, emailed, transmitted or otherwise made available via the Open Sats Service.
|
||||
|
||||
You also agree that you will not collect or store personal data about other users in connection with any prohibited conduct and activities. You acknowledge that Open Sats may or may not pre-screen Content, but that Open Sats and its designees shall have the right (but not the obligation) in their sole discretion to pre-screen, refuse, move, or remove any Content that is available via the Services and which violates the Terms of Service. You agree that you must evaluate, and bear all risks associated with, the use of any Content, including any reliance on the accuracy, completeness, or usefulness of such Content. You acknowledge, consent and agree that Open Sats may access, preserve and disclose your account information and Content if required to do so by law or in a good faith belief that such access preservation or disclosure is reasonably necessary to:
|
||||
|
||||
- comply with legal process;
|
||||
- enforce the Terms of Use and the Privacy Policy;
|
||||
- respond to claims that any Content violates the rights of third parties;
|
||||
- respond to your requests for customer service; or
|
||||
- protect the rights, property or personal safety of Open Sats its users and the public.
|
||||
|
||||
1. Provision of the Service Not an Exchange. Open Sats is not a bitcoin exchange or wallet service and does not receive, hold or exchange digital currencies on behalf of any other person or entity. Open Sats does not withhold funds for tax purposes or otherwise.
|
||||
2. Tax Advice. Open Sats makes no representation as to whether all or any portion of your donations to us are tax deductible or eligible for tax credits. Open Sats will have no liability for any claim by any federal, state, local or any other tax authority with respect to the characterization on any applicable tax return of any donation by you. You should consult your tax advisor as to the amount of your donation that is tax deductible or eligible for tax recognition, if any.
|
||||
3. Access Restriction. Open Sats reserves the right to deny access or service to any person or entity at Open Sats' sole and absolute discretion. You acknowledge and agree that Open Sats may stop providing the Site and/or the Service or restrict your use of the Site and/or the Service at any time, without notifying you in advance, for any reason or no reason, including, without limitation, for any violation of the Terms and/or if Open Sats suspects that you have used any aspect of the Service to conduct any fraudulent or illegal activity. If Open Sats disables your access to your account, you may be prevented from accessing the Service, your account details and/or any materials contained in your account.
|
||||
4. Accounts and Security.
|
||||
5. Account. Open Sats may require registration for an account to access the Site and the Services. There will be a registration process for the creation of accounts to complete the registration process. You may be required to provide information about yourself or your company as part of the registration process or your continued use of the Service. You agree that any registration information that you submit to Open Sats will be correct, accurate, and up to date and that you will not impersonate any person or entity, or falsely state or otherwise misrepresent your affiliation with a person or entity.
|
||||
6. Account Security. Maintaining account security is very important. You are solely responsible for maintaining the confidentiality of your account password. You agree to notify Open Sats immediately if you become aware of any unauthorized use of your password or of your account.
|
||||
7. Account Sharing or Transfers. Accounts are registered to individuals or entities and may not be sold, traded, gifted or otherwise transferred at any time under any circumstances. An account may not be shared. Passwords may not be disclosed to anyone else.
|
||||
8. Cancellation by You. You have the right to cancel your account at any time. You may cancel your account by emailing us at info@opensats.org to submit a request to our support team.
|
||||
9. Termination by Open Sats. Open Sats may at any time terminate your account for any reason or no reason including, without limitation, if:
|
||||
|
||||
- Open Sats determines that you are (a) in breach of or otherwise acting inconsistently with the Terms or written agreements (b) engaging in fraudulent or illegal activities or other conduct that may result in liability to Open Sats;
|
||||
- Open Sats determines it is required by law to terminate your account; or
|
||||
- Open Sats decides to stop providing the Service or critical portions of the Service in the country where you reside, access the Site or use the Service or Open Sats determines that it is no longer in its charitable business interests to continue providing the Service or portions of the Service.
|
||||
|
||||
1. Content Licensing. Open Sats mission includes educating the public on free and open-source software through content such as articles, images, photographs, comments, software code, audio and video clips, and other materials (collectively, "Content"). Content is authored by Open Sats, contributors to Open Sats projects, and other sources.
|
||||
|
||||
Content authored by Open Sats is generally made available for public sharing and reuse through open licenses such as Creative Commons (for expressive material) or the Open Sats Public License. In most cases we ask Open Sats contributors to release Content under open licenses.
|
||||
|
||||
Some Content in our Site may be acquired from sources that prohibit further use of their Content without advance permission. Where possible, the Content will display a notice with the applicable license. You agree to abide by such notices. However it may occur that:
|
||||
|
||||
1. Some Content expressly indicates that the author does not intend for an open license to apply. You should contact the author or author's agent for permission to use such Content. Questions on Open Sats authored content can be sent to: info@opensats.org.
|
||||
2. Some Content contains trademarks, trade dress, logos and brand assets of Open Sats and other parties ("Trademarks"). Except for a few limited circumstances, Trademarks cannot be used without advance written permission of the owner of the Trademark.
|
||||
3. Software used by our Websites is licensed under the Open Sats Public License or similarly permissive open source licenses.
|
||||
4. Content Submissions **.** You may contribute Content when interacting with our Site and Services, including but not limited to commenting on an article, blogging, contributing code, or contributing graphics or written material (each a "Submission"). Unless your Submission is made under a separate agreement with Open Sats, in which case that agreement will govern, then
|
||||
|
||||
- For Submissions to Open Sats' open source Projects:
|
||||
|
||||
1. You agree to license your Submission under the terms of the corresponding license of the particular open source project to which you are contributing. For more information on the specific license, please see the applicable source.
|
||||
|
||||
- For all other Submissions, you agree to the following in connection with each:
|
||||
|
||||
1. You represent and warrant that your Submission will comply with these Terms and any additional terms that may govern your Submission.
|
||||
2. You hereby grant us a nonexclusive, royalty-free, worldwide, sublicensable (to those we work with) license to use your Submission in connection with the Content, Site, and Services and online and offline promotion of Open Sats' mission, products and services.
|
||||
3. You acknowledge that your Submissions may be accessible by other registered users of the applicable service or the public.
|
||||
4. If your Submission contains expressive material or software code, you agree to license it in a manner that is compatible with the particular website you are making a Submission to.
|
||||
5. You represent and warrant that you have the rights necessary to grant the rights granted herein, and further, that the uses contemplated under these Terms will not infringe the proprietary or intellectual property rights of any third party.
|
||||
6. You understand and agree that Open Sats reserves the right, at its discretion, to review, modify, or remove any Submission that it deems is objectionable or in violation of these Terms.
|
||||
|
||||
1. Effect of Account Termination or Cancellation. If you voluntarily terminate your account or allow your account to lapse, you will be able to reactivate that account at any time through the account interface on the Site. Accounts terminated by Open Sats for any type of abuse including, without limitation, a violation of the Terms, may not be reactivated for any reason. If you are blocked by us from accessing the Site or Service (including by blocking your IP address), you agree not to implement any measures to circumvent such blocking (e.g., by masking your IP address or using a proxy IP address).
|
||||
2. Restrictions and Conditions of Use.
|
||||
3. Use of the Site. Open Sats permits users to view and use the Site solely for personal or nonprofit use. You agree not to license, create derivative works from, transfer, sell or re-sell any information, content, materials, data or services obtained from the Site or through the Service unless specifically allowed by an Open Source license or express permission.
|
||||
4. Accessing the Service. You agree not to access, or attempt to access, the Service by any means other than through the user interface provided through the Site or any mobile application provided by Open Sats. You specifically agree not to access, or attempt to access, the Service through any automated means (including, without limitation, through the use of scripts, bots, spiders or web crawlers) and you agree to comply with the instructions contained in any robots.txt file present on the Site or the Service.
|
||||
5. No Violation of Laws. You agree that you will not, in connection with your use of the Site or the Service, violate any applicable law, ordinance, rule, regulation or treaty. Without limiting the foregoing, you agree that you will not make available through the Site and/or the Service any material or information that infringes any copyright, trademark, patent, trade secret, or other right of any party (including rights of privacy or publicity).
|
||||
6. Use Restrictions. You may not connect to or use the Site or the Service in any way that is not expressly permitted by the Terms.
|
||||
7. You may not: (a) remove any proprietary notices from the Service; (b) cause, permit or authorize the modification, creation of derivative works, translation, reverse engineering, decompiling, disassembling or hacking of the Site or the Service; (c) sell, assign, rent, lease, act as a service bureau, or grant rights in the Service, including, without limitation, through sublicense, to any other person or entity without the prior written consent of Open Sats; or (d) make any false, misleading or deceptive statement or representation regarding Open Sats and/or the Site or the Service.
|
||||
8. Without limiting the foregoing, you agree that you will not: (i) institute, assist, or become involved in any type of attack including, without limitation, denial of service attacks, upon the Site and/or the Service (or any servers, systems, or networks connected to the Site or the Service) or otherwise attempt to obstruct, disrupt, or interfere with the operation of the Site and/or the Service or any other person's or entity's use of the Site and/or the Service (or any servers, systems or networks connected to the Site or the Service); (ii) attempt to gain unauthorized access to the Site, the Service, accounts registered to other users, or any servers, systems or networks connected to the Site and/or the Service; (iii) use the Site or the Service for any commercial purpose or the benefit of any third party, or charge any person or entity, or receive any compensation for, the use of the Site or the Service, unless you are specifically authorized to do so in a separate written agreement with Open Sats; (iv) use the Site or the Service to (y) develop, generate, transmit or store information that is defamatory, harmful, abusive, obscene or hateful; or (z) perform any unsolicited commercial communication; or (v) engage in any activity that (A) constitutes harassment or a violation of privacy or threatens other people or groups of people; (B) is harmful to children in any manner; (C) constitutes phishing, pharming, or impersonates any other person or entity, or steals or assumes any person's identity (whether a real identity or online nickname or alias); (D) violates any applicable law, ordinance, rule, regulation or treaty or (E) in Open Sats' sole judgment, is objectionable or that restricts or inhibits any other person from using or enjoying our Site or Service, or which may expose us or our users to any harm or liability of any type.
|
||||
9. No Data Mining or Harmful Code. You agree that you will not (a) obtain or attempt to obtain any information from the Site or Services including, without limitation, any personal information of other account holders or other software data; (b) intercept, examine or otherwise observe any proprietary communications protocol used by the Site or the Service, whether through the use of a network analyzer, packet sniffer, or other device; or (c) use any type of bot, spider, virus, clock, timer, counter, worm, software lock, drop dead device, Trojan horse routing, trap door, time bomb or any other codes, instructions or third party software that is designed to provide a means of surreptitious or unauthorized access to, or distort, delete, damage or disassemble, the Site or the Service.
|
||||
10. Violation of the Terms. You acknowledge and agree that you are solely responsible, and Open Sats has no responsibility or liability to you or any other person or entity, for any breach by you of the Terms or for the consequences of any such breach.
|
||||
11. Links.
|
||||
12. Links from the Site. The Site may contain links to websites operated by other parties. Open Sats provides these links to other websites as a convenience and use of these websites is at your own risk. The linked websites are not under the control of Open Sats and Open Sats is not responsible for the content available on the other websites. Such links do not imply Open Sats' endorsement of information or material on any other website and Open Sats disclaims all liability with regard to your access to and use of such linked websites.
|
||||
13. Links to the Site. Unless otherwise set forth in a written agreement between you and Open Sats, you must adhere to Open Sats' linking policy as follows: (i) the appearance, position, and other aspects of the link may not be such as to damage or dilute the goodwill associated with Open Sats' and/or its licensors' names and trademarks; (ii) the appearance, position and other attributes of the link may not create the false appearance that your organization or entity is sponsored by, affiliated with, or associated with Open Sats; and (iii) when selected by a user, the link must display the Site on full-screen and not within a "frame" on the linking Site. Open Sats reserves the right to revoke its consent to the link at any time and in its sole discretion.
|
||||
14. Intellectual Property.
|
||||
15. Trademarks. The Open Sats marks are trademarks of Open Sats. Unless permitted in a separate written agreement with Open Sats, you do not have the right to use any of Open Sats' trademarks, service marks, or logos; and your unauthorized use of any of these may be a violation of federal and state trademark laws.
|
||||
16. Ownership. You acknowledge and agree that Open Sats, or its licensors, owns all right, title and interest in and to the Site and the Service, including all intellectual property, industrial property and proprietary rights recognized anywhere in the world at any time and that the Site and the Service are protected by U.S. and international copyright laws. Further, you acknowledge that the Service may contain information that Open Sats has designated as confidential and you agree not to disclose such information without Open Sats' prior written consent.
|
||||
|
||||
17. Location. The Site and the Service are operated by Open Sats in the United States. If you choose to access the Site and/or the Service from a location outside of the United States, you do so on your own initiative and you are responsible for compliance with applicable local laws.
|
||||
|
||||
18. Children. The Site and the Service are not directed toward children under 13 years of age nor does Open Sats knowingly collect information from children under 13 or allow them to create an account or access account features. If you are under 13, please do not submit any personal information about yourself to Open Sats.
|
||||
19. Term/Termination. These Terms will continue to apply until ended by either you or Open Sats. You can choose to end them at any time for any reason by discontinuing your use of our Site and Services and, if applicable, deleting your account. We may suspend or terminate your access to our Site and Services at any time for any reason, including, but not limited to, if we reasonably believe: (i) you have violated these Terms, our Privacy Policy, or other relevant policy; (ii) you create risk or possible legal exposure for us; or (iii) our provision of the Site and Services to you is no longer commercially viable. In all such cases, these Terms shall terminate, except that the following sections shall continue to apply: Indemnification, Disclaimer; Limitation of Liability, Modification, and Miscellaneous.
|
||||
20. Indemnification **.** You agree to defend, indemnify and hold harmless Open Sats, its contractors, contributors, licensors, and partners; and the respective directors, officers, employees and agents of the foregoing ("Indemnified Parties") from and against any and all third party claims and expenses, including attorneys' fees, arising out of or related to your use of our Site and Services (including, but not limited to, from your Submissions or from your violation of any these Terms).
|
||||
21. Disclaimer; Limitation of Liability. THE SITE AND SERVICES ARE PROVIDED "AS IS" WITH ALL FAULTS. TO THE EXTENT PERMITTED BY LAW, OPEN SATS AND THE INDEMNIFIED PARTIES HEREBY DISCLAIM ALL WARRANTIES, WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION WARRANTIES THAT THE CONTENT, SITE, AND SERVICES (AS APPLICABLE) ARE FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, AND NON-INFRINGING. YOU BEAR THE ENTIRE RISK AS TO USING THE SITE AND SERVICES FOR YOUR PURPOSES AND AS TO THE QUALITY AND PERFORMANCE OF THE SITE AND SERVICES, INCLUDING WITHOUT LIMITATION THE RISK THAT YOUR HARDWARE, SOFTWARE, OR CONTENT IS DELETED OR CORRUPTED, THAT SOMEONE ELSE GAINS UNAUTHORIZED ACCESS TO YOUR INFORMATION, OR THAT ANOTHER USER MISUSES OR MISAPPROPRIATES YOUR SUBMISSION. THIS LIMITATION WILL APPLY NOTWITHSTANDING THE FAILURE OF ESSENTIAL PURPOSE OF ANY REMEDY. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF IMPLIED WARRANTIES, SO THIS DISCLAIMER MAY NOT APPLY TO YOU. EXCEPT AS REQUIRED BY LAW, OPEN SATS AND THE INDEMNIFIED PARTIES WILL NOT BE LIABLE FOR ANY INDIRECT, SPECIAL, INCIDENTAL, CONSEQUENTIAL, OR EXEMPLARY DAMAGES ARISING OUT OF OR IN ANY WAY RELATING TO THESE TERMS OR THE USE OF OR INABILITY TO USE THE CONTENT, SITE, AND SERVICES, INCLUDING WITHOUT LIMITATION DIRECT AND INDIRECT DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, LOST PROFITS, LOSS OF DATA, AND COMPUTER FAILURE OR MALFUNCTION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES AND REGARDLESS OF THE THEORY (CONTRACT, TORT, OR OTHERWISE) UPON WHICH SUCH CLAIM IS BASED. THE COLLECTIVE LIABILITY OF OPEN SATS AND THE INDEMNIFIED PARTIES UNDER THIS AGREEMENT WILL NOT EXCEED \$500 (FIVE HUNDRED DOLLARS). SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL, CONSEQUENTIAL, OR SPECIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.
|
||||
22. Modifications to these Terms **.** We may update these Terms from time to time to address a new feature of the Site and Services or to clarify a provision. The updated Terms will be posted online. If the changes are substantive, we will announce the update through our usual channels for such announcements such as blog posts, banners, emails, or forums. Your continued use of our Site and Services after the effective date of such changes constitutes your acceptance of such changes. To make your review more convenient, we will post an effective date at the top of this page.
|
||||
23. Miscellaneous. These Terms constitute the entire agreement between you and Open Sats concerning our Site and Services and supersede any prior versions of these Terms. The Site and Services and these Terms are governed by the laws of the state of North Carolina, U.S.A., excluding its conflict of law provisions. All claims and disputes arising out of the Site and Services or these Terms shall be brought exclusively in the courts of Wake County, North Carolina, and you consent to personal jurisdiction in those courts. If any portion of these Terms is held to be invalid or unenforceable, the remaining portions will remain in full force and effect. In the event of a conflict between a translated version of these Terms and the English language version, the English language version shall control. In the event of a conflict between these Terms and relevant additional terms, the additional terms shall control.
|
||||
24. Contact Open Sats.
|
||||
|
||||
> Open Sats
|
||||
>
|
||||
> Attn: Open Sats – Legal Notices
|
||||
>
|
||||
> P.O. Box 20389
|
||||
>
|
||||
> Raleigh, NC 27612
|
||||
>
|
||||
> info@opensats.org
|
||||
>
|
||||
> 3566450v1.AWB.31306.G51883
|
||||
24
docs/general/about_us.md
Normal file
24
docs/general/about_us.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# About the MAGIC Monero Fund
|
||||
|
||||
MAGIC (Multidisciplinary Academic Grants in Cryptocurrencies) Grants is a 501(c)(3) U.S. nonprofit that focuses on building strong cryptocurrency communities and networks. [The MAGIC Monero Fund](https://magicgrants.org/funds/monero) is a subentity of MAGIC Grants guided by a five-member committee elected by [Monero community members](https://magicgrants.org/funds/monero/monero_fund_voters/).
|
||||
|
||||
### MAGIC Monero Fund Vision and Goals:
|
||||
|
||||
* Improve the Monero ecosystem.
|
||||
* Support Monero development and research.
|
||||
* Create Monero educational resources.
|
||||
* Fund Monero security audits.
|
||||
* Run essential services that support the Monero ecosystem.
|
||||
|
||||
### Committee Members
|
||||
|
||||
* [Rucknium](https://github.com/Rucknium) is a Monero Research Lab researcher and economist who has focused on statistical obfuscation on Monero and Bitcoin Cash.
|
||||
|
||||
* [kayabaNerve](https://twitter.com/kayabaNerve) is a Monero-ecosystem developer and security researcher who was the first to implement Monero atomic swaps with ASMR.
|
||||
|
||||
* [monerobull](https://twitter.com/monerobull) is a distributor of marketing materials for Monero Outreach and moderates various communication channels of the Monero community.
|
||||
|
||||
* [artlimber](https://github.com/artlimber) is a Monero user and community supporter who believes privacy is a human right.
|
||||
|
||||
* [kowalabearhugs](https://twitter.com/kowalabearhugs) is a Monero community member, photographer, artist, seasonal farmer, and offseason wanderer.
|
||||
|
||||
80
docs/general/apply_research.md
Normal file
80
docs/general/apply_research.md
Normal file
@@ -0,0 +1,80 @@
|
||||
# MAGIC Monero Fund Request for Research Proposals
|
||||
|
||||
## Mission
|
||||
|
||||
The MAGIC Monero Fund is offering a grant program to support actionable Monero research, especially research relating to privacy, security, user experience, and efficiency. Proposals can be related to the Monero protocol directly, or they can be related to other areas of the Monero ecosystem.
|
||||
|
||||
## Target Research Areas
|
||||
|
||||
We are interested in Monero's [open research questions](https://github.com/monero-project/research-lab/issues/94), along with the following:
|
||||
|
||||
- Security proofs around Monero's existing constructions
|
||||
- Arithmetic-circuit-based membership proofs, specifically ones without a trusted setup based on battle-tested cryptographic assumptions
|
||||
|
||||
While the above topics are especially encouraged, the Fund is open to funding other topics as well.
|
||||
|
||||
The proposal's chance to be approved will be increased if it also helps support one or more of the additional mission areas of the MAGIC Monero Fund: Development, Security (including audits); Critical Infrastructure; Community Building and Community Infrastructure; Interoperability; Feature Enhancements; Efficiency Improvements; Educational Materials.
|
||||
|
||||
## Funding Amount
|
||||
|
||||
The MAGIC Monero Fund anticipates funding requests of the equivalent of 5,000 to 20,000 USD at this time.
|
||||
|
||||
## Deadline
|
||||
|
||||
The MAGIC Monero Fund accepts applications on a rolling basis. Applications will be notified of the committee's vote on approval within three weeks of submission except in extraordinary circumstances.
|
||||
|
||||
## Proposal Format
|
||||
|
||||
Applicants must submit their applications on the web form [here](/apply). Alternatively, applicants can submit a PDF file by email to MoneroFund@magicgrants.org . Applicants are free to use their legal name or a pseudonym at this step, although note the "Eligibility" section below.
|
||||
|
||||
The research plan should be 3-5 pages (not counting citations, any images, and biographical sketch) and include the following:
|
||||
|
||||
* The research question you seek to answer, and how the Monero Project benefits from the research.
|
||||
|
||||
* A literature review of existing work and how your proposal improves upon it.
|
||||
|
||||
* Any preliminary work you have already completed.
|
||||
|
||||
* Description of the plan to carry out the research.
|
||||
|
||||
* A plan to work with Monero's developers and/or researchers to integrate the results of the research into Monero's protocol or ecosystem.
|
||||
|
||||
* A budget, likely consisting mostly of labor costs for the researcher(s). This should include the desired payment schedule, which should be no more frequent than monthly. Any additional budgetary item such as equipment should be included as well. Specify the desired form of payment, which can be cryptocurrency or fiat currency.
|
||||
|
||||
* OPTIONAL: A biographical sketch such as a resume or CV. Alternatively, a list of contributions to open source projects.
|
||||
|
||||
|
||||
## Computing Resources Available
|
||||
|
||||
Computing and data storage resources can be made available to applicants depending on research requirements, resource availability, and vetting by a third party. These resources include a research computing server with a 64-thread Threadripper CPU, 256 GB RAM, 2TB SSD, and 12TB RAID1 HDD.
|
||||
|
||||
## Proposal Evaluation Criteria
|
||||
|
||||
Submitted proposals will be evaluated by the committee based on the following criteria:
|
||||
|
||||
* Impact on Monero's privacy, scaling, decentralization, and/or user experience
|
||||
|
||||
* Feasibility of research plan
|
||||
|
||||
* Prior work and qualifications of applicant(s)
|
||||
|
||||
* Clear plan to integrate research findings into Monero's protocol and/or ecosystem
|
||||
|
||||
|
||||
## Eligibility
|
||||
|
||||
All competent researchers are eligible to apply, regardless of educational attainment or occupation. However, as a nonprofit organization registered under U.S. tax laws, MAGIC Grants is required to comply with certain laws when disbursing funds to grant recipients.
|
||||
|
||||
Grant recipients must complete a Due Diligence checklist, which are the last two pages of [this document](https://magicgrants.org/funds/MAGIC%20Fund%20Grant%20Disbursement%20Process%20and%20Requirements.pdf). This includes the collection of your ID and tax information. We will conduct sanctions checks.
|
||||
|
||||
## Vulnerability Research
|
||||
|
||||
If your proposal seek to uncover weaknesses in the privacy and/or security features of Monero as it exists today, then the Committee will require that you share any significant weaknesses with the Committee (and any critical vulnerabilities with [Monero's official Vulnerability Response Process](https://github.com/monero-project/meta/blob/master/VULNERABILITY_RESPONSE_PROCESS.md)) 90 days before publishing the research so that action can be taken to mitigate the vulnerabilities.
|
||||
|
||||
## How to Submit an Application
|
||||
|
||||
Applicants must submit their applications on the web form [here](/apply). Alternatively, applicants can submit a PDF file by email to MoneroFund@magicgrants.org
|
||||
|
||||
## Contact
|
||||
|
||||
Contact MoneroFund@magicgrants.org for further questions.
|
||||
75
docs/general/faq.md
Normal file
75
docs/general/faq.md
Normal file
@@ -0,0 +1,75 @@
|
||||
# FAQ
|
||||
|
||||
## What is the mission statement of the Monero Fund?
|
||||
|
||||
- We are a committee of a 501(c)(3) public charity that funds Monero-related open source software, research and associated educational initiatives.
|
||||
|
||||
|
||||
## How are funds distributed?
|
||||
|
||||
- Donations to the **general fund** are disbursed by our committee as needs arise. For projects listed on our site, we review and approve submissions carefully to ensure donated funds are positively impacting the Monero ecosystem. To hold researchers and developers accountable, payment schedules are aligned with approved project milestones.
|
||||
|
||||
|
||||
## How much of my donation goes towards individuals and projects supported by the Monero Fund?
|
||||
|
||||
- We set up campaigns to closely match the amount needed to pay these individuals and projects. There are some credit card processing fees and other related fees that we try to estimate. Typically, we add a buffer of 3% to the project campaign to account for these.
|
||||
- If there are any proceeds are retained by the MAGIC Monero Fund, and will be used on related projects.
|
||||
- If a campaign fails to raise the full amount of funds, then the committee will work with the intended recipient to revise the scope of the project, or the raised funds will be used on related projects.
|
||||
|
||||
## Can an individual or project be funded by both the Monero Community Crowdfunding System (CCS) and the Monero Fund?
|
||||
|
||||
- Yes. There is no expectation of exclusivity, but a proposer cannot raise funds elsewhere for the exact same work that a MAGIC Monero Fund proposal is intended to cover. This allows a proposer to maintain multiple, simultaneous funding options, so long as the scope of work included in the proposal is unique.
|
||||
|
||||
## Do you distribute grants in Monero, Bitcoin or fiat?
|
||||
|
||||
- We distribute grants in the currency of the researchers choosing. We prefer to pay in XMR but will gladly distribute funds in BTC, USD, or other crypto or fiat currencies that are highly liquid.
|
||||
|
||||
## How do you collect Monero donations?
|
||||
|
||||
- We use BTCPay Server to receive all cryptocurrency donations. For fiat donations, we leverage Stripe Payments.
|
||||
|
||||
|
||||
## Can you provide the view key to verify the Fund's incoming Monero donations?
|
||||
|
||||
- Yes. You can create a view-only Monero wallet with this information:
|
||||
- Main address:
|
||||
```
|
||||
4458gM5iAPuJBeVf5u9DwS4Hj82qNPzAcgD7wF9VrRCRb4M635UtmZNPPDonqXkBsb2RmKjUSRLXtJNZCjZgnNFKKW3SxBz
|
||||
```
|
||||
- Secret view key:
|
||||
```
|
||||
2595ab540844231f66c2266f12b174461f81c09b39010dc42697a6a58a7d680c
|
||||
```
|
||||
- Restore height: 2724728
|
||||
|
||||
|
||||
## How can I communicate with you?
|
||||
|
||||
- You can reach the committee via [Discord](https://discord.gg/yEuhhdtbHN), Matrix or [email](mailto:MoneroFund@magicgrants.org).
|
||||
- Applications are reviewed as submitted. Research approval depends on several factors, including funding availability. Projects that align with our mission statement are encouraged to apply. Committee members evaluate each application based on technical merit, potential impact, and the team's ability to execute.
|
||||
- All projects should be free and open source and related to Monero or an ancillary technology (like Tor, etc.) which helps Monero use. Your project must align with the mission of our charity to be eligible for donations.
|
||||
- To reach MAGIC Grants, please [email us](mailto:info@magicgrants.org).
|
||||
|
||||
|
||||
## How can I submit a project for fundraising?
|
||||
|
||||
- Any project that is free and open source and is aligned with the Monero Fund mission are free to [submit an application](/apply) for their project to be listed on the [Monero Fund](/projects) project page.
|
||||
- All applications which fulfill the criteria will be evaluated by the Monero Fund Committee. Upon approval, projects will be listed on the MoneroFund project portal. Donors will be able to contribute funds directly to the these pre-approved, mission-aligned projects.
|
||||
- If you are helping Monero and Free and Open Source Software (FOSS), please [submit an application](/apply) to be listed on our site.
|
||||
|
||||
|
||||
## Are my donations tax deductible?
|
||||
|
||||
- Yes. MAGIC Monero Fund is committee under Multidisciplinary Academic Grants in Cryptocurrencies (MAGIC Grants), a 501(c)(3) non-profit organization. All gifts and donations are tax-deductible in the USA.
|
||||
- If you would like to receive a tax deduction, we may need to collect supplementary information such as your name and email for required record keeping. If you donate over $500 with cryptocurrencies, you will need to fill out [Form 8283](https://www.irs.gov/pub/irs-pdf/f8283.pdf) and email that form to [info@maigcgrants.org](mailto:info@magicgrants.org) for us to sign Part V.
|
||||
|
||||
The Monero Fund relies on donors like you to help promote and support a sustainable ecosystem of contributors to the Monero ecosystem. We greatly appreciate your contributions.
|
||||
|
||||
# Can I join the committee?
|
||||
|
||||
- MAGIC Monero Fund committee elections happen annually. Learn more on the [MAGIC Grants website](https://magicgrants.org/funds/monero).
|
||||
|
||||
# Can I donate with bank transfer / wire?
|
||||
|
||||
- Yes! [Email us](mailto:MoneroFund@magicgrants.org), and we will send you the bank details and manually add your donation. We can accept domestic and international wire transfers. Wires are appreciated for large donations, so that ~3% more of your donation can go to the recipient instead of credit card fees.
|
||||
|
||||
186
docs/general/privacy.md
Normal file
186
docs/general/privacy.md
Normal file
@@ -0,0 +1,186 @@
|
||||
# Privacy Policy
|
||||
|
||||
**Last Updated: November 5, 2021**
|
||||
|
||||
Open Sats Initiative's core purpose is to foster an ecosystem that supports the collaborative and public development of free and open-source software projects (each, a "Project"). This privacy policy ("Privacy Policy") describes our policies and procedures about the collection, use, disclosure and sharing, or other processing of your personal information when you use our websites (e.g., opensats.org) or participate in or use our project sites (collectively, the "Sites"), as well as when you interact with or participate in our educations and training programs and events. (collectively, the "Services"). This Privacy Policy applies to activities by Open Sats Initiative and its affiliates, subsidiaries and related entities (collectively "Open Sats" "we" or "us"), including activities that we perform for other entities through third party agreements.
|
||||
|
||||
For purposes of the General Data Protection Regulation ("GDPR"), Open Sats is the controller of your personal information. Where processing of personal information is undertaken by our affiliates, subsidiaries and related entities, they are a joint controller with Open Sats Initiative for your personal information.
|
||||
|
||||
Capitalized terms that are not defined in this Privacy Policy have the meaning given them in our Terms and Conditions (the "Terms"). In this Privacy Policy, "personal information" includes references to "personal data" as defined under applicable laws. Your use of our Sites and Services, and any dispute over privacy, is subject to this Policy and the relevant Terms, including the applicable limitations on damages and the resolution of disputes. The Terms are incorporated by reference into this Policy.
|
||||
|
||||
## Personal Information That Open Sats Collects
|
||||
|
||||
We collect personal information directly from individuals, from third parties, and automatically through the Sites and Services. You do not have to provide us your personal information. However, if you choose not to disclose certain information, we will not be able to provide you with access to certain services or features, including registering on the Sites, registration for training, events, or other programs, or participation in certain aspects of our open-source projects.
|
||||
|
||||
_Registration Information._ We collect personal information when you register for an account or register to participate in an Open Sats event or Program:
|
||||
|
||||
_Account and Profile Information._ Users may sign up for, request, or order our Services and may register to receive materials on our Sites. Users may also create a login, which is a single sign-on account which is used for common access to many of our Services. Personal information collected on the Sites includes community forum content, profiles, photographs, names, unique identifiers, information about your current and past employment affiliations, contact information (address, telephone number, email address, preferred pronoun, etc.), and transaction information (to the extent you share that information). In order to access certain personalized services on the Sites, you may be asked to also create and store a username and password for an account from Open Sats. In order to improve the functioning of the website and our subsequent communications to users we may also ask users to provide additional optional information regarding your interests, demographics, experience and detailed contact preferences.
|
||||
|
||||
_Donations._ To register for and participate in the Open Sats Projects and related Services, users must have an active login ID and account (see above for information collected related to account registration). Open Sats may collect the following information related to financial contributions and :Depending on the Community Bridge Services in which users participate, we may also collect additional information relating to their use of those Services, including:
|
||||
|
||||
- _Donations_: We collect information about financial contributions made, as well as and funds received through the Sites. Open Sats generally only records the result of the transaction and any references to the transaction record provided by the third-party site. For example, when users make financial contributions to projects, we collect and process the donation amount, allocation to certain projects, and identifiers used to associate that donation with the donor and project in the project's open and transparent public ledger (unless otherwise agreed to by the donor and Open Sats. We also collect disbursement amount and category, recipient name and email, and identifiers related to disbursements of project funds for projects. Further, we use third-party services including Stripe to facilitate funding and disbursements. If applicable, the third-party site may collect payment information directly to facilitate a transaction.
|
||||
|
||||
_Events Registration._ When you register for an Open Sats event (training, conference, or other event) to participate as an attendee, a speaker or a sponsor, we collect personal information that includes name, company, contact information, and other information. We may also collect other optional personal information such as likes, interests, preferred pronoun, dietary restriction, size preferences for conference attire gifts and other background information. In addition, if you provide it, we may collect (1) personal information about disabilities, medical conditions and allergies in order to provide appropriate accommodations for attendees, and (2) personal information about your citizenship, date of birth, and passport details if you request assistance from us with obtaining a visa letter to travel to one of our events.
|
||||
|
||||
For in-person events requiring attendees to be vaccinated against COVID-19, in order to provide a safer environment for attendees and staff, we may collect information to verify your identity and COVID-19 vaccination status. We may collect this information via direct verification of identity and vaccination status documents by Open Sats staff or third-party contractors, and/or through the use of third-party vaccination status apps and service providers.
|
||||
|
||||
_Training and Certification Exam Registration_. When you participate in one of our training or certification programs, we collect registration-related personal information that includes name, company, certifications, contact information, and other information depending on the circumstances.
|
||||
|
||||
_Registration for Projects._ You can register to receive access to various information provided by Open Sats and its free and open-source Projects relating to the open-source ecosystem, open source project development, collaboration and best practices. This includes providing us with personal information such as your email address and name to receive newsletters, mailing list postings and social media postings, to view webinars, and to access other resources made available by Open Sats and its Projects.
|
||||
|
||||
**Your Contributions to Open Source Projects**.
|
||||
|
||||
_Project Integrity and Credit for Attribution_. When you contribute source code, documentation or other content to one of our Projects (whether on your own behalf or through a third party entity), we collect and store the information and content that you contribute. This includes the contents of those contributions, as well as information required to confirm the provenance of intellectual property contained in those contributions, and personal information that you make publicly available in the record of the contribution pursuant to sign-offs under the a Certificate of Origin as Follows:
|
||||
|
||||
_Developer's Certificate of Origin:_
|
||||
|
||||
By making a contribution to this project, I certify that:
|
||||
|
||||
(a) The contribution was created in whole or in part by me and I have the right to submit it under the open-source license indicated in the file; or
|
||||
|
||||
(b) The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate open-source license and I have the right under that license to submit that work with modifications, whether created in whole or in part by me, under the same open source license (unless I am permitted to submit under a different license), as indicated in the file; or
|
||||
|
||||
(c) The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not modified it.
|
||||
|
||||
(d) I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the open source license(s) involved. [end]
|
||||
|
||||
Some Projects require additional agreements or information pursuant to their intellectual property policies; in such cases we collect and store information related to your acceptance of those agreements. We may also collect information relating to your participation in technical, governance, or other Project-related meetings.
|
||||
|
||||
_Other Project-related Content._ The content you provide in relation to Projects also includes materials that you make publicly available in connection with Project development, collaboration and communication, such as on mailing lists, blogs, Project pages and issue trackers, and related services.
|
||||
|
||||
_Your Content_. We collect and store the information and content that you post to the Sites, including your questions, answers, comments, forum postings, and responses to surveys.
|
||||
|
||||
_Communications_. When you communicate with us (via email, phone, through the Sites or otherwise), we may maintain a record of your communication.
|
||||
|
||||
_Payment Information._ To participate in or purchase Services (including registering for events, training and certification exams), users may be asked to be directed to a third-party site, such as Stripe, to pay for their purchases. If applicable, the third-party site may collect payment information directly to facilitate a transaction. Open Sats generally only records the result of the transaction and any references to the transaction record provided by the third-party site.
|
||||
|
||||
_Automatically Collected Information._ In addition, Open Sats may automatically collect the following information about users' use of the Sites or Services through cookies, web beacons, and other technologies: your domain name; your browser type and operating system; web pages you view; when you open certain emails we send; links you click; your IP address; your country of location; the length of time you visit our Sites and or use our Services; and the referring URL, or the webpage that led you to our Sites. We may combine this information with other information that we have collected about you, including, where applicable, your user name, name, and other personal information.
|
||||
|
||||
**Basis for Use of Personal Information:**
|
||||
|
||||
**Purposes and Legitimate Interests**
|
||||
|
||||
Open Sats uses the personal information we collect for our legitimate non-proft and charitable business interests, which include the following purposes:
|
||||
|
||||
- _Providing our Sites and Services_. To provide the Services and our Sites, to communicate with you about your use of our Sites and Services, to respond to your inquiries, provide support and maintenance of the Sites and for other purposes to support users and the community.
|
||||
- _Operating our Open-Source Projects_. To enable communication between and among open source developers in the community; to facilitate and document Project governance and technical decision-making; to maintain, and make publicly available on a perpetual basis, records regarding intellectual property provenance and license compliance for Project contributions; and for related activities to further Open Sats's core purpose of fostering an ecosystem that supports the collaborative and public development of free and open source software projects. See the "Project Integrity and Credit for Attribution" section above for more information.
|
||||
- _Maintain our Training and Certification Programs_. To maintain records about who has attended or registered to attend educational or training programs.
|
||||
- _Event Administration_. To plan, organize, and facilitate access to events and related services and activities, and to carry out informative and safe events for participants, including attendees, speakers and sponsors. If you provide us information about disabilities, medical conditions and allergies, we will use this information in order to provide appropriate accommodations for attendees and to ensure their health and safety; we will not use this information for other purposes, unless required by law or as necessary to defend our legal rights. For in-person events requiring attendees to be vaccinated against COVID-19, we use information regarding your COVID-19 vaccination status to provide a safer environment for attendees and staff, in order to confirm vaccination status before permitting access to the event venue space.
|
||||
- _Personalization_. To tailor the content and information that we may send or display to you on our Sites and in our Services, to offer location customization and personalized help and instructions and to otherwise personalize your experiences.
|
||||
- _Marketing and Promotions_. For marketing and promotional purposes, such as to send you news and newsletters, special offers, and promotions, or to otherwise contact you about Projects, Services, events, trainings or other information we think may interest you related to Open Sats, and, subject to applicable law, our affiliates, subsidiaries and managed services entities.
|
||||
- _Advertising_. For targeting advertising to you on our Sites and third-party sites and measuring the effectiveness and reach of ads and services (through third-party ad networks and services).
|
||||
- _Analytics_. To gather metrics to better understand how users access and use our Sites and Services and participate in our Projects; to evaluate and improve the Sites, including personalization, to develop new services; and to understand metrics regarding the community health of our Projects. If a user voluntary provides and explicitly consents to our processing of personal information regarding their demographics and socioeconomics, we process such personal information for the specific purposes for which you have consented, which may include for the purpose of compiling, analyzing and disclosing aggregate statistics regarding diversity of participation in open source projects and communities.
|
||||
- _Compliance_. To comply with legal obligations and requests. For example, to comply with laws that compel us to disclose information to public authorities, courts, law enforcement or regulators, maintain records for a certain period, or maintain records demonstrating enforcement and sublicensing of our trademarks and those of our Projects.
|
||||
- _Business and Legal Operations_. As part of our general charitable and non-profit business and legal operations (e.g., accounting, record keeping, and for other business administration purposes), and as necessary to establish, exercise and defend (actual and potential) legal claims.
|
||||
- _Prevent Misuse_. Where we believe necessary to investigate, prevent or take action regarding illegal activities, suspected fraud, situations involving potential threats to the safety of any person or violations of the relevant Terms and Conditions or this Privacy Policy.
|
||||
|
||||
**Sharing of Personal Information**
|
||||
|
||||
We disclose personal information as set forth below, and where individuals have otherwise consented:
|
||||
|
||||
- _Publicly Available Information, including Your Contributions to Open-Source Projects._ User names, other user ids, email addresses and other attribution information related to the information and contributions that a user posts in conjunction with or subject to an Open Source license are publicly available in the relevant Project source code repositories. Your contributions to Open-Source Projects, and certain of your other Content such as comments and messages posted to public forums, are available to other participants and users of our Projects and of our Services, and may be viewed publicly. In some cases you may be able to provide Project or contribution-related information directly to third-party sites and services; these third parties are independent data controllers and their use of your personal information is subject to their own policies.
|
||||
- _Service Providers._ We may share your information with third party service providers who use this information to perform services for us, such as payment processors, hosting providers, auditors, advisors, contractors and consultants.
|
||||
- _Affiliates._ The information collected about you may be accessed by or shared with subsidiaries and affiliates of Open Sats, whose use and disclosure of your personal information is subject to this Privacy Policy, unless an affiliate has its own separate privacy policy.
|
||||
- _Event Participants_. If you register for an event, we may ask for your consent to share your personal information with third party sponsors and other participants. We will not share your event information with third parties without your consent. For in-person events requiring attendees to be vaccinated against COVID-19, we may use third-party service providers to validate your identity and COVID-19 vaccination status.
|
||||
- _Training and Program Sponsors_. If you participate in one of our education, certification, or training programs that a third party has sponsored or engaged us to provide to you and others (for example, your employers), we may receive attendee list information from them and may share information about your completion of the program, including confirmation of your participation and your certification exam results, as applicable; these third parties are independent data controllers and their use of your personal information is subject to their own policies. You may also elect to provide third parties (e.g., your employers or your prospective employers) with information that will enable them to look up your certification exam status; if you do so, we may share your certification exam status with such third parties.
|
||||
- _Legally Required._ We may disclose your information if we are required to do so by law (including to law enforcement in the U.S. and other jurisdictions).
|
||||
- _Protection of Rights._ We may disclose information where we believe it necessary to respond to claims asserted against us or, comply with legal process (e.g., subpoenas or warrants), enforce or administer our agreements and terms, for fraud prevention, risk assessment, investigation, and protect the rights, property or safety of Open Sats, its Users, participants in its events or Projects, or others.
|
||||
- _Anonymized and Aggregated Information._ We may share aggregated information with third parties for research, marketing, analytics and other purposes, provided such information does not identify a particular individual.
|
||||
|
||||
**Cookies, Tracking, and Interest-Based Ads**
|
||||
|
||||
We and our third-party providers use cookies, pixel tags, JavaScript, log files, and other mechanisms to automatically collect and record information about your usage and browsing activities on our Site and across third party sites or online services. We may combine this information with other information we collect about users. Below, we provide a brief summary these activities.
|
||||
|
||||
- _Cookies._ These are small files with a unique identifier that are transferred to your browser through our websites. They allow us to remember users who are logged in, to understand how users navigate through and use the Sites, and to display personalized content and targeted ads (including on third party sites and applications).
|
||||
- _Pixels, web beacons, clear GIFs_ These are tiny graphics with a unique identifier, similar in function to cookies, which we track browsing activities.
|
||||
- _Analytics Tools._ We may use internal and third-party analytics tools. The third-party analytics companies we work with may combine the information collected with other information they have independently collected from other websites and/or other online products and services. Their collection and use of information is subject to their own privacy policies.
|
||||
|
||||
**Targeted Ads.** As discussed in our Cookie Policy, we may work with third-party advertisers to display more relevant ads on our website and on third party sites; these third parties may display ads to you based on your visit to our Sites and other third-party sites.
|
||||
|
||||
**Data Security**
|
||||
|
||||
We have implemented commercially reasonable precautions designed to protect the information we collect from loss, misuse, and unauthorized access, disclosure, alteration, and destruction. Please be aware that despite our best efforts, Open Sats provides no guarantee that any security measure will be completely and totally secure.
|
||||
|
||||
We are not responsible for any lost, stolen, or compromised passwords or for any activity on your account via unauthorized password activity. We ask you to promptly notify us if you become aware that any information provided by or submitted to our Sites or through our Services is lost, stolen, or used without permission at info@opensats.org.
|
||||
|
||||
**Marketing Choices**
|
||||
|
||||
You may opt out of or withdraw your consent to receive direct marketing emails from us by using the unsubscribe or opt out mechanisms included in our marketing emails or by emailing info@opensats.org. You may also unsubscribe from mailing lists via the applicable mailing list's subscription website or, in some cases, by using the unsubscribe mechanisms included in such emails.
|
||||
|
||||
**Retention of Your Personal Information**
|
||||
|
||||
We generally keep personal information only for as long as required to fulfill the purposes for which it was collected. However, in some circumstances, we may retain personal information for other periods of time, for instance where we are required to do so in accordance with legal, tax and accounting requirements, or if required to do so by a legal process, legal authority, or other governmental entity having authority to make the request, for so long as required. In specific circumstances, we may also retain your personal information for longer periods of time corresponding to a statute of limitation, so that we have an accurate record of your dealings with us in the event of any complaints or challenges.
|
||||
|
||||
**International Information:**
|
||||
|
||||
**Scope**. This section applies to individuals in the European Union "EU" (for these purposes, reference to the EU also includes the European Economic Area countries of Iceland, Liechtenstein and Norway and, to the extent applicable, Switzerland).
|
||||
|
||||
**Data Controller**. Open Sats is the data controller for the processing of Personal data related to donor and non-profit accounts and information on our Sites. You can find our contact information below.
|
||||
|
||||
Open Sats is the data processor with respect to processing personal information related to donations and any interaction with Projects. If you wish to exercise one of the below rights with respect to your contribution (whether financial or to a Project) please contact us.
|
||||
|
||||
**Your Rights**. Pursuant to the GDPR, to the extent Open Sats is a data controller of your Personal data, you have the following rights in relation to your personal data, under certain circumstances:
|
||||
|
||||
**Right of access** : If you ask us, we will confirm whether we are processing your personal data and, if so, provide you with a copy of that personal data along with certain other details. If you require additional copies, we may need to charge a reasonable fee.
|
||||
|
||||
**Right to rectification** : If your personal data is inaccurate or incomplete, you are entitled to ask that we correct or complete it. If we shared your personal data with others, we will tell them about the correction where possible. If you ask us, and where possible and lawful to do so, we will also tell you with whom we shared your Personal data so you can contact them directly.
|
||||
|
||||
**Right to erasure** : You may ask us to delete or remove your personal data, such as where you withdraw your consent. If we shared your data with others, we will tell them about the erasure where possible. If you ask us, and where possible and lawful to do so, we will also tell you with whom we shared your Personal data with so you can contact them directly.
|
||||
|
||||
**Right to restrict processing** : You may ask us to restrict or 'block' the processing of your personal data in certain circumstances, such as where you contest the accuracy of the data or object to us processing it (please read below for information on your right to object). We will tell you before we lift any restriction on processing. If we shared your Personal data with others, we will tell them about the restriction where possible. If you ask us, and where possible and lawful to do so, we will also tell you with whom we shared your Personal data so you can contact them directly.
|
||||
|
||||
**Right to data portability** : You have the right to obtain your personal data from us that you consented to give us or that was provided to us as necessary in connection with our contract with you, and that is processed by automated means. We will give you your personal data in a structured, commonly used and machine-readable format. You may reuse it elsewhere.
|
||||
|
||||
**Right to object** : You may ask us at any time to stop processing your personal data, and we will do so:
|
||||
|
||||
If we are relying on a legitimate interest to process your personal data (unless we demonstrate compelling legitimate grounds for the processing or if we are processing your personal data for direct marketing) and if we are processing your personal data for direct marketing, we may keep minimum information about you in a suppression list in order to ensure your choices are respected in the future and to comply with data protection laws (such processing is necessary for our and your legitimate interest in pursuing the purposes described above).
|
||||
|
||||
**Right to withdraw consent** : If we rely on your consent to process your personal data, you have the right to withdraw that consent at any time. Withdrawal of consent will not affect any processing of your data before we received notice that you wished to withdraw consent.
|
||||
|
||||
**Right to lodge a complaint with the data protection authority** : If you have a concern about our privacy practices, including the way we handled your personal data, you can report it to the data protection authority that is authorized to hear those concerns.
|
||||
|
||||
Please see the section below with our contact information on how to reach Open Sats to exercise your rights.
|
||||
|
||||
**Legitimate Interest**. "Legitimate interests" means our interests in conducting our charitable business and developing a relationship with you. This Privacy Policy describes when we process your Personal data for our legitimate interests, what these interests are and your rights. We will not use your Personal data for activities where the impact on you overrides our interests, unless we have your consent, or those activities are otherwise required or permitted by law.
|
||||
|
||||
**International Transfers of Personal Data**. Because Open Sats is a non-profit organization that is not subject to the jurisdiction of the United States Federal Trade Commission, it is not eligible for certification under the EU-U.S. and Swiss-U.S. Privacy Shield frameworks ("Frameworks") as set forth by the U.S. Department of Commerce regarding the processing of personal data transferred from the EU, United Kingdom, and Switzerland to the U.S. (for these purposes, reference to the EU also includes the European Economic Area countries of Iceland, Liechtenstein and Norway). However, Open Sats commits to process Personal data transferred from the EU to the United States in accordance with the principles of Notice, Choice, Accountability for Onward Transfer, Security, Data Integrity and Purpose Limitation, Access, and Recourse, Enforcement and Liability, as described below.
|
||||
|
||||
**Notice and Choice**. This Privacy Policy provides notice of the personal data collected and transferred to the United States and the choices that you have with respect to such personal data. It also provides information about the protections applicable to transferred data below.
|
||||
|
||||
**Accountability for Onward Transfers**. We may be accountable for the personal data transfer to third-party service providers. If we are and our third-party service providers process personal data in a manner inconsistent with these principles, we are responsible and liable for the harm caused, unless we prove that we are not responsible for the event giving rise to the damage.
|
||||
|
||||
**Security**. We maintain security measures to protect personal data as described in the "Data Security" section of this Privacy Policy.
|
||||
|
||||
**Data Integrity and Purpose Limitation**. We take reasonable steps to ensure that personal data is reliable for its intended use, and that it is accurate, complete and current for as long as we retain it. We will retain the data as long as necessary for the following purposes: delivering the Services, engaging in customer service, complying with legal obligations, auditing, performing security and fraud prevention, responding to legal and regulatory inquiries, and preserving or defending our legal rights or those of other users or third parties.
|
||||
|
||||
**Access**. EU users have certain rights to access, correct, amend, or delete personal data where it is inaccurate, or has been processed in violation of these principles. Please see the "Your Rights" section above for more information on the rights of users in the EU (and, to the extent applicable, users in Switzerland).
|
||||
|
||||
**Recourse, Enforcement, Liability**. Open Sats commits to resolve complaints about our processing of your personal data. European Union, United Kingdom, and Swiss users with inquiries or complaints regarding our processing of Personal data should first contact Open Sats as follows:
|
||||
|
||||
Email: info@opensats.org
|
||||
|
||||
Attention: Information Security
|
||||
|
||||
We will respond to such inquiries or complaints within thirty (30) days.
|
||||
|
||||
**Children's Privacy**
|
||||
|
||||
Open Sats does not knowingly collect or solicit personal information from anyone under the age of sixteen (16), or knowingly allow such persons to register. If we become aware that we have collected personal information from a child under the relevant age without parental consent, we take steps to delete that information. Where we specifically indicate that we collect personal information from children under sixteen (16), we will obtain the parent or guardian's consent and provide adequate notice.
|
||||
|
||||
**Links to Third Party Sites and Services**
|
||||
|
||||
The Sites may contain links to third party sites or online services. Please refer to the privacy policies of the relevant third-party websites or services to find out more about how they process and handle personal information.
|
||||
|
||||
**California Privacy Rights**
|
||||
|
||||
Only to the extent that Open Sats meets the minimum thresholds as required under California law to be subject to the California Privacy Rights Act of 2020, residents of California will be able to request and obtain from us once a year, free of charge, a list of the third parties to whom we have disclosed their personal information (if any) for their direct marketing purposes in the prior calendar year, as well as the types of personal information disclosed to those parties. If you are a California resident and would like to request this information, please submit your request in an email to [info@opensats.org](mailto:info@opensats.org). We reserve the right to ask for verification of your California residence and deny this request if Open Sats believes it is not subject to this requirement.
|
||||
|
||||
**Contact Us**
|
||||
|
||||
If you have any questions about our practices or this Privacy Policy, please contact us at [info@opensats.org](mailto:info@opensats.org), or write to us at: Open Sats Initiative, Attn: Legal Department, 3605 Glenwood Ave., Suite 500, Raleigh, North Carolina, 27612, USA.
|
||||
|
||||
**Changes to the Privacy Policy**
|
||||
|
||||
This Policy is current as of the effective date set forth above. If we change our privacy policies and procedures, we will post those changes on this page and/or continue to provide access to a copy of the prior version. If we make any changes to this Privacy Policy that materially change how we treat your personal information, we will endeavor to provide you with reasonable notice of such changes, such as via prominent notice on our Sites or to your email address of record, and where required by law, we will obtain your consent or give you the opportunity to opt out of such changes.
|
||||
|
||||
3564707v1.AWB.31306.G51883
|
||||
49
docs/general/projects/eae_attack_and_churning.md
Normal file
49
docs/general/projects/eae_attack_and_churning.md
Normal file
@@ -0,0 +1,49 @@
|
||||
---
|
||||
title: 'General Example Campaign'
|
||||
summary: "The EAE attack is one of Monero's privacy weak points. Churning may be a solution."
|
||||
nym: 'Dr. Nathan Borggren'
|
||||
website: 'https://github.com/nborggren'
|
||||
coverImage: '/img/project/EAE_diagram.png'
|
||||
git: 'https://github.com/nborggren'
|
||||
twitter: 'magicgrants'
|
||||
personalTwitter: 'magicgrants'
|
||||
personalWebsite: 'https://github.com/nborggren'
|
||||
type: 'Other Free and Open Source Project'
|
||||
date: '2023-06-08'
|
||||
staticXMRaddress: '87LZA8XLDvhVKLi974MaxUANcvkWdL6n986R7WNgKLXY16y31t69Z8228EWcg8THQq3tuAWfQ7Np35Tt3AhPrjzcNbm8Jr5'
|
||||
goal: 29260
|
||||
isFunded: false
|
||||
numdonationsxmr: 27
|
||||
totaldonationsinfiatxmr: 29260
|
||||
totaldonationsxmr: 220
|
||||
numdonationsbtc: 0
|
||||
totaldonationsinfiatbtc: 0
|
||||
totaldonationsbtc: 0
|
||||
fiatnumdonations: 0
|
||||
fiattotaldonationsinfiat: 0
|
||||
fiattotaldonations: 0
|
||||
---
|
||||
|
||||
### Funded Goal: 220 XMR (86 XMR contributed from MAGIC Monero Fund general fund)
|
||||
|
||||
### Start: June 2023
|
||||
|
||||
### End: September 2023
|
||||
|
||||
### Result: [Research paper](/pdf/Borggren-Sept-2023-Probing-the-Attacks-on-the-Privacy-of-the-Monero-Blockchain.pdf)
|
||||
|
||||
The EAE (Eve-Alice-Eve) attack is a threat to Monero user privacy. When a Monero user sends and/or receives funds repeatedly with an entity (Eve) that aims to trace funds, enough information in the local transaction graph and ring signatures may be available to make a probabalistic guess about the true destination or source of funds. There are different names for this attack and related attacks, which mostly differ in how many colluding entities are involved and how much information they may possess: EABE, poisoned outputs, Overseer, Flashlight, Tainted Dust, and Knacc attacks. One of the videos of the Breaking Monero series [discusses the EAE attack in detail](https://www.monerooutreach.org/breaking-monero/poisoned-outputs.html).
|
||||
|
||||
The EAE attack has been a concern of the Monero Research Lab for years, but rigorous measurement of the possible risk of this attack and possible defenses against it have not been successfully researched. "Churning", the practice of users sending funds to themselves, has been suggested as a possible defense, but neither its effectiveness nor details about best churning procedures have been determined by research to date.
|
||||
|
||||
Dr. Nathan Borggren has stepped up to investigate these important research questions about how to best protect Monero user privacy. Dr. Borggren is lead author of two papers about possible statistical threats to Monero user privacy: Borggren & Yao (2020) ["Correlations of Multi-input Monero Transactions"](https://moneroresearch.info/index.php?action=resource_RESOURCEVIEW_CORE&id=57) and Borggren et al. (2020) ["Simulated Blockchains for Machine Learning Traceability and Transaction Values in the Monero Network"](https://moneroresearch.info/index.php?action=resource_RESOURCEVIEW_CORE&id=58). His work analyzing transparent blockchains includes Borggren et al. (2017) "Deanonymizing Shapeshift: Linking Transactions Across Multiple Blockchains" and Borggren (2017) "Deep Learning of Entity Behavior in the Bitcoin Economy".
|
||||
|
||||
Dr. Borggren has proposed using Topological Data Analysis and Bayesian statistical methods to analyze the EAE attack and related attacks on Monero user privacy. The false positive and false negative rate of the EAE attack will be investigated through simulations and possibly analysis of Monero's mainnet blockchain. The full details of the plan are in [the research proposal](https://github.com/MAGICGrants/Monero-Fund/blob/main/projects/borggren_research-MAGIC-submission.pdf).
|
||||
|
||||
> "I think that the EAE attack is one of Monero's biggest _practical_ attack surfaces currently, and I see value in quantification plus real world data-informed best practices."
|
||||
|
||||
— [isthmus](https://github.com/Mitchellpkt), Monero Research Lab researcher and lead author of ["Fingerprinting a flood: Forensic statistical analysis of the mid-2021 Monero transaction volume anomaly"](https://mitchellpkt.medium.com/fingerprinting-a-flood-forensic-statistical-analysis-of-the-mid-2021-monero-transaction-volume-a19cbf41ce60)
|
||||
|
||||
> "Borggren has previously released fascinating papers quantifying Monero privacy pitfalls and I'm excited he is looking to continue."
|
||||
|
||||
— [ACK-J](https://github.com/ACK-J), author of ["Lord of the Rings: An Empirical Analysis of Monero's Ring Signature Resilience to Artifically Intelligent Attacks"](https://raw.githubusercontent.com/ACK-J/Monero-Dataset-Pipeline/main/Lord_of_the_Rings__An_Empirical_Analysis_of_Monero_s_Ring_Signature_Resilience_to_Artificially_Intelligent_Attacks.pdf)
|
||||
97
docs/general/terms.md
Normal file
97
docs/general/terms.md
Normal file
@@ -0,0 +1,97 @@
|
||||
# Open Sats Initiative terms of use
|
||||
|
||||
**Last updated: November 14, 2021**
|
||||
|
||||
Welcome to the Opensats.org website and/or mobile application (individually and collectively, the "Site"). Your access and use of the Site and of features, software, products and services provided by Open Sats Initiative ("Open Sats," "we," "us," or "our") through the Site, (individually and collectively, the "Service") is subject to the terms and conditions in this Terms of Use ("Terms of Use" or "Terms").
|
||||
|
||||
You must agree to the Terms in order to use the Site and/or the Service. If you use the Site and/or the Service, or click to accept or agree to the Terms if presented to you in a user interface for the Service, this is your acceptance of the Terms and your agreement to all of its terms and conditions. By accepting the Terms or using the Site and/or the Service, you represent and warrant that you are at least 18 years of age and have the legal capacity to enter a contract in the jurisdiction where you reside. If you do not accept the Terms, then you may not use the Site or the Service. If you are using the Site or the Service on behalf of another entity, you represent and warrant that you have full legal authority to bind such other entity to the Terms. If you do not have such authority, then you may not use the Site or the Service and you must discontinue all use of the Site and the Service immediately.
|
||||
|
||||
1. Our Services. The purpose of the Service is to promote the use of open source software to enhance blockchain technology and to promote the development of the Bitcoin infrastructure along with other free and open source software projects. As a non-profit organization ourselves, Open Sats Initiative does accept donations on the opensats.org website.
|
||||
2. Privacy Policy. By clicking on the Terms of Use and Privacy Policy box or using the Site or the Service, you represent that you have read and consent to our Privacy Policy located at [/privacy](/privacy) in addition to the Terms. Open Sats may revise the Privacy Policy at any time, and the new versions will be available on the Site. If at any point you do not agree to any portion of the Privacy Policy, you must immediately stop using the Site and/or Service.
|
||||
3. Terms of Use Updates. Open Sats may update the Terms at any time, and Open Sats will post the updated version of the Terms on the Site. You understand and agree that you will be deemed to have accepted the updated Terms if you use the Site or the Service after the updated Terms are posted on the Site. If at any point you do not agree to any portion of the Terms then in effect, you must immediately stop using the Site and the Service.
|
||||
4. Provision of the Services. You understand that all information, data, text, software, graphics or other materials ("Content"), whether publicly posted or privately transmitted, are the sole responsibility of the person from whom such Content originated. This means that you, and not Open Sats, is/are entirely responsible for all Content that you upload, post, email, transmit or otherwise make available via Services. Open Sats does not control the Content posted and, as such, does not guarantee the accuracy, integrity or quality of such Content. Under no circumstances will Open Sats be liable in any way for any Content, including, but not limited to, any errors or omissions in any Content, or any loss or damage of any kind incurred as a result of the use of any Content posted, emailed, transmitted or otherwise made available via the Open Sats Service.
|
||||
|
||||
You also agree that you will not collect or store personal data about other users in connection with any prohibited conduct and activities. You acknowledge that Open Sats may or may not pre-screen Content, but that Open Sats and its designees shall have the right (but not the obligation) in their sole discretion to pre-screen, refuse, move, or remove any Content that is available via the Services and which violates the Terms of Service. You agree that you must evaluate, and bear all risks associated with, the use of any Content, including any reliance on the accuracy, completeness, or usefulness of such Content. You acknowledge, consent and agree that Open Sats may access, preserve and disclose your account information and Content if required to do so by law or in a good faith belief that such access preservation or disclosure is reasonably necessary to:
|
||||
|
||||
- comply with legal process;
|
||||
- enforce the Terms of Use and the Privacy Policy;
|
||||
- respond to claims that any Content violates the rights of third parties;
|
||||
- respond to your requests for customer service; or
|
||||
- protect the rights, property or personal safety of Open Sats its users and the public.
|
||||
|
||||
1. Provision of the Service Not an Exchange. Open Sats is not a bitcoin exchange or wallet service and does not receive, hold or exchange digital currencies on behalf of any other person or entity. Open Sats does not withhold funds for tax purposes or otherwise.
|
||||
2. Tax Advice. Open Sats makes no representation as to whether all or any portion of your donations to us are tax deductible or eligible for tax credits. Open Sats will have no liability for any claim by any federal, state, local or any other tax authority with respect to the characterization on any applicable tax return of any donation by you. You should consult your tax advisor as to the amount of your donation that is tax deductible or eligible for tax recognition, if any.
|
||||
3. Access Restriction. Open Sats reserves the right to deny access or service to any person or entity at Open Sats' sole and absolute discretion. You acknowledge and agree that Open Sats may stop providing the Site and/or the Service or restrict your use of the Site and/or the Service at any time, without notifying you in advance, for any reason or no reason, including, without limitation, for any violation of the Terms and/or if Open Sats suspects that you have used any aspect of the Service to conduct any fraudulent or illegal activity. If Open Sats disables your access to your account, you may be prevented from accessing the Service, your account details and/or any materials contained in your account.
|
||||
4. Accounts and Security.
|
||||
5. Account. Open Sats may require registration for an account to access the Site and the Services. There will be a registration process for the creation of accounts to complete the registration process. You may be required to provide information about yourself or your company as part of the registration process or your continued use of the Service. You agree that any registration information that you submit to Open Sats will be correct, accurate, and up to date and that you will not impersonate any person or entity, or falsely state or otherwise misrepresent your affiliation with a person or entity.
|
||||
6. Account Security. Maintaining account security is very important. You are solely responsible for maintaining the confidentiality of your account password. You agree to notify Open Sats immediately if you become aware of any unauthorized use of your password or of your account.
|
||||
7. Account Sharing or Transfers. Accounts are registered to individuals or entities and may not be sold, traded, gifted or otherwise transferred at any time under any circumstances. An account may not be shared. Passwords may not be disclosed to anyone else.
|
||||
8. Cancellation by You. You have the right to cancel your account at any time. You may cancel your account by emailing us at info@opensats.org to submit a request to our support team.
|
||||
9. Termination by Open Sats. Open Sats may at any time terminate your account for any reason or no reason including, without limitation, if:
|
||||
|
||||
- Open Sats determines that you are (a) in breach of or otherwise acting inconsistently with the Terms or written agreements (b) engaging in fraudulent or illegal activities or other conduct that may result in liability to Open Sats;
|
||||
- Open Sats determines it is required by law to terminate your account; or
|
||||
- Open Sats decides to stop providing the Service or critical portions of the Service in the country where you reside, access the Site or use the Service or Open Sats determines that it is no longer in its charitable business interests to continue providing the Service or portions of the Service.
|
||||
|
||||
1. Content Licensing. Open Sats mission includes educating the public on free and open-source software through content such as articles, images, photographs, comments, software code, audio and video clips, and other materials (collectively, "Content"). Content is authored by Open Sats, contributors to Open Sats projects, and other sources.
|
||||
|
||||
Content authored by Open Sats is generally made available for public sharing and reuse through open licenses such as Creative Commons (for expressive material) or the Open Sats Public License. In most cases we ask Open Sats contributors to release Content under open licenses.
|
||||
|
||||
Some Content in our Site may be acquired from sources that prohibit further use of their Content without advance permission. Where possible, the Content will display a notice with the applicable license. You agree to abide by such notices. However it may occur that:
|
||||
|
||||
1. Some Content expressly indicates that the author does not intend for an open license to apply. You should contact the author or author's agent for permission to use such Content. Questions on Open Sats authored content can be sent to: info@opensats.org.
|
||||
2. Some Content contains trademarks, trade dress, logos and brand assets of Open Sats and other parties ("Trademarks"). Except for a few limited circumstances, Trademarks cannot be used without advance written permission of the owner of the Trademark.
|
||||
3. Software used by our Websites is licensed under the Open Sats Public License or similarly permissive open source licenses.
|
||||
4. Content Submissions **.** You may contribute Content when interacting with our Site and Services, including but not limited to commenting on an article, blogging, contributing code, or contributing graphics or written material (each a "Submission"). Unless your Submission is made under a separate agreement with Open Sats, in which case that agreement will govern, then
|
||||
|
||||
- For Submissions to Open Sats' open source Projects:
|
||||
|
||||
1. You agree to license your Submission under the terms of the corresponding license of the particular open source project to which you are contributing. For more information on the specific license, please see the applicable source.
|
||||
|
||||
- For all other Submissions, you agree to the following in connection with each:
|
||||
|
||||
1. You represent and warrant that your Submission will comply with these Terms and any additional terms that may govern your Submission.
|
||||
2. You hereby grant us a nonexclusive, royalty-free, worldwide, sublicensable (to those we work with) license to use your Submission in connection with the Content, Site, and Services and online and offline promotion of Open Sats' mission, products and services.
|
||||
3. You acknowledge that your Submissions may be accessible by other registered users of the applicable service or the public.
|
||||
4. If your Submission contains expressive material or software code, you agree to license it in a manner that is compatible with the particular website you are making a Submission to.
|
||||
5. You represent and warrant that you have the rights necessary to grant the rights granted herein, and further, that the uses contemplated under these Terms will not infringe the proprietary or intellectual property rights of any third party.
|
||||
6. You understand and agree that Open Sats reserves the right, at its discretion, to review, modify, or remove any Submission that it deems is objectionable or in violation of these Terms.
|
||||
|
||||
1. Effect of Account Termination or Cancellation. If you voluntarily terminate your account or allow your account to lapse, you will be able to reactivate that account at any time through the account interface on the Site. Accounts terminated by Open Sats for any type of abuse including, without limitation, a violation of the Terms, may not be reactivated for any reason. If you are blocked by us from accessing the Site or Service (including by blocking your IP address), you agree not to implement any measures to circumvent such blocking (e.g., by masking your IP address or using a proxy IP address).
|
||||
2. Restrictions and Conditions of Use.
|
||||
3. Use of the Site. Open Sats permits users to view and use the Site solely for personal or nonprofit use. You agree not to license, create derivative works from, transfer, sell or re-sell any information, content, materials, data or services obtained from the Site or through the Service unless specifically allowed by an Open Source license or express permission.
|
||||
4. Accessing the Service. You agree not to access, or attempt to access, the Service by any means other than through the user interface provided through the Site or any mobile application provided by Open Sats. You specifically agree not to access, or attempt to access, the Service through any automated means (including, without limitation, through the use of scripts, bots, spiders or web crawlers) and you agree to comply with the instructions contained in any robots.txt file present on the Site or the Service.
|
||||
5. No Violation of Laws. You agree that you will not, in connection with your use of the Site or the Service, violate any applicable law, ordinance, rule, regulation or treaty. Without limiting the foregoing, you agree that you will not make available through the Site and/or the Service any material or information that infringes any copyright, trademark, patent, trade secret, or other right of any party (including rights of privacy or publicity).
|
||||
6. Use Restrictions. You may not connect to or use the Site or the Service in any way that is not expressly permitted by the Terms.
|
||||
7. You may not: (a) remove any proprietary notices from the Service; (b) cause, permit or authorize the modification, creation of derivative works, translation, reverse engineering, decompiling, disassembling or hacking of the Site or the Service; (c) sell, assign, rent, lease, act as a service bureau, or grant rights in the Service, including, without limitation, through sublicense, to any other person or entity without the prior written consent of Open Sats; or (d) make any false, misleading or deceptive statement or representation regarding Open Sats and/or the Site or the Service.
|
||||
8. Without limiting the foregoing, you agree that you will not: (i) institute, assist, or become involved in any type of attack including, without limitation, denial of service attacks, upon the Site and/or the Service (or any servers, systems, or networks connected to the Site or the Service) or otherwise attempt to obstruct, disrupt, or interfere with the operation of the Site and/or the Service or any other person's or entity's use of the Site and/or the Service (or any servers, systems or networks connected to the Site or the Service); (ii) attempt to gain unauthorized access to the Site, the Service, accounts registered to other users, or any servers, systems or networks connected to the Site and/or the Service; (iii) use the Site or the Service for any commercial purpose or the benefit of any third party, or charge any person or entity, or receive any compensation for, the use of the Site or the Service, unless you are specifically authorized to do so in a separate written agreement with Open Sats; (iv) use the Site or the Service to (y) develop, generate, transmit or store information that is defamatory, harmful, abusive, obscene or hateful; or (z) perform any unsolicited commercial communication; or (v) engage in any activity that (A) constitutes harassment or a violation of privacy or threatens other people or groups of people; (B) is harmful to children in any manner; (C) constitutes phishing, pharming, or impersonates any other person or entity, or steals or assumes any person's identity (whether a real identity or online nickname or alias); (D) violates any applicable law, ordinance, rule, regulation or treaty or (E) in Open Sats' sole judgment, is objectionable or that restricts or inhibits any other person from using or enjoying our Site or Service, or which may expose us or our users to any harm or liability of any type.
|
||||
9. No Data Mining or Harmful Code. You agree that you will not (a) obtain or attempt to obtain any information from the Site or Services including, without limitation, any personal information of other account holders or other software data; (b) intercept, examine or otherwise observe any proprietary communications protocol used by the Site or the Service, whether through the use of a network analyzer, packet sniffer, or other device; or (c) use any type of bot, spider, virus, clock, timer, counter, worm, software lock, drop dead device, Trojan horse routing, trap door, time bomb or any other codes, instructions or third party software that is designed to provide a means of surreptitious or unauthorized access to, or distort, delete, damage or disassemble, the Site or the Service.
|
||||
10. Violation of the Terms. You acknowledge and agree that you are solely responsible, and Open Sats has no responsibility or liability to you or any other person or entity, for any breach by you of the Terms or for the consequences of any such breach.
|
||||
11. Links.
|
||||
12. Links from the Site. The Site may contain links to websites operated by other parties. Open Sats provides these links to other websites as a convenience and use of these websites is at your own risk. The linked websites are not under the control of Open Sats and Open Sats is not responsible for the content available on the other websites. Such links do not imply Open Sats' endorsement of information or material on any other website and Open Sats disclaims all liability with regard to your access to and use of such linked websites.
|
||||
13. Links to the Site. Unless otherwise set forth in a written agreement between you and Open Sats, you must adhere to Open Sats' linking policy as follows: (i) the appearance, position, and other aspects of the link may not be such as to damage or dilute the goodwill associated with Open Sats' and/or its licensors' names and trademarks; (ii) the appearance, position and other attributes of the link may not create the false appearance that your organization or entity is sponsored by, affiliated with, or associated with Open Sats; and (iii) when selected by a user, the link must display the Site on full-screen and not within a "frame" on the linking Site. Open Sats reserves the right to revoke its consent to the link at any time and in its sole discretion.
|
||||
14. Intellectual Property.
|
||||
15. Trademarks. The Open Sats marks are trademarks of Open Sats. Unless permitted in a separate written agreement with Open Sats, you do not have the right to use any of Open Sats' trademarks, service marks, or logos; and your unauthorized use of any of these may be a violation of federal and state trademark laws.
|
||||
16. Ownership. You acknowledge and agree that Open Sats, or its licensors, owns all right, title and interest in and to the Site and the Service, including all intellectual property, industrial property and proprietary rights recognized anywhere in the world at any time and that the Site and the Service are protected by U.S. and international copyright laws. Further, you acknowledge that the Service may contain information that Open Sats has designated as confidential and you agree not to disclose such information without Open Sats' prior written consent.
|
||||
|
||||
17. Location. The Site and the Service are operated by Open Sats in the United States. If you choose to access the Site and/or the Service from a location outside of the United States, you do so on your own initiative and you are responsible for compliance with applicable local laws.
|
||||
|
||||
18. Children. The Site and the Service are not directed toward children under 13 years of age nor does Open Sats knowingly collect information from children under 13 or allow them to create an account or access account features. If you are under 13, please do not submit any personal information about yourself to Open Sats.
|
||||
19. Term/Termination. These Terms will continue to apply until ended by either you or Open Sats. You can choose to end them at any time for any reason by discontinuing your use of our Site and Services and, if applicable, deleting your account. We may suspend or terminate your access to our Site and Services at any time for any reason, including, but not limited to, if we reasonably believe: (i) you have violated these Terms, our Privacy Policy, or other relevant policy; (ii) you create risk or possible legal exposure for us; or (iii) our provision of the Site and Services to you is no longer commercially viable. In all such cases, these Terms shall terminate, except that the following sections shall continue to apply: Indemnification, Disclaimer; Limitation of Liability, Modification, and Miscellaneous.
|
||||
20. Indemnification **.** You agree to defend, indemnify and hold harmless Open Sats, its contractors, contributors, licensors, and partners; and the respective directors, officers, employees and agents of the foregoing ("Indemnified Parties") from and against any and all third party claims and expenses, including attorneys' fees, arising out of or related to your use of our Site and Services (including, but not limited to, from your Submissions or from your violation of any these Terms).
|
||||
21. Disclaimer; Limitation of Liability. THE SITE AND SERVICES ARE PROVIDED "AS IS" WITH ALL FAULTS. TO THE EXTENT PERMITTED BY LAW, OPEN SATS AND THE INDEMNIFIED PARTIES HEREBY DISCLAIM ALL WARRANTIES, WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION WARRANTIES THAT THE CONTENT, SITE, AND SERVICES (AS APPLICABLE) ARE FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, AND NON-INFRINGING. YOU BEAR THE ENTIRE RISK AS TO USING THE SITE AND SERVICES FOR YOUR PURPOSES AND AS TO THE QUALITY AND PERFORMANCE OF THE SITE AND SERVICES, INCLUDING WITHOUT LIMITATION THE RISK THAT YOUR HARDWARE, SOFTWARE, OR CONTENT IS DELETED OR CORRUPTED, THAT SOMEONE ELSE GAINS UNAUTHORIZED ACCESS TO YOUR INFORMATION, OR THAT ANOTHER USER MISUSES OR MISAPPROPRIATES YOUR SUBMISSION. THIS LIMITATION WILL APPLY NOTWITHSTANDING THE FAILURE OF ESSENTIAL PURPOSE OF ANY REMEDY. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF IMPLIED WARRANTIES, SO THIS DISCLAIMER MAY NOT APPLY TO YOU. EXCEPT AS REQUIRED BY LAW, OPEN SATS AND THE INDEMNIFIED PARTIES WILL NOT BE LIABLE FOR ANY INDIRECT, SPECIAL, INCIDENTAL, CONSEQUENTIAL, OR EXEMPLARY DAMAGES ARISING OUT OF OR IN ANY WAY RELATING TO THESE TERMS OR THE USE OF OR INABILITY TO USE THE CONTENT, SITE, AND SERVICES, INCLUDING WITHOUT LIMITATION DIRECT AND INDIRECT DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, LOST PROFITS, LOSS OF DATA, AND COMPUTER FAILURE OR MALFUNCTION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES AND REGARDLESS OF THE THEORY (CONTRACT, TORT, OR OTHERWISE) UPON WHICH SUCH CLAIM IS BASED. THE COLLECTIVE LIABILITY OF OPEN SATS AND THE INDEMNIFIED PARTIES UNDER THIS AGREEMENT WILL NOT EXCEED \$500 (FIVE HUNDRED DOLLARS). SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL, CONSEQUENTIAL, OR SPECIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.
|
||||
22. Modifications to these Terms **.** We may update these Terms from time to time to address a new feature of the Site and Services or to clarify a provision. The updated Terms will be posted online. If the changes are substantive, we will announce the update through our usual channels for such announcements such as blog posts, banners, emails, or forums. Your continued use of our Site and Services after the effective date of such changes constitutes your acceptance of such changes. To make your review more convenient, we will post an effective date at the top of this page.
|
||||
23. Miscellaneous. These Terms constitute the entire agreement between you and Open Sats concerning our Site and Services and supersede any prior versions of these Terms. The Site and Services and these Terms are governed by the laws of the state of North Carolina, U.S.A., excluding its conflict of law provisions. All claims and disputes arising out of the Site and Services or these Terms shall be brought exclusively in the courts of Wake County, North Carolina, and you consent to personal jurisdiction in those courts. If any portion of these Terms is held to be invalid or unenforceable, the remaining portions will remain in full force and effect. In the event of a conflict between a translated version of these Terms and the English language version, the English language version shall control. In the event of a conflict between these Terms and relevant additional terms, the additional terms shall control.
|
||||
24. Contact Open Sats.
|
||||
|
||||
> Open Sats
|
||||
>
|
||||
> Attn: Open Sats – Legal Notices
|
||||
>
|
||||
> P.O. Box 20389
|
||||
>
|
||||
> Raleigh, NC 27612
|
||||
>
|
||||
> info@opensats.org
|
||||
>
|
||||
> 3566450v1.AWB.31306.G51883
|
||||
@@ -12,7 +12,7 @@ personalWebsite: 'https://www.leeclagett.com'
|
||||
type: 'Other Free and Open Source Project'
|
||||
staticXMRaddress: '8454MvGDuZPFP1WKSMcgbRJqV1sXHz7Z3KyURMpkoLXR3CJUZiebjymjQGc6YvTWqhFZEtJwELbcgFHZ9qGPwPsF7fWLWPT'
|
||||
goal: 28800
|
||||
isFunded: true
|
||||
isFunded: false
|
||||
numdonationsxmr: 43
|
||||
totaldonationsinfiatxmr: 28800
|
||||
totaldonationsxmr: 226.1
|
||||
|
||||
24
docs/privacyguides/about_us.md
Normal file
24
docs/privacyguides/about_us.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# About the MAGIC Monero Fund
|
||||
|
||||
MAGIC (Multidisciplinary Academic Grants in Cryptocurrencies) Grants is a 501(c)(3) U.S. nonprofit that focuses on building strong cryptocurrency communities and networks. [The MAGIC Monero Fund](https://magicgrants.org/funds/monero) is a subentity of MAGIC Grants guided by a five-member committee elected by [Monero community members](https://magicgrants.org/funds/monero/monero_fund_voters/).
|
||||
|
||||
### MAGIC Monero Fund Vision and Goals:
|
||||
|
||||
* Improve the Monero ecosystem.
|
||||
* Support Monero development and research.
|
||||
* Create Monero educational resources.
|
||||
* Fund Monero security audits.
|
||||
* Run essential services that support the Monero ecosystem.
|
||||
|
||||
### Committee Members
|
||||
|
||||
* [Rucknium](https://github.com/Rucknium) is a Monero Research Lab researcher and economist who has focused on statistical obfuscation on Monero and Bitcoin Cash.
|
||||
|
||||
* [kayabaNerve](https://twitter.com/kayabaNerve) is a Monero-ecosystem developer and security researcher who was the first to implement Monero atomic swaps with ASMR.
|
||||
|
||||
* [monerobull](https://twitter.com/monerobull) is a distributor of marketing materials for Monero Outreach and moderates various communication channels of the Monero community.
|
||||
|
||||
* [artlimber](https://github.com/artlimber) is a Monero user and community supporter who believes privacy is a human right.
|
||||
|
||||
* [kowalabearhugs](https://twitter.com/kowalabearhugs) is a Monero community member, photographer, artist, seasonal farmer, and offseason wanderer.
|
||||
|
||||
80
docs/privacyguides/apply_research.md
Normal file
80
docs/privacyguides/apply_research.md
Normal file
@@ -0,0 +1,80 @@
|
||||
# MAGIC Monero Fund Request for Research Proposals
|
||||
|
||||
## Mission
|
||||
|
||||
The MAGIC Monero Fund is offering a grant program to support actionable Monero research, especially research relating to privacy, security, user experience, and efficiency. Proposals can be related to the Monero protocol directly, or they can be related to other areas of the Monero ecosystem.
|
||||
|
||||
## Target Research Areas
|
||||
|
||||
We are interested in Monero's [open research questions](https://github.com/monero-project/research-lab/issues/94), along with the following:
|
||||
|
||||
- Security proofs around Monero's existing constructions
|
||||
- Arithmetic-circuit-based membership proofs, specifically ones without a trusted setup based on battle-tested cryptographic assumptions
|
||||
|
||||
While the above topics are especially encouraged, the Fund is open to funding other topics as well.
|
||||
|
||||
The proposal's chance to be approved will be increased if it also helps support one or more of the additional mission areas of the MAGIC Monero Fund: Development, Security (including audits); Critical Infrastructure; Community Building and Community Infrastructure; Interoperability; Feature Enhancements; Efficiency Improvements; Educational Materials.
|
||||
|
||||
## Funding Amount
|
||||
|
||||
The MAGIC Monero Fund anticipates funding requests of the equivalent of 5,000 to 20,000 USD at this time.
|
||||
|
||||
## Deadline
|
||||
|
||||
The MAGIC Monero Fund accepts applications on a rolling basis. Applications will be notified of the committee's vote on approval within three weeks of submission except in extraordinary circumstances.
|
||||
|
||||
## Proposal Format
|
||||
|
||||
Applicants must submit their applications on the web form [here](/apply). Alternatively, applicants can submit a PDF file by email to MoneroFund@magicgrants.org . Applicants are free to use their legal name or a pseudonym at this step, although note the "Eligibility" section below.
|
||||
|
||||
The research plan should be 3-5 pages (not counting citations, any images, and biographical sketch) and include the following:
|
||||
|
||||
* The research question you seek to answer, and how the Monero Project benefits from the research.
|
||||
|
||||
* A literature review of existing work and how your proposal improves upon it.
|
||||
|
||||
* Any preliminary work you have already completed.
|
||||
|
||||
* Description of the plan to carry out the research.
|
||||
|
||||
* A plan to work with Monero's developers and/or researchers to integrate the results of the research into Monero's protocol or ecosystem.
|
||||
|
||||
* A budget, likely consisting mostly of labor costs for the researcher(s). This should include the desired payment schedule, which should be no more frequent than monthly. Any additional budgetary item such as equipment should be included as well. Specify the desired form of payment, which can be cryptocurrency or fiat currency.
|
||||
|
||||
* OPTIONAL: A biographical sketch such as a resume or CV. Alternatively, a list of contributions to open source projects.
|
||||
|
||||
|
||||
## Computing Resources Available
|
||||
|
||||
Computing and data storage resources can be made available to applicants depending on research requirements, resource availability, and vetting by a third party. These resources include a research computing server with a 64-thread Threadripper CPU, 256 GB RAM, 2TB SSD, and 12TB RAID1 HDD.
|
||||
|
||||
## Proposal Evaluation Criteria
|
||||
|
||||
Submitted proposals will be evaluated by the committee based on the following criteria:
|
||||
|
||||
* Impact on Monero's privacy, scaling, decentralization, and/or user experience
|
||||
|
||||
* Feasibility of research plan
|
||||
|
||||
* Prior work and qualifications of applicant(s)
|
||||
|
||||
* Clear plan to integrate research findings into Monero's protocol and/or ecosystem
|
||||
|
||||
|
||||
## Eligibility
|
||||
|
||||
All competent researchers are eligible to apply, regardless of educational attainment or occupation. However, as a nonprofit organization registered under U.S. tax laws, MAGIC Grants is required to comply with certain laws when disbursing funds to grant recipients.
|
||||
|
||||
Grant recipients must complete a Due Diligence checklist, which are the last two pages of [this document](https://magicgrants.org/funds/MAGIC%20Fund%20Grant%20Disbursement%20Process%20and%20Requirements.pdf). This includes the collection of your ID and tax information. We will conduct sanctions checks.
|
||||
|
||||
## Vulnerability Research
|
||||
|
||||
If your proposal seek to uncover weaknesses in the privacy and/or security features of Monero as it exists today, then the Committee will require that you share any significant weaknesses with the Committee (and any critical vulnerabilities with [Monero's official Vulnerability Response Process](https://github.com/monero-project/meta/blob/master/VULNERABILITY_RESPONSE_PROCESS.md)) 90 days before publishing the research so that action can be taken to mitigate the vulnerabilities.
|
||||
|
||||
## How to Submit an Application
|
||||
|
||||
Applicants must submit their applications on the web form [here](/apply). Alternatively, applicants can submit a PDF file by email to MoneroFund@magicgrants.org
|
||||
|
||||
## Contact
|
||||
|
||||
Contact MoneroFund@magicgrants.org for further questions.
|
||||
75
docs/privacyguides/faq.md
Normal file
75
docs/privacyguides/faq.md
Normal file
@@ -0,0 +1,75 @@
|
||||
# FAQ
|
||||
|
||||
## What is the mission statement of the Monero Fund?
|
||||
|
||||
- We are a committee of a 501(c)(3) public charity that funds Monero-related open source software, research and associated educational initiatives.
|
||||
|
||||
|
||||
## How are funds distributed?
|
||||
|
||||
- Donations to the **general fund** are disbursed by our committee as needs arise. For projects listed on our site, we review and approve submissions carefully to ensure donated funds are positively impacting the Monero ecosystem. To hold researchers and developers accountable, payment schedules are aligned with approved project milestones.
|
||||
|
||||
|
||||
## How much of my donation goes towards individuals and projects supported by the Monero Fund?
|
||||
|
||||
- We set up campaigns to closely match the amount needed to pay these individuals and projects. There are some credit card processing fees and other related fees that we try to estimate. Typically, we add a buffer of 3% to the project campaign to account for these.
|
||||
- If there are any proceeds are retained by the MAGIC Monero Fund, and will be used on related projects.
|
||||
- If a campaign fails to raise the full amount of funds, then the committee will work with the intended recipient to revise the scope of the project, or the raised funds will be used on related projects.
|
||||
|
||||
## Can an individual or project be funded by both the Monero Community Crowdfunding System (CCS) and the Monero Fund?
|
||||
|
||||
- Yes. There is no expectation of exclusivity, but a proposer cannot raise funds elsewhere for the exact same work that a MAGIC Monero Fund proposal is intended to cover. This allows a proposer to maintain multiple, simultaneous funding options, so long as the scope of work included in the proposal is unique.
|
||||
|
||||
## Do you distribute grants in Monero, Bitcoin or fiat?
|
||||
|
||||
- We distribute grants in the currency of the researchers choosing. We prefer to pay in XMR but will gladly distribute funds in BTC, USD, or other crypto or fiat currencies that are highly liquid.
|
||||
|
||||
## How do you collect Monero donations?
|
||||
|
||||
- We use BTCPay Server to receive all cryptocurrency donations. For fiat donations, we leverage Stripe Payments.
|
||||
|
||||
|
||||
## Can you provide the view key to verify the Fund's incoming Monero donations?
|
||||
|
||||
- Yes. You can create a view-only Monero wallet with this information:
|
||||
- Main address:
|
||||
```
|
||||
4458gM5iAPuJBeVf5u9DwS4Hj82qNPzAcgD7wF9VrRCRb4M635UtmZNPPDonqXkBsb2RmKjUSRLXtJNZCjZgnNFKKW3SxBz
|
||||
```
|
||||
- Secret view key:
|
||||
```
|
||||
2595ab540844231f66c2266f12b174461f81c09b39010dc42697a6a58a7d680c
|
||||
```
|
||||
- Restore height: 2724728
|
||||
|
||||
|
||||
## How can I communicate with you?
|
||||
|
||||
- You can reach the committee via [Discord](https://discord.gg/yEuhhdtbHN), Matrix or [email](mailto:MoneroFund@magicgrants.org).
|
||||
- Applications are reviewed as submitted. Research approval depends on several factors, including funding availability. Projects that align with our mission statement are encouraged to apply. Committee members evaluate each application based on technical merit, potential impact, and the team's ability to execute.
|
||||
- All projects should be free and open source and related to Monero or an ancillary technology (like Tor, etc.) which helps Monero use. Your project must align with the mission of our charity to be eligible for donations.
|
||||
- To reach MAGIC Grants, please [email us](mailto:info@magicgrants.org).
|
||||
|
||||
|
||||
## How can I submit a project for fundraising?
|
||||
|
||||
- Any project that is free and open source and is aligned with the Monero Fund mission are free to [submit an application](/apply) for their project to be listed on the [Monero Fund](/projects) project page.
|
||||
- All applications which fulfill the criteria will be evaluated by the Monero Fund Committee. Upon approval, projects will be listed on the MoneroFund project portal. Donors will be able to contribute funds directly to the these pre-approved, mission-aligned projects.
|
||||
- If you are helping Monero and Free and Open Source Software (FOSS), please [submit an application](/apply) to be listed on our site.
|
||||
|
||||
|
||||
## Are my donations tax deductible?
|
||||
|
||||
- Yes. MAGIC Monero Fund is committee under Multidisciplinary Academic Grants in Cryptocurrencies (MAGIC Grants), a 501(c)(3) non-profit organization. All gifts and donations are tax-deductible in the USA.
|
||||
- If you would like to receive a tax deduction, we may need to collect supplementary information such as your name and email for required record keeping. If you donate over $500 with cryptocurrencies, you will need to fill out [Form 8283](https://www.irs.gov/pub/irs-pdf/f8283.pdf) and email that form to [info@maigcgrants.org](mailto:info@magicgrants.org) for us to sign Part V.
|
||||
|
||||
The Monero Fund relies on donors like you to help promote and support a sustainable ecosystem of contributors to the Monero ecosystem. We greatly appreciate your contributions.
|
||||
|
||||
# Can I join the committee?
|
||||
|
||||
- MAGIC Monero Fund committee elections happen annually. Learn more on the [MAGIC Grants website](https://magicgrants.org/funds/monero).
|
||||
|
||||
# Can I donate with bank transfer / wire?
|
||||
|
||||
- Yes! [Email us](mailto:MoneroFund@magicgrants.org), and we will send you the bank details and manually add your donation. We can accept domestic and international wire transfers. Wires are appreciated for large donations, so that ~3% more of your donation can go to the recipient instead of credit card fees.
|
||||
|
||||
186
docs/privacyguides/privacy.md
Normal file
186
docs/privacyguides/privacy.md
Normal file
@@ -0,0 +1,186 @@
|
||||
# Privacy Policy
|
||||
|
||||
**Last Updated: November 5, 2021**
|
||||
|
||||
Open Sats Initiative's core purpose is to foster an ecosystem that supports the collaborative and public development of free and open-source software projects (each, a "Project"). This privacy policy ("Privacy Policy") describes our policies and procedures about the collection, use, disclosure and sharing, or other processing of your personal information when you use our websites (e.g., opensats.org) or participate in or use our project sites (collectively, the "Sites"), as well as when you interact with or participate in our educations and training programs and events. (collectively, the "Services"). This Privacy Policy applies to activities by Open Sats Initiative and its affiliates, subsidiaries and related entities (collectively "Open Sats" "we" or "us"), including activities that we perform for other entities through third party agreements.
|
||||
|
||||
For purposes of the General Data Protection Regulation ("GDPR"), Open Sats is the controller of your personal information. Where processing of personal information is undertaken by our affiliates, subsidiaries and related entities, they are a joint controller with Open Sats Initiative for your personal information.
|
||||
|
||||
Capitalized terms that are not defined in this Privacy Policy have the meaning given them in our Terms and Conditions (the "Terms"). In this Privacy Policy, "personal information" includes references to "personal data" as defined under applicable laws. Your use of our Sites and Services, and any dispute over privacy, is subject to this Policy and the relevant Terms, including the applicable limitations on damages and the resolution of disputes. The Terms are incorporated by reference into this Policy.
|
||||
|
||||
## Personal Information That Open Sats Collects
|
||||
|
||||
We collect personal information directly from individuals, from third parties, and automatically through the Sites and Services. You do not have to provide us your personal information. However, if you choose not to disclose certain information, we will not be able to provide you with access to certain services or features, including registering on the Sites, registration for training, events, or other programs, or participation in certain aspects of our open-source projects.
|
||||
|
||||
_Registration Information._ We collect personal information when you register for an account or register to participate in an Open Sats event or Program:
|
||||
|
||||
_Account and Profile Information._ Users may sign up for, request, or order our Services and may register to receive materials on our Sites. Users may also create a login, which is a single sign-on account which is used for common access to many of our Services. Personal information collected on the Sites includes community forum content, profiles, photographs, names, unique identifiers, information about your current and past employment affiliations, contact information (address, telephone number, email address, preferred pronoun, etc.), and transaction information (to the extent you share that information). In order to access certain personalized services on the Sites, you may be asked to also create and store a username and password for an account from Open Sats. In order to improve the functioning of the website and our subsequent communications to users we may also ask users to provide additional optional information regarding your interests, demographics, experience and detailed contact preferences.
|
||||
|
||||
_Donations._ To register for and participate in the Open Sats Projects and related Services, users must have an active login ID and account (see above for information collected related to account registration). Open Sats may collect the following information related to financial contributions and :Depending on the Community Bridge Services in which users participate, we may also collect additional information relating to their use of those Services, including:
|
||||
|
||||
- _Donations_: We collect information about financial contributions made, as well as and funds received through the Sites. Open Sats generally only records the result of the transaction and any references to the transaction record provided by the third-party site. For example, when users make financial contributions to projects, we collect and process the donation amount, allocation to certain projects, and identifiers used to associate that donation with the donor and project in the project's open and transparent public ledger (unless otherwise agreed to by the donor and Open Sats. We also collect disbursement amount and category, recipient name and email, and identifiers related to disbursements of project funds for projects. Further, we use third-party services including Stripe to facilitate funding and disbursements. If applicable, the third-party site may collect payment information directly to facilitate a transaction.
|
||||
|
||||
_Events Registration._ When you register for an Open Sats event (training, conference, or other event) to participate as an attendee, a speaker or a sponsor, we collect personal information that includes name, company, contact information, and other information. We may also collect other optional personal information such as likes, interests, preferred pronoun, dietary restriction, size preferences for conference attire gifts and other background information. In addition, if you provide it, we may collect (1) personal information about disabilities, medical conditions and allergies in order to provide appropriate accommodations for attendees, and (2) personal information about your citizenship, date of birth, and passport details if you request assistance from us with obtaining a visa letter to travel to one of our events.
|
||||
|
||||
For in-person events requiring attendees to be vaccinated against COVID-19, in order to provide a safer environment for attendees and staff, we may collect information to verify your identity and COVID-19 vaccination status. We may collect this information via direct verification of identity and vaccination status documents by Open Sats staff or third-party contractors, and/or through the use of third-party vaccination status apps and service providers.
|
||||
|
||||
_Training and Certification Exam Registration_. When you participate in one of our training or certification programs, we collect registration-related personal information that includes name, company, certifications, contact information, and other information depending on the circumstances.
|
||||
|
||||
_Registration for Projects._ You can register to receive access to various information provided by Open Sats and its free and open-source Projects relating to the open-source ecosystem, open source project development, collaboration and best practices. This includes providing us with personal information such as your email address and name to receive newsletters, mailing list postings and social media postings, to view webinars, and to access other resources made available by Open Sats and its Projects.
|
||||
|
||||
**Your Contributions to Open Source Projects**.
|
||||
|
||||
_Project Integrity and Credit for Attribution_. When you contribute source code, documentation or other content to one of our Projects (whether on your own behalf or through a third party entity), we collect and store the information and content that you contribute. This includes the contents of those contributions, as well as information required to confirm the provenance of intellectual property contained in those contributions, and personal information that you make publicly available in the record of the contribution pursuant to sign-offs under the a Certificate of Origin as Follows:
|
||||
|
||||
_Developer's Certificate of Origin:_
|
||||
|
||||
By making a contribution to this project, I certify that:
|
||||
|
||||
(a) The contribution was created in whole or in part by me and I have the right to submit it under the open-source license indicated in the file; or
|
||||
|
||||
(b) The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate open-source license and I have the right under that license to submit that work with modifications, whether created in whole or in part by me, under the same open source license (unless I am permitted to submit under a different license), as indicated in the file; or
|
||||
|
||||
(c) The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not modified it.
|
||||
|
||||
(d) I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the open source license(s) involved. [end]
|
||||
|
||||
Some Projects require additional agreements or information pursuant to their intellectual property policies; in such cases we collect and store information related to your acceptance of those agreements. We may also collect information relating to your participation in technical, governance, or other Project-related meetings.
|
||||
|
||||
_Other Project-related Content._ The content you provide in relation to Projects also includes materials that you make publicly available in connection with Project development, collaboration and communication, such as on mailing lists, blogs, Project pages and issue trackers, and related services.
|
||||
|
||||
_Your Content_. We collect and store the information and content that you post to the Sites, including your questions, answers, comments, forum postings, and responses to surveys.
|
||||
|
||||
_Communications_. When you communicate with us (via email, phone, through the Sites or otherwise), we may maintain a record of your communication.
|
||||
|
||||
_Payment Information._ To participate in or purchase Services (including registering for events, training and certification exams), users may be asked to be directed to a third-party site, such as Stripe, to pay for their purchases. If applicable, the third-party site may collect payment information directly to facilitate a transaction. Open Sats generally only records the result of the transaction and any references to the transaction record provided by the third-party site.
|
||||
|
||||
_Automatically Collected Information._ In addition, Open Sats may automatically collect the following information about users' use of the Sites or Services through cookies, web beacons, and other technologies: your domain name; your browser type and operating system; web pages you view; when you open certain emails we send; links you click; your IP address; your country of location; the length of time you visit our Sites and or use our Services; and the referring URL, or the webpage that led you to our Sites. We may combine this information with other information that we have collected about you, including, where applicable, your user name, name, and other personal information.
|
||||
|
||||
**Basis for Use of Personal Information:**
|
||||
|
||||
**Purposes and Legitimate Interests**
|
||||
|
||||
Open Sats uses the personal information we collect for our legitimate non-proft and charitable business interests, which include the following purposes:
|
||||
|
||||
- _Providing our Sites and Services_. To provide the Services and our Sites, to communicate with you about your use of our Sites and Services, to respond to your inquiries, provide support and maintenance of the Sites and for other purposes to support users and the community.
|
||||
- _Operating our Open-Source Projects_. To enable communication between and among open source developers in the community; to facilitate and document Project governance and technical decision-making; to maintain, and make publicly available on a perpetual basis, records regarding intellectual property provenance and license compliance for Project contributions; and for related activities to further Open Sats's core purpose of fostering an ecosystem that supports the collaborative and public development of free and open source software projects. See the "Project Integrity and Credit for Attribution" section above for more information.
|
||||
- _Maintain our Training and Certification Programs_. To maintain records about who has attended or registered to attend educational or training programs.
|
||||
- _Event Administration_. To plan, organize, and facilitate access to events and related services and activities, and to carry out informative and safe events for participants, including attendees, speakers and sponsors. If you provide us information about disabilities, medical conditions and allergies, we will use this information in order to provide appropriate accommodations for attendees and to ensure their health and safety; we will not use this information for other purposes, unless required by law or as necessary to defend our legal rights. For in-person events requiring attendees to be vaccinated against COVID-19, we use information regarding your COVID-19 vaccination status to provide a safer environment for attendees and staff, in order to confirm vaccination status before permitting access to the event venue space.
|
||||
- _Personalization_. To tailor the content and information that we may send or display to you on our Sites and in our Services, to offer location customization and personalized help and instructions and to otherwise personalize your experiences.
|
||||
- _Marketing and Promotions_. For marketing and promotional purposes, such as to send you news and newsletters, special offers, and promotions, or to otherwise contact you about Projects, Services, events, trainings or other information we think may interest you related to Open Sats, and, subject to applicable law, our affiliates, subsidiaries and managed services entities.
|
||||
- _Advertising_. For targeting advertising to you on our Sites and third-party sites and measuring the effectiveness and reach of ads and services (through third-party ad networks and services).
|
||||
- _Analytics_. To gather metrics to better understand how users access and use our Sites and Services and participate in our Projects; to evaluate and improve the Sites, including personalization, to develop new services; and to understand metrics regarding the community health of our Projects. If a user voluntary provides and explicitly consents to our processing of personal information regarding their demographics and socioeconomics, we process such personal information for the specific purposes for which you have consented, which may include for the purpose of compiling, analyzing and disclosing aggregate statistics regarding diversity of participation in open source projects and communities.
|
||||
- _Compliance_. To comply with legal obligations and requests. For example, to comply with laws that compel us to disclose information to public authorities, courts, law enforcement or regulators, maintain records for a certain period, or maintain records demonstrating enforcement and sublicensing of our trademarks and those of our Projects.
|
||||
- _Business and Legal Operations_. As part of our general charitable and non-profit business and legal operations (e.g., accounting, record keeping, and for other business administration purposes), and as necessary to establish, exercise and defend (actual and potential) legal claims.
|
||||
- _Prevent Misuse_. Where we believe necessary to investigate, prevent or take action regarding illegal activities, suspected fraud, situations involving potential threats to the safety of any person or violations of the relevant Terms and Conditions or this Privacy Policy.
|
||||
|
||||
**Sharing of Personal Information**
|
||||
|
||||
We disclose personal information as set forth below, and where individuals have otherwise consented:
|
||||
|
||||
- _Publicly Available Information, including Your Contributions to Open-Source Projects._ User names, other user ids, email addresses and other attribution information related to the information and contributions that a user posts in conjunction with or subject to an Open Source license are publicly available in the relevant Project source code repositories. Your contributions to Open-Source Projects, and certain of your other Content such as comments and messages posted to public forums, are available to other participants and users of our Projects and of our Services, and may be viewed publicly. In some cases you may be able to provide Project or contribution-related information directly to third-party sites and services; these third parties are independent data controllers and their use of your personal information is subject to their own policies.
|
||||
- _Service Providers._ We may share your information with third party service providers who use this information to perform services for us, such as payment processors, hosting providers, auditors, advisors, contractors and consultants.
|
||||
- _Affiliates._ The information collected about you may be accessed by or shared with subsidiaries and affiliates of Open Sats, whose use and disclosure of your personal information is subject to this Privacy Policy, unless an affiliate has its own separate privacy policy.
|
||||
- _Event Participants_. If you register for an event, we may ask for your consent to share your personal information with third party sponsors and other participants. We will not share your event information with third parties without your consent. For in-person events requiring attendees to be vaccinated against COVID-19, we may use third-party service providers to validate your identity and COVID-19 vaccination status.
|
||||
- _Training and Program Sponsors_. If you participate in one of our education, certification, or training programs that a third party has sponsored or engaged us to provide to you and others (for example, your employers), we may receive attendee list information from them and may share information about your completion of the program, including confirmation of your participation and your certification exam results, as applicable; these third parties are independent data controllers and their use of your personal information is subject to their own policies. You may also elect to provide third parties (e.g., your employers or your prospective employers) with information that will enable them to look up your certification exam status; if you do so, we may share your certification exam status with such third parties.
|
||||
- _Legally Required._ We may disclose your information if we are required to do so by law (including to law enforcement in the U.S. and other jurisdictions).
|
||||
- _Protection of Rights._ We may disclose information where we believe it necessary to respond to claims asserted against us or, comply with legal process (e.g., subpoenas or warrants), enforce or administer our agreements and terms, for fraud prevention, risk assessment, investigation, and protect the rights, property or safety of Open Sats, its Users, participants in its events or Projects, or others.
|
||||
- _Anonymized and Aggregated Information._ We may share aggregated information with third parties for research, marketing, analytics and other purposes, provided such information does not identify a particular individual.
|
||||
|
||||
**Cookies, Tracking, and Interest-Based Ads**
|
||||
|
||||
We and our third-party providers use cookies, pixel tags, JavaScript, log files, and other mechanisms to automatically collect and record information about your usage and browsing activities on our Site and across third party sites or online services. We may combine this information with other information we collect about users. Below, we provide a brief summary these activities.
|
||||
|
||||
- _Cookies._ These are small files with a unique identifier that are transferred to your browser through our websites. They allow us to remember users who are logged in, to understand how users navigate through and use the Sites, and to display personalized content and targeted ads (including on third party sites and applications).
|
||||
- _Pixels, web beacons, clear GIFs_ These are tiny graphics with a unique identifier, similar in function to cookies, which we track browsing activities.
|
||||
- _Analytics Tools._ We may use internal and third-party analytics tools. The third-party analytics companies we work with may combine the information collected with other information they have independently collected from other websites and/or other online products and services. Their collection and use of information is subject to their own privacy policies.
|
||||
|
||||
**Targeted Ads.** As discussed in our Cookie Policy, we may work with third-party advertisers to display more relevant ads on our website and on third party sites; these third parties may display ads to you based on your visit to our Sites and other third-party sites.
|
||||
|
||||
**Data Security**
|
||||
|
||||
We have implemented commercially reasonable precautions designed to protect the information we collect from loss, misuse, and unauthorized access, disclosure, alteration, and destruction. Please be aware that despite our best efforts, Open Sats provides no guarantee that any security measure will be completely and totally secure.
|
||||
|
||||
We are not responsible for any lost, stolen, or compromised passwords or for any activity on your account via unauthorized password activity. We ask you to promptly notify us if you become aware that any information provided by or submitted to our Sites or through our Services is lost, stolen, or used without permission at info@opensats.org.
|
||||
|
||||
**Marketing Choices**
|
||||
|
||||
You may opt out of or withdraw your consent to receive direct marketing emails from us by using the unsubscribe or opt out mechanisms included in our marketing emails or by emailing info@opensats.org. You may also unsubscribe from mailing lists via the applicable mailing list's subscription website or, in some cases, by using the unsubscribe mechanisms included in such emails.
|
||||
|
||||
**Retention of Your Personal Information**
|
||||
|
||||
We generally keep personal information only for as long as required to fulfill the purposes for which it was collected. However, in some circumstances, we may retain personal information for other periods of time, for instance where we are required to do so in accordance with legal, tax and accounting requirements, or if required to do so by a legal process, legal authority, or other governmental entity having authority to make the request, for so long as required. In specific circumstances, we may also retain your personal information for longer periods of time corresponding to a statute of limitation, so that we have an accurate record of your dealings with us in the event of any complaints or challenges.
|
||||
|
||||
**International Information:**
|
||||
|
||||
**Scope**. This section applies to individuals in the European Union "EU" (for these purposes, reference to the EU also includes the European Economic Area countries of Iceland, Liechtenstein and Norway and, to the extent applicable, Switzerland).
|
||||
|
||||
**Data Controller**. Open Sats is the data controller for the processing of Personal data related to donor and non-profit accounts and information on our Sites. You can find our contact information below.
|
||||
|
||||
Open Sats is the data processor with respect to processing personal information related to donations and any interaction with Projects. If you wish to exercise one of the below rights with respect to your contribution (whether financial or to a Project) please contact us.
|
||||
|
||||
**Your Rights**. Pursuant to the GDPR, to the extent Open Sats is a data controller of your Personal data, you have the following rights in relation to your personal data, under certain circumstances:
|
||||
|
||||
**Right of access** : If you ask us, we will confirm whether we are processing your personal data and, if so, provide you with a copy of that personal data along with certain other details. If you require additional copies, we may need to charge a reasonable fee.
|
||||
|
||||
**Right to rectification** : If your personal data is inaccurate or incomplete, you are entitled to ask that we correct or complete it. If we shared your personal data with others, we will tell them about the correction where possible. If you ask us, and where possible and lawful to do so, we will also tell you with whom we shared your Personal data so you can contact them directly.
|
||||
|
||||
**Right to erasure** : You may ask us to delete or remove your personal data, such as where you withdraw your consent. If we shared your data with others, we will tell them about the erasure where possible. If you ask us, and where possible and lawful to do so, we will also tell you with whom we shared your Personal data with so you can contact them directly.
|
||||
|
||||
**Right to restrict processing** : You may ask us to restrict or 'block' the processing of your personal data in certain circumstances, such as where you contest the accuracy of the data or object to us processing it (please read below for information on your right to object). We will tell you before we lift any restriction on processing. If we shared your Personal data with others, we will tell them about the restriction where possible. If you ask us, and where possible and lawful to do so, we will also tell you with whom we shared your Personal data so you can contact them directly.
|
||||
|
||||
**Right to data portability** : You have the right to obtain your personal data from us that you consented to give us or that was provided to us as necessary in connection with our contract with you, and that is processed by automated means. We will give you your personal data in a structured, commonly used and machine-readable format. You may reuse it elsewhere.
|
||||
|
||||
**Right to object** : You may ask us at any time to stop processing your personal data, and we will do so:
|
||||
|
||||
If we are relying on a legitimate interest to process your personal data (unless we demonstrate compelling legitimate grounds for the processing or if we are processing your personal data for direct marketing) and if we are processing your personal data for direct marketing, we may keep minimum information about you in a suppression list in order to ensure your choices are respected in the future and to comply with data protection laws (such processing is necessary for our and your legitimate interest in pursuing the purposes described above).
|
||||
|
||||
**Right to withdraw consent** : If we rely on your consent to process your personal data, you have the right to withdraw that consent at any time. Withdrawal of consent will not affect any processing of your data before we received notice that you wished to withdraw consent.
|
||||
|
||||
**Right to lodge a complaint with the data protection authority** : If you have a concern about our privacy practices, including the way we handled your personal data, you can report it to the data protection authority that is authorized to hear those concerns.
|
||||
|
||||
Please see the section below with our contact information on how to reach Open Sats to exercise your rights.
|
||||
|
||||
**Legitimate Interest**. "Legitimate interests" means our interests in conducting our charitable business and developing a relationship with you. This Privacy Policy describes when we process your Personal data for our legitimate interests, what these interests are and your rights. We will not use your Personal data for activities where the impact on you overrides our interests, unless we have your consent, or those activities are otherwise required or permitted by law.
|
||||
|
||||
**International Transfers of Personal Data**. Because Open Sats is a non-profit organization that is not subject to the jurisdiction of the United States Federal Trade Commission, it is not eligible for certification under the EU-U.S. and Swiss-U.S. Privacy Shield frameworks ("Frameworks") as set forth by the U.S. Department of Commerce regarding the processing of personal data transferred from the EU, United Kingdom, and Switzerland to the U.S. (for these purposes, reference to the EU also includes the European Economic Area countries of Iceland, Liechtenstein and Norway). However, Open Sats commits to process Personal data transferred from the EU to the United States in accordance with the principles of Notice, Choice, Accountability for Onward Transfer, Security, Data Integrity and Purpose Limitation, Access, and Recourse, Enforcement and Liability, as described below.
|
||||
|
||||
**Notice and Choice**. This Privacy Policy provides notice of the personal data collected and transferred to the United States and the choices that you have with respect to such personal data. It also provides information about the protections applicable to transferred data below.
|
||||
|
||||
**Accountability for Onward Transfers**. We may be accountable for the personal data transfer to third-party service providers. If we are and our third-party service providers process personal data in a manner inconsistent with these principles, we are responsible and liable for the harm caused, unless we prove that we are not responsible for the event giving rise to the damage.
|
||||
|
||||
**Security**. We maintain security measures to protect personal data as described in the "Data Security" section of this Privacy Policy.
|
||||
|
||||
**Data Integrity and Purpose Limitation**. We take reasonable steps to ensure that personal data is reliable for its intended use, and that it is accurate, complete and current for as long as we retain it. We will retain the data as long as necessary for the following purposes: delivering the Services, engaging in customer service, complying with legal obligations, auditing, performing security and fraud prevention, responding to legal and regulatory inquiries, and preserving or defending our legal rights or those of other users or third parties.
|
||||
|
||||
**Access**. EU users have certain rights to access, correct, amend, or delete personal data where it is inaccurate, or has been processed in violation of these principles. Please see the "Your Rights" section above for more information on the rights of users in the EU (and, to the extent applicable, users in Switzerland).
|
||||
|
||||
**Recourse, Enforcement, Liability**. Open Sats commits to resolve complaints about our processing of your personal data. European Union, United Kingdom, and Swiss users with inquiries or complaints regarding our processing of Personal data should first contact Open Sats as follows:
|
||||
|
||||
Email: info@opensats.org
|
||||
|
||||
Attention: Information Security
|
||||
|
||||
We will respond to such inquiries or complaints within thirty (30) days.
|
||||
|
||||
**Children's Privacy**
|
||||
|
||||
Open Sats does not knowingly collect or solicit personal information from anyone under the age of sixteen (16), or knowingly allow such persons to register. If we become aware that we have collected personal information from a child under the relevant age without parental consent, we take steps to delete that information. Where we specifically indicate that we collect personal information from children under sixteen (16), we will obtain the parent or guardian's consent and provide adequate notice.
|
||||
|
||||
**Links to Third Party Sites and Services**
|
||||
|
||||
The Sites may contain links to third party sites or online services. Please refer to the privacy policies of the relevant third-party websites or services to find out more about how they process and handle personal information.
|
||||
|
||||
**California Privacy Rights**
|
||||
|
||||
Only to the extent that Open Sats meets the minimum thresholds as required under California law to be subject to the California Privacy Rights Act of 2020, residents of California will be able to request and obtain from us once a year, free of charge, a list of the third parties to whom we have disclosed their personal information (if any) for their direct marketing purposes in the prior calendar year, as well as the types of personal information disclosed to those parties. If you are a California resident and would like to request this information, please submit your request in an email to [info@opensats.org](mailto:info@opensats.org). We reserve the right to ask for verification of your California residence and deny this request if Open Sats believes it is not subject to this requirement.
|
||||
|
||||
**Contact Us**
|
||||
|
||||
If you have any questions about our practices or this Privacy Policy, please contact us at [info@opensats.org](mailto:info@opensats.org), or write to us at: Open Sats Initiative, Attn: Legal Department, 3605 Glenwood Ave., Suite 500, Raleigh, North Carolina, 27612, USA.
|
||||
|
||||
**Changes to the Privacy Policy**
|
||||
|
||||
This Policy is current as of the effective date set forth above. If we change our privacy policies and procedures, we will post those changes on this page and/or continue to provide access to a copy of the prior version. If we make any changes to this Privacy Policy that materially change how we treat your personal information, we will endeavor to provide you with reasonable notice of such changes, such as via prominent notice on our Sites or to your email address of record, and where required by law, we will obtain your consent or give you the opportunity to opt out of such changes.
|
||||
|
||||
3564707v1.AWB.31306.G51883
|
||||
49
docs/privacyguides/projects/eae_attack_and_churning.md
Normal file
49
docs/privacyguides/projects/eae_attack_and_churning.md
Normal file
@@ -0,0 +1,49 @@
|
||||
---
|
||||
title: 'PG Example Campaign'
|
||||
summary: "The EAE attack is one of Monero's privacy weak points. Churning may be a solution."
|
||||
nym: 'Dr. Nathan Borggren'
|
||||
website: 'https://github.com/nborggren'
|
||||
coverImage: '/img/project/EAE_diagram.png'
|
||||
git: 'https://github.com/nborggren'
|
||||
twitter: 'magicgrants'
|
||||
personalTwitter: 'magicgrants'
|
||||
personalWebsite: 'https://github.com/nborggren'
|
||||
type: 'Other Free and Open Source Project'
|
||||
date: '2023-06-08'
|
||||
staticXMRaddress: '87LZA8XLDvhVKLi974MaxUANcvkWdL6n986R7WNgKLXY16y31t69Z8228EWcg8THQq3tuAWfQ7Np35Tt3AhPrjzcNbm8Jr5'
|
||||
goal: 29260
|
||||
isFunded: false
|
||||
numdonationsxmr: 27
|
||||
totaldonationsinfiatxmr: 29260
|
||||
totaldonationsxmr: 220
|
||||
numdonationsbtc: 0
|
||||
totaldonationsinfiatbtc: 0
|
||||
totaldonationsbtc: 0
|
||||
fiatnumdonations: 0
|
||||
fiattotaldonationsinfiat: 0
|
||||
fiattotaldonations: 0
|
||||
---
|
||||
|
||||
### Funded Goal: 220 XMR (86 XMR contributed from MAGIC Monero Fund general fund)
|
||||
|
||||
### Start: June 2023
|
||||
|
||||
### End: September 2023
|
||||
|
||||
### Result: [Research paper](/pdf/Borggren-Sept-2023-Probing-the-Attacks-on-the-Privacy-of-the-Monero-Blockchain.pdf)
|
||||
|
||||
The EAE (Eve-Alice-Eve) attack is a threat to Monero user privacy. When a Monero user sends and/or receives funds repeatedly with an entity (Eve) that aims to trace funds, enough information in the local transaction graph and ring signatures may be available to make a probabalistic guess about the true destination or source of funds. There are different names for this attack and related attacks, which mostly differ in how many colluding entities are involved and how much information they may possess: EABE, poisoned outputs, Overseer, Flashlight, Tainted Dust, and Knacc attacks. One of the videos of the Breaking Monero series [discusses the EAE attack in detail](https://www.monerooutreach.org/breaking-monero/poisoned-outputs.html).
|
||||
|
||||
The EAE attack has been a concern of the Monero Research Lab for years, but rigorous measurement of the possible risk of this attack and possible defenses against it have not been successfully researched. "Churning", the practice of users sending funds to themselves, has been suggested as a possible defense, but neither its effectiveness nor details about best churning procedures have been determined by research to date.
|
||||
|
||||
Dr. Nathan Borggren has stepped up to investigate these important research questions about how to best protect Monero user privacy. Dr. Borggren is lead author of two papers about possible statistical threats to Monero user privacy: Borggren & Yao (2020) ["Correlations of Multi-input Monero Transactions"](https://moneroresearch.info/index.php?action=resource_RESOURCEVIEW_CORE&id=57) and Borggren et al. (2020) ["Simulated Blockchains for Machine Learning Traceability and Transaction Values in the Monero Network"](https://moneroresearch.info/index.php?action=resource_RESOURCEVIEW_CORE&id=58). His work analyzing transparent blockchains includes Borggren et al. (2017) "Deanonymizing Shapeshift: Linking Transactions Across Multiple Blockchains" and Borggren (2017) "Deep Learning of Entity Behavior in the Bitcoin Economy".
|
||||
|
||||
Dr. Borggren has proposed using Topological Data Analysis and Bayesian statistical methods to analyze the EAE attack and related attacks on Monero user privacy. The false positive and false negative rate of the EAE attack will be investigated through simulations and possibly analysis of Monero's mainnet blockchain. The full details of the plan are in [the research proposal](https://github.com/MAGICGrants/Monero-Fund/blob/main/projects/borggren_research-MAGIC-submission.pdf).
|
||||
|
||||
> "I think that the EAE attack is one of Monero's biggest _practical_ attack surfaces currently, and I see value in quantification plus real world data-informed best practices."
|
||||
|
||||
— [isthmus](https://github.com/Mitchellpkt), Monero Research Lab researcher and lead author of ["Fingerprinting a flood: Forensic statistical analysis of the mid-2021 Monero transaction volume anomaly"](https://mitchellpkt.medium.com/fingerprinting-a-flood-forensic-statistical-analysis-of-the-mid-2021-monero-transaction-volume-a19cbf41ce60)
|
||||
|
||||
> "Borggren has previously released fascinating papers quantifying Monero privacy pitfalls and I'm excited he is looking to continue."
|
||||
|
||||
— [ACK-J](https://github.com/ACK-J), author of ["Lord of the Rings: An Empirical Analysis of Monero's Ring Signature Resilience to Artifically Intelligent Attacks"](https://raw.githubusercontent.com/ACK-J/Monero-Dataset-Pipeline/main/Lord_of_the_Rings__An_Empirical_Analysis_of_Monero_s_Ring_Signature_Resilience_to_Artificially_Intelligent_Attacks.pdf)
|
||||
97
docs/privacyguides/terms.md
Normal file
97
docs/privacyguides/terms.md
Normal file
@@ -0,0 +1,97 @@
|
||||
# Open Sats Initiative terms of use
|
||||
|
||||
**Last updated: November 14, 2021**
|
||||
|
||||
Welcome to the Opensats.org website and/or mobile application (individually and collectively, the "Site"). Your access and use of the Site and of features, software, products and services provided by Open Sats Initiative ("Open Sats," "we," "us," or "our") through the Site, (individually and collectively, the "Service") is subject to the terms and conditions in this Terms of Use ("Terms of Use" or "Terms").
|
||||
|
||||
You must agree to the Terms in order to use the Site and/or the Service. If you use the Site and/or the Service, or click to accept or agree to the Terms if presented to you in a user interface for the Service, this is your acceptance of the Terms and your agreement to all of its terms and conditions. By accepting the Terms or using the Site and/or the Service, you represent and warrant that you are at least 18 years of age and have the legal capacity to enter a contract in the jurisdiction where you reside. If you do not accept the Terms, then you may not use the Site or the Service. If you are using the Site or the Service on behalf of another entity, you represent and warrant that you have full legal authority to bind such other entity to the Terms. If you do not have such authority, then you may not use the Site or the Service and you must discontinue all use of the Site and the Service immediately.
|
||||
|
||||
1. Our Services. The purpose of the Service is to promote the use of open source software to enhance blockchain technology and to promote the development of the Bitcoin infrastructure along with other free and open source software projects. As a non-profit organization ourselves, Open Sats Initiative does accept donations on the opensats.org website.
|
||||
2. Privacy Policy. By clicking on the Terms of Use and Privacy Policy box or using the Site or the Service, you represent that you have read and consent to our Privacy Policy located at [/privacy](/privacy) in addition to the Terms. Open Sats may revise the Privacy Policy at any time, and the new versions will be available on the Site. If at any point you do not agree to any portion of the Privacy Policy, you must immediately stop using the Site and/or Service.
|
||||
3. Terms of Use Updates. Open Sats may update the Terms at any time, and Open Sats will post the updated version of the Terms on the Site. You understand and agree that you will be deemed to have accepted the updated Terms if you use the Site or the Service after the updated Terms are posted on the Site. If at any point you do not agree to any portion of the Terms then in effect, you must immediately stop using the Site and the Service.
|
||||
4. Provision of the Services. You understand that all information, data, text, software, graphics or other materials ("Content"), whether publicly posted or privately transmitted, are the sole responsibility of the person from whom such Content originated. This means that you, and not Open Sats, is/are entirely responsible for all Content that you upload, post, email, transmit or otherwise make available via Services. Open Sats does not control the Content posted and, as such, does not guarantee the accuracy, integrity or quality of such Content. Under no circumstances will Open Sats be liable in any way for any Content, including, but not limited to, any errors or omissions in any Content, or any loss or damage of any kind incurred as a result of the use of any Content posted, emailed, transmitted or otherwise made available via the Open Sats Service.
|
||||
|
||||
You also agree that you will not collect or store personal data about other users in connection with any prohibited conduct and activities. You acknowledge that Open Sats may or may not pre-screen Content, but that Open Sats and its designees shall have the right (but not the obligation) in their sole discretion to pre-screen, refuse, move, or remove any Content that is available via the Services and which violates the Terms of Service. You agree that you must evaluate, and bear all risks associated with, the use of any Content, including any reliance on the accuracy, completeness, or usefulness of such Content. You acknowledge, consent and agree that Open Sats may access, preserve and disclose your account information and Content if required to do so by law or in a good faith belief that such access preservation or disclosure is reasonably necessary to:
|
||||
|
||||
- comply with legal process;
|
||||
- enforce the Terms of Use and the Privacy Policy;
|
||||
- respond to claims that any Content violates the rights of third parties;
|
||||
- respond to your requests for customer service; or
|
||||
- protect the rights, property or personal safety of Open Sats its users and the public.
|
||||
|
||||
1. Provision of the Service Not an Exchange. Open Sats is not a bitcoin exchange or wallet service and does not receive, hold or exchange digital currencies on behalf of any other person or entity. Open Sats does not withhold funds for tax purposes or otherwise.
|
||||
2. Tax Advice. Open Sats makes no representation as to whether all or any portion of your donations to us are tax deductible or eligible for tax credits. Open Sats will have no liability for any claim by any federal, state, local or any other tax authority with respect to the characterization on any applicable tax return of any donation by you. You should consult your tax advisor as to the amount of your donation that is tax deductible or eligible for tax recognition, if any.
|
||||
3. Access Restriction. Open Sats reserves the right to deny access or service to any person or entity at Open Sats' sole and absolute discretion. You acknowledge and agree that Open Sats may stop providing the Site and/or the Service or restrict your use of the Site and/or the Service at any time, without notifying you in advance, for any reason or no reason, including, without limitation, for any violation of the Terms and/or if Open Sats suspects that you have used any aspect of the Service to conduct any fraudulent or illegal activity. If Open Sats disables your access to your account, you may be prevented from accessing the Service, your account details and/or any materials contained in your account.
|
||||
4. Accounts and Security.
|
||||
5. Account. Open Sats may require registration for an account to access the Site and the Services. There will be a registration process for the creation of accounts to complete the registration process. You may be required to provide information about yourself or your company as part of the registration process or your continued use of the Service. You agree that any registration information that you submit to Open Sats will be correct, accurate, and up to date and that you will not impersonate any person or entity, or falsely state or otherwise misrepresent your affiliation with a person or entity.
|
||||
6. Account Security. Maintaining account security is very important. You are solely responsible for maintaining the confidentiality of your account password. You agree to notify Open Sats immediately if you become aware of any unauthorized use of your password or of your account.
|
||||
7. Account Sharing or Transfers. Accounts are registered to individuals or entities and may not be sold, traded, gifted or otherwise transferred at any time under any circumstances. An account may not be shared. Passwords may not be disclosed to anyone else.
|
||||
8. Cancellation by You. You have the right to cancel your account at any time. You may cancel your account by emailing us at info@opensats.org to submit a request to our support team.
|
||||
9. Termination by Open Sats. Open Sats may at any time terminate your account for any reason or no reason including, without limitation, if:
|
||||
|
||||
- Open Sats determines that you are (a) in breach of or otherwise acting inconsistently with the Terms or written agreements (b) engaging in fraudulent or illegal activities or other conduct that may result in liability to Open Sats;
|
||||
- Open Sats determines it is required by law to terminate your account; or
|
||||
- Open Sats decides to stop providing the Service or critical portions of the Service in the country where you reside, access the Site or use the Service or Open Sats determines that it is no longer in its charitable business interests to continue providing the Service or portions of the Service.
|
||||
|
||||
1. Content Licensing. Open Sats mission includes educating the public on free and open-source software through content such as articles, images, photographs, comments, software code, audio and video clips, and other materials (collectively, "Content"). Content is authored by Open Sats, contributors to Open Sats projects, and other sources.
|
||||
|
||||
Content authored by Open Sats is generally made available for public sharing and reuse through open licenses such as Creative Commons (for expressive material) or the Open Sats Public License. In most cases we ask Open Sats contributors to release Content under open licenses.
|
||||
|
||||
Some Content in our Site may be acquired from sources that prohibit further use of their Content without advance permission. Where possible, the Content will display a notice with the applicable license. You agree to abide by such notices. However it may occur that:
|
||||
|
||||
1. Some Content expressly indicates that the author does not intend for an open license to apply. You should contact the author or author's agent for permission to use such Content. Questions on Open Sats authored content can be sent to: info@opensats.org.
|
||||
2. Some Content contains trademarks, trade dress, logos and brand assets of Open Sats and other parties ("Trademarks"). Except for a few limited circumstances, Trademarks cannot be used without advance written permission of the owner of the Trademark.
|
||||
3. Software used by our Websites is licensed under the Open Sats Public License or similarly permissive open source licenses.
|
||||
4. Content Submissions **.** You may contribute Content when interacting with our Site and Services, including but not limited to commenting on an article, blogging, contributing code, or contributing graphics or written material (each a "Submission"). Unless your Submission is made under a separate agreement with Open Sats, in which case that agreement will govern, then
|
||||
|
||||
- For Submissions to Open Sats' open source Projects:
|
||||
|
||||
1. You agree to license your Submission under the terms of the corresponding license of the particular open source project to which you are contributing. For more information on the specific license, please see the applicable source.
|
||||
|
||||
- For all other Submissions, you agree to the following in connection with each:
|
||||
|
||||
1. You represent and warrant that your Submission will comply with these Terms and any additional terms that may govern your Submission.
|
||||
2. You hereby grant us a nonexclusive, royalty-free, worldwide, sublicensable (to those we work with) license to use your Submission in connection with the Content, Site, and Services and online and offline promotion of Open Sats' mission, products and services.
|
||||
3. You acknowledge that your Submissions may be accessible by other registered users of the applicable service or the public.
|
||||
4. If your Submission contains expressive material or software code, you agree to license it in a manner that is compatible with the particular website you are making a Submission to.
|
||||
5. You represent and warrant that you have the rights necessary to grant the rights granted herein, and further, that the uses contemplated under these Terms will not infringe the proprietary or intellectual property rights of any third party.
|
||||
6. You understand and agree that Open Sats reserves the right, at its discretion, to review, modify, or remove any Submission that it deems is objectionable or in violation of these Terms.
|
||||
|
||||
1. Effect of Account Termination or Cancellation. If you voluntarily terminate your account or allow your account to lapse, you will be able to reactivate that account at any time through the account interface on the Site. Accounts terminated by Open Sats for any type of abuse including, without limitation, a violation of the Terms, may not be reactivated for any reason. If you are blocked by us from accessing the Site or Service (including by blocking your IP address), you agree not to implement any measures to circumvent such blocking (e.g., by masking your IP address or using a proxy IP address).
|
||||
2. Restrictions and Conditions of Use.
|
||||
3. Use of the Site. Open Sats permits users to view and use the Site solely for personal or nonprofit use. You agree not to license, create derivative works from, transfer, sell or re-sell any information, content, materials, data or services obtained from the Site or through the Service unless specifically allowed by an Open Source license or express permission.
|
||||
4. Accessing the Service. You agree not to access, or attempt to access, the Service by any means other than through the user interface provided through the Site or any mobile application provided by Open Sats. You specifically agree not to access, or attempt to access, the Service through any automated means (including, without limitation, through the use of scripts, bots, spiders or web crawlers) and you agree to comply with the instructions contained in any robots.txt file present on the Site or the Service.
|
||||
5. No Violation of Laws. You agree that you will not, in connection with your use of the Site or the Service, violate any applicable law, ordinance, rule, regulation or treaty. Without limiting the foregoing, you agree that you will not make available through the Site and/or the Service any material or information that infringes any copyright, trademark, patent, trade secret, or other right of any party (including rights of privacy or publicity).
|
||||
6. Use Restrictions. You may not connect to or use the Site or the Service in any way that is not expressly permitted by the Terms.
|
||||
7. You may not: (a) remove any proprietary notices from the Service; (b) cause, permit or authorize the modification, creation of derivative works, translation, reverse engineering, decompiling, disassembling or hacking of the Site or the Service; (c) sell, assign, rent, lease, act as a service bureau, or grant rights in the Service, including, without limitation, through sublicense, to any other person or entity without the prior written consent of Open Sats; or (d) make any false, misleading or deceptive statement or representation regarding Open Sats and/or the Site or the Service.
|
||||
8. Without limiting the foregoing, you agree that you will not: (i) institute, assist, or become involved in any type of attack including, without limitation, denial of service attacks, upon the Site and/or the Service (or any servers, systems, or networks connected to the Site or the Service) or otherwise attempt to obstruct, disrupt, or interfere with the operation of the Site and/or the Service or any other person's or entity's use of the Site and/or the Service (or any servers, systems or networks connected to the Site or the Service); (ii) attempt to gain unauthorized access to the Site, the Service, accounts registered to other users, or any servers, systems or networks connected to the Site and/or the Service; (iii) use the Site or the Service for any commercial purpose or the benefit of any third party, or charge any person or entity, or receive any compensation for, the use of the Site or the Service, unless you are specifically authorized to do so in a separate written agreement with Open Sats; (iv) use the Site or the Service to (y) develop, generate, transmit or store information that is defamatory, harmful, abusive, obscene or hateful; or (z) perform any unsolicited commercial communication; or (v) engage in any activity that (A) constitutes harassment or a violation of privacy or threatens other people or groups of people; (B) is harmful to children in any manner; (C) constitutes phishing, pharming, or impersonates any other person or entity, or steals or assumes any person's identity (whether a real identity or online nickname or alias); (D) violates any applicable law, ordinance, rule, regulation or treaty or (E) in Open Sats' sole judgment, is objectionable or that restricts or inhibits any other person from using or enjoying our Site or Service, or which may expose us or our users to any harm or liability of any type.
|
||||
9. No Data Mining or Harmful Code. You agree that you will not (a) obtain or attempt to obtain any information from the Site or Services including, without limitation, any personal information of other account holders or other software data; (b) intercept, examine or otherwise observe any proprietary communications protocol used by the Site or the Service, whether through the use of a network analyzer, packet sniffer, or other device; or (c) use any type of bot, spider, virus, clock, timer, counter, worm, software lock, drop dead device, Trojan horse routing, trap door, time bomb or any other codes, instructions or third party software that is designed to provide a means of surreptitious or unauthorized access to, or distort, delete, damage or disassemble, the Site or the Service.
|
||||
10. Violation of the Terms. You acknowledge and agree that you are solely responsible, and Open Sats has no responsibility or liability to you or any other person or entity, for any breach by you of the Terms or for the consequences of any such breach.
|
||||
11. Links.
|
||||
12. Links from the Site. The Site may contain links to websites operated by other parties. Open Sats provides these links to other websites as a convenience and use of these websites is at your own risk. The linked websites are not under the control of Open Sats and Open Sats is not responsible for the content available on the other websites. Such links do not imply Open Sats' endorsement of information or material on any other website and Open Sats disclaims all liability with regard to your access to and use of such linked websites.
|
||||
13. Links to the Site. Unless otherwise set forth in a written agreement between you and Open Sats, you must adhere to Open Sats' linking policy as follows: (i) the appearance, position, and other aspects of the link may not be such as to damage or dilute the goodwill associated with Open Sats' and/or its licensors' names and trademarks; (ii) the appearance, position and other attributes of the link may not create the false appearance that your organization or entity is sponsored by, affiliated with, or associated with Open Sats; and (iii) when selected by a user, the link must display the Site on full-screen and not within a "frame" on the linking Site. Open Sats reserves the right to revoke its consent to the link at any time and in its sole discretion.
|
||||
14. Intellectual Property.
|
||||
15. Trademarks. The Open Sats marks are trademarks of Open Sats. Unless permitted in a separate written agreement with Open Sats, you do not have the right to use any of Open Sats' trademarks, service marks, or logos; and your unauthorized use of any of these may be a violation of federal and state trademark laws.
|
||||
16. Ownership. You acknowledge and agree that Open Sats, or its licensors, owns all right, title and interest in and to the Site and the Service, including all intellectual property, industrial property and proprietary rights recognized anywhere in the world at any time and that the Site and the Service are protected by U.S. and international copyright laws. Further, you acknowledge that the Service may contain information that Open Sats has designated as confidential and you agree not to disclose such information without Open Sats' prior written consent.
|
||||
|
||||
17. Location. The Site and the Service are operated by Open Sats in the United States. If you choose to access the Site and/or the Service from a location outside of the United States, you do so on your own initiative and you are responsible for compliance with applicable local laws.
|
||||
|
||||
18. Children. The Site and the Service are not directed toward children under 13 years of age nor does Open Sats knowingly collect information from children under 13 or allow them to create an account or access account features. If you are under 13, please do not submit any personal information about yourself to Open Sats.
|
||||
19. Term/Termination. These Terms will continue to apply until ended by either you or Open Sats. You can choose to end them at any time for any reason by discontinuing your use of our Site and Services and, if applicable, deleting your account. We may suspend or terminate your access to our Site and Services at any time for any reason, including, but not limited to, if we reasonably believe: (i) you have violated these Terms, our Privacy Policy, or other relevant policy; (ii) you create risk or possible legal exposure for us; or (iii) our provision of the Site and Services to you is no longer commercially viable. In all such cases, these Terms shall terminate, except that the following sections shall continue to apply: Indemnification, Disclaimer; Limitation of Liability, Modification, and Miscellaneous.
|
||||
20. Indemnification **.** You agree to defend, indemnify and hold harmless Open Sats, its contractors, contributors, licensors, and partners; and the respective directors, officers, employees and agents of the foregoing ("Indemnified Parties") from and against any and all third party claims and expenses, including attorneys' fees, arising out of or related to your use of our Site and Services (including, but not limited to, from your Submissions or from your violation of any these Terms).
|
||||
21. Disclaimer; Limitation of Liability. THE SITE AND SERVICES ARE PROVIDED "AS IS" WITH ALL FAULTS. TO THE EXTENT PERMITTED BY LAW, OPEN SATS AND THE INDEMNIFIED PARTIES HEREBY DISCLAIM ALL WARRANTIES, WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION WARRANTIES THAT THE CONTENT, SITE, AND SERVICES (AS APPLICABLE) ARE FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, AND NON-INFRINGING. YOU BEAR THE ENTIRE RISK AS TO USING THE SITE AND SERVICES FOR YOUR PURPOSES AND AS TO THE QUALITY AND PERFORMANCE OF THE SITE AND SERVICES, INCLUDING WITHOUT LIMITATION THE RISK THAT YOUR HARDWARE, SOFTWARE, OR CONTENT IS DELETED OR CORRUPTED, THAT SOMEONE ELSE GAINS UNAUTHORIZED ACCESS TO YOUR INFORMATION, OR THAT ANOTHER USER MISUSES OR MISAPPROPRIATES YOUR SUBMISSION. THIS LIMITATION WILL APPLY NOTWITHSTANDING THE FAILURE OF ESSENTIAL PURPOSE OF ANY REMEDY. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF IMPLIED WARRANTIES, SO THIS DISCLAIMER MAY NOT APPLY TO YOU. EXCEPT AS REQUIRED BY LAW, OPEN SATS AND THE INDEMNIFIED PARTIES WILL NOT BE LIABLE FOR ANY INDIRECT, SPECIAL, INCIDENTAL, CONSEQUENTIAL, OR EXEMPLARY DAMAGES ARISING OUT OF OR IN ANY WAY RELATING TO THESE TERMS OR THE USE OF OR INABILITY TO USE THE CONTENT, SITE, AND SERVICES, INCLUDING WITHOUT LIMITATION DIRECT AND INDIRECT DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, LOST PROFITS, LOSS OF DATA, AND COMPUTER FAILURE OR MALFUNCTION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES AND REGARDLESS OF THE THEORY (CONTRACT, TORT, OR OTHERWISE) UPON WHICH SUCH CLAIM IS BASED. THE COLLECTIVE LIABILITY OF OPEN SATS AND THE INDEMNIFIED PARTIES UNDER THIS AGREEMENT WILL NOT EXCEED \$500 (FIVE HUNDRED DOLLARS). SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL, CONSEQUENTIAL, OR SPECIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.
|
||||
22. Modifications to these Terms **.** We may update these Terms from time to time to address a new feature of the Site and Services or to clarify a provision. The updated Terms will be posted online. If the changes are substantive, we will announce the update through our usual channels for such announcements such as blog posts, banners, emails, or forums. Your continued use of our Site and Services after the effective date of such changes constitutes your acceptance of such changes. To make your review more convenient, we will post an effective date at the top of this page.
|
||||
23. Miscellaneous. These Terms constitute the entire agreement between you and Open Sats concerning our Site and Services and supersede any prior versions of these Terms. The Site and Services and these Terms are governed by the laws of the state of North Carolina, U.S.A., excluding its conflict of law provisions. All claims and disputes arising out of the Site and Services or these Terms shall be brought exclusively in the courts of Wake County, North Carolina, and you consent to personal jurisdiction in those courts. If any portion of these Terms is held to be invalid or unenforceable, the remaining portions will remain in full force and effect. In the event of a conflict between a translated version of these Terms and the English language version, the English language version shall control. In the event of a conflict between these Terms and relevant additional terms, the additional terms shall control.
|
||||
24. Contact Open Sats.
|
||||
|
||||
> Open Sats
|
||||
>
|
||||
> Attn: Open Sats – Legal Notices
|
||||
>
|
||||
> P.O. Box 20389
|
||||
>
|
||||
> Raleigh, NC 27612
|
||||
>
|
||||
> info@opensats.org
|
||||
>
|
||||
> 3566450v1.AWB.31306.G51883
|
||||
2
env.mjs
2
env.mjs
@@ -25,6 +25,7 @@ export const env = createEnv({
|
||||
STRIPE_GENERAL_SECRET_KEY: z.string().min(1),
|
||||
STRIPE_GENERAL_WEBHOOK_SECRET: z.string().min(1),
|
||||
|
||||
KEYCLOAK_URL: z.string().url(),
|
||||
KEYCLOAK_CLIENT_ID: z.string().min(1),
|
||||
KEYCLOAK_CLIENT_SECRET: z.string().min(1),
|
||||
KEYCLOAK_REALM_NAME: z.string().min(1),
|
||||
@@ -74,6 +75,7 @@ export const env = createEnv({
|
||||
STRIPE_GENERAL_SECRET_KEY: process.env.STRIPE_GENERAL_SECRET_KEY,
|
||||
STRIPE_GENERAL_WEBHOOK_SECRET: process.env.STRIPE_GENERAL_WEBHOOK_SECRET,
|
||||
|
||||
KEYCLOAK_URL: process.env.KEYCLOAK_URL,
|
||||
KEYCLOAK_CLIENT_ID: process.env.KEYCLOAK_CLIENT_ID,
|
||||
KEYCLOAK_CLIENT_SECRET: process.env.KEYCLOAK_CLIENT_SECRET,
|
||||
KEYCLOAK_REALM_NAME: process.env.KEYCLOAK_REALM_NAME,
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import xss from 'xss'
|
||||
import { FundSlug } from '@prisma/client'
|
||||
|
||||
import markdownToHtml from '../../utils/markdownToHtml'
|
||||
import { getSingleFile } from '../../utils/md'
|
||||
import { FundSlug, funds, fundSlugs } from '../../utils/funds'
|
||||
import { fundSlugs } from '../../utils/funds'
|
||||
|
||||
export default function About({ content }: { content: string }) {
|
||||
return (
|
||||
<article
|
||||
className="prose max-w-3xl mx-auto pb-8 pt-8 dark:prose-dark xl:col-span-2"
|
||||
className="prose max-w-3xl mx-auto pb-8 pt-8 xl:col-span-2"
|
||||
dangerouslySetInnerHTML={{ __html: xss(content || '') }}
|
||||
/>
|
||||
)
|
||||
|
||||
@@ -41,7 +41,6 @@ function MyDonations() {
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead>Project</TableHead>
|
||||
<TableHead>Fund</TableHead>
|
||||
<TableHead>Method</TableHead>
|
||||
<TableHead>Amount</TableHead>
|
||||
<TableHead>Date</TableHead>
|
||||
@@ -51,7 +50,6 @@ function MyDonations() {
|
||||
{donationListQuery.data?.map((donation) => (
|
||||
<TableRow key={donation.createdAt.toISOString()}>
|
||||
<TableCell>{donation.projectName}</TableCell>
|
||||
<TableCell>{donation.fundSlug}</TableCell>
|
||||
<TableCell>{donation.btcPayInvoiceId ? 'Crypto' : 'Fiat'}</TableCell>
|
||||
<TableCell>${donation.fiatAmount}</TableCell>
|
||||
<TableCell>{dayjs(donation.createdAt).format('lll')}</TableCell>
|
||||
|
||||
@@ -47,7 +47,6 @@ function MyMemberships() {
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead>Project</TableHead>
|
||||
<TableHead>Fund</TableHead>
|
||||
<TableHead>Method</TableHead>
|
||||
<TableHead>Recurring</TableHead>
|
||||
<TableHead>Date</TableHead>
|
||||
@@ -58,7 +57,6 @@ function MyMemberships() {
|
||||
{membershipListQuery.data?.memberships.map((membership) => (
|
||||
<TableRow key={membership.createdAt.toISOString()}>
|
||||
<TableCell>{membership.projectName}</TableCell>
|
||||
<TableCell>{membership.fundSlug}</TableCell>
|
||||
<TableCell>{membership.btcPayInvoiceId ? 'Crypto' : 'Fiat'}</TableCell>
|
||||
<TableCell>{membership.stripeSubscriptionId ? 'Yes' : 'No'}</TableCell>
|
||||
<TableCell>{dayjs(membership.createdAt).format('lll')}</TableCell>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import markdownToHtml from '../../utils/markdownToHtml'
|
||||
import { getSingleFile } from '../../utils/md'
|
||||
import BigDumbMarkdown from '../../components/BigDumbMarkdown'
|
||||
import { FundSlug, fundSlugs } from '../../utils/funds'
|
||||
import { FundSlug, fundSlugs } from '../../server/utils/funds'
|
||||
|
||||
export default function About({ content }: { content: string }) {
|
||||
return <BigDumbMarkdown content={content} />
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import xss from 'xss'
|
||||
import { FundSlug } from '@prisma/client'
|
||||
|
||||
import markdownToHtml from '../../utils/markdownToHtml'
|
||||
import { getSingleFile } from '../../utils/md'
|
||||
import BigDumbMarkdown from '../../components/BigDumbMarkdown'
|
||||
import { FundSlug, fundSlugs } from '../../utils/funds'
|
||||
import { fundSlugs } from '../../utils/funds'
|
||||
|
||||
export default function Faq({ content }: { content: string }) {
|
||||
return (
|
||||
<article
|
||||
className="prose max-w-3xl mx-auto pb-8 pt-8 dark:prose-dark xl:col-span-2"
|
||||
className="prose max-w-3xl mx-auto pb-8 pt-8 xl:col-span-2"
|
||||
dangerouslySetInnerHTML={{ __html: xss(content || '') }}
|
||||
/>
|
||||
)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import markdownToHtml from '../../utils/markdownToHtml'
|
||||
import { getSingleFile } from '../../utils/md'
|
||||
import BigDumbMarkdown from '../../components/BigDumbMarkdown'
|
||||
import { FundSlug, fundSlugs } from '../../utils/funds'
|
||||
import { FundSlug, fundSlugs } from '../../server/utils/funds'
|
||||
|
||||
export default function Terms({ content }: { content: string }) {
|
||||
return <BigDumbMarkdown content={content} />
|
||||
|
||||
297
pages/[fund]/projects/[slug].tsx
Normal file
297
pages/[fund]/projects/[slug].tsx
Normal file
@@ -0,0 +1,297 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useSession } from 'next-auth/react'
|
||||
import { useRouter } from 'next/router'
|
||||
import { GetServerSidePropsContext, NextPage } from 'next/types'
|
||||
import Head from 'next/head'
|
||||
import ErrorPage from 'next/error'
|
||||
import Image from 'next/image'
|
||||
import xss from 'xss'
|
||||
|
||||
import { ProjectDonationStats, ProjectItem } from '../../../utils/types'
|
||||
import { getProjectBySlug } from '../../../utils/md'
|
||||
import markdownToHtml from '../../../utils/markdownToHtml'
|
||||
import PageHeading from '../../../components/PageHeading'
|
||||
import Progress from '../../../components/Progress'
|
||||
import { prisma } from '../../../server/services'
|
||||
import { Button } from '../../../components/ui/button'
|
||||
import { Dialog, DialogContent } from '../../../components/ui/dialog'
|
||||
import DonationFormModal from '../../../components/DonationFormModal'
|
||||
import MembershipFormModal from '../../../components/MembershipFormModal'
|
||||
import LoginFormModal from '../../../components/LoginFormModal'
|
||||
import RegisterFormModal from '../../../components/RegisterFormModal'
|
||||
import PasswordResetFormModal from '../../../components/PasswordResetFormModal'
|
||||
import CustomLink from '../../../components/CustomLink'
|
||||
import { trpc } from '../../../utils/trpc'
|
||||
import { getFundSlugFromUrlPath } from '../../../utils/funds'
|
||||
import { useFundSlug } from '../../../utils/use-fund-slug'
|
||||
|
||||
type SingleProjectPageProps = {
|
||||
project: ProjectItem
|
||||
projects: ProjectItem[]
|
||||
donationStats: ProjectDonationStats
|
||||
}
|
||||
|
||||
const Project: NextPage<SingleProjectPageProps> = ({ project, donationStats }) => {
|
||||
const router = useRouter()
|
||||
const [donateModalOpen, setDonateModalOpen] = useState(false)
|
||||
const [memberModalOpen, setMemberModalOpen] = useState(false)
|
||||
const [registerIsOpen, setRegisterIsOpen] = useState(false)
|
||||
const [loginIsOpen, setLoginIsOpen] = useState(false)
|
||||
const [passwordResetIsOpen, setPasswordResetIsOpen] = useState(false)
|
||||
const session = useSession()
|
||||
const fundSlug = useFundSlug()
|
||||
|
||||
const userHasMembershipQuery = trpc.donation.userHasMembership.useQuery(
|
||||
{ projectSlug: project.slug },
|
||||
{ enabled: false }
|
||||
)
|
||||
|
||||
const {
|
||||
slug,
|
||||
title,
|
||||
summary,
|
||||
coverImage,
|
||||
git,
|
||||
twitter,
|
||||
content,
|
||||
nym,
|
||||
website,
|
||||
personalTwitter,
|
||||
personalWebsite,
|
||||
goal,
|
||||
isFunded,
|
||||
} = project
|
||||
|
||||
function formatBtc(bitcoin: number) {
|
||||
if (bitcoin > 0.1) {
|
||||
return `${bitcoin.toFixed(3) || 0.0} BTC`
|
||||
} else {
|
||||
return `${Math.floor(bitcoin * 100000000).toLocaleString()} sats`
|
||||
}
|
||||
}
|
||||
|
||||
function formatUsd(dollars: number): string {
|
||||
if (dollars == 0) {
|
||||
return '$0'
|
||||
} else if (dollars / 1000 > 1) {
|
||||
return `$${Math.round(dollars / 1000)}k+`
|
||||
} else {
|
||||
return `$${dollars.toFixed(0)}`
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (session.status === 'authenticated') {
|
||||
console.log('refetching')
|
||||
userHasMembershipQuery.refetch()
|
||||
}
|
||||
}, [session.status])
|
||||
|
||||
if (!router.isFallback && !slug) {
|
||||
return <ErrorPage statusCode={404} />
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>Monero Fund - {project.title}</title>
|
||||
</Head>
|
||||
|
||||
<div className="divide-y divide-gray-200">
|
||||
<PageHeading project={project}>
|
||||
<div className="flex flex-col items-center space-x-2 pt-8 xl:block">
|
||||
<Image
|
||||
src={coverImage}
|
||||
alt="avatar"
|
||||
width={300}
|
||||
height={300}
|
||||
className="h-72 w-72 mx-auto object-contain xl:hidden"
|
||||
/>
|
||||
|
||||
<div className="space-y-4">
|
||||
{!project.isFunded && (
|
||||
<div className="flex flex-col space-y-2">
|
||||
<Button onClick={() => setDonateModalOpen(true)}>Donate</Button>
|
||||
|
||||
{!userHasMembershipQuery.data && (
|
||||
<Button
|
||||
onClick={() =>
|
||||
session.status === 'authenticated'
|
||||
? setMemberModalOpen(true)
|
||||
: setRegisterIsOpen(true)
|
||||
}
|
||||
variant="outline"
|
||||
>
|
||||
Get Annual Membership
|
||||
</Button>
|
||||
)}
|
||||
|
||||
{!!userHasMembershipQuery.data && (
|
||||
<Button variant="outline">
|
||||
<CustomLink href={`${fundSlug}/account/my-memberships`}>
|
||||
My Memberships
|
||||
</CustomLink>
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<h1 className="mb-4 font-bold">Raised</h1>
|
||||
|
||||
<Progress
|
||||
percent={Math.floor(
|
||||
((donationStats.xmr.fiatAmount +
|
||||
donationStats.btc.fiatAmount +
|
||||
donationStats.usd.fiatAmount) /
|
||||
goal) *
|
||||
100
|
||||
)}
|
||||
/>
|
||||
|
||||
<ul className="font-semibold space-y-1">
|
||||
<li className="flex items-center space-x-1">
|
||||
<span className="text-green-500 text-xl">{`${formatUsd(donationStats.xmr.fiatAmount + donationStats.btc.fiatAmount + donationStats.usd.fiatAmount)}`}</span>{' '}
|
||||
<span className="font-normal text-sm text-gray">
|
||||
in {donationStats.xmr.count + donationStats.btc.count + donationStats.usd.count}{' '}
|
||||
donations total
|
||||
</span>
|
||||
</li>
|
||||
<li>
|
||||
{donationStats.xmr.amount} XMR{' '}
|
||||
<span className="font-normal text-sm text-gray">
|
||||
in {donationStats.xmr.count} donations
|
||||
</span>
|
||||
</li>
|
||||
<li>
|
||||
{formatBtc(donationStats.btc.amount)}{' '}
|
||||
<span className="font-normal text-sm text-gray">
|
||||
in {donationStats.btc.count} donations
|
||||
</span>
|
||||
</li>
|
||||
<li>
|
||||
{`${formatUsd(donationStats.usd.amount)}`} Fiat{' '}
|
||||
<span className="font-normal text-sm text-gray">
|
||||
in {donationStats.usd.count} donations
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<article
|
||||
className="prose max-w-none pb-8 pt-8 xl:col-span-2"
|
||||
dangerouslySetInnerHTML={{ __html: xss(content || '') }}
|
||||
/>
|
||||
</PageHeading>
|
||||
</div>
|
||||
|
||||
<Dialog open={donateModalOpen} onOpenChange={setDonateModalOpen}>
|
||||
<DialogContent>
|
||||
<DonationFormModal project={project} />
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
<Dialog open={memberModalOpen} onOpenChange={setMemberModalOpen}>
|
||||
<DialogContent>
|
||||
<MembershipFormModal project={project} />
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
{session.status !== 'authenticated' && (
|
||||
<>
|
||||
<Dialog open={loginIsOpen} onOpenChange={setLoginIsOpen}>
|
||||
<DialogContent>
|
||||
<LoginFormModal
|
||||
close={() => setLoginIsOpen(false)}
|
||||
openRegisterModal={() => setRegisterIsOpen(true)}
|
||||
openPasswordResetModal={() => setPasswordResetIsOpen(true)}
|
||||
/>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
<Dialog open={registerIsOpen} onOpenChange={setRegisterIsOpen}>
|
||||
<DialogContent>
|
||||
<RegisterFormModal
|
||||
openLoginModal={() => setLoginIsOpen(true)}
|
||||
close={() => setRegisterIsOpen(false)}
|
||||
/>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
<Dialog open={passwordResetIsOpen} onOpenChange={setPasswordResetIsOpen}>
|
||||
<DialogContent>
|
||||
<PasswordResetFormModal close={() => setPasswordResetIsOpen(false)} />
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default Project
|
||||
|
||||
export async function getServerSideProps({ params, resolvedUrl }: GetServerSidePropsContext) {
|
||||
const fundSlug = getFundSlugFromUrlPath(resolvedUrl)
|
||||
|
||||
if (!params?.slug) return {}
|
||||
if (!fundSlug) return {}
|
||||
|
||||
const project = getProjectBySlug(params.slug as string, fundSlug)
|
||||
const content = await markdownToHtml(project.content || '')
|
||||
|
||||
const donationStats = {
|
||||
xmr: {
|
||||
count: project.isFunded ? project.numdonationsxmr : 0,
|
||||
amount: project.isFunded ? project.totaldonationsxmr : 0,
|
||||
fiatAmount: project.isFunded ? project.totaldonationsinfiatxmr : 0,
|
||||
},
|
||||
btc: {
|
||||
count: project.isFunded ? project.numdonationsbtc : 0,
|
||||
amount: project.isFunded ? project.totaldonationsbtc : 0,
|
||||
fiatAmount: project.isFunded ? project.totaldonationsinfiatbtc : 0,
|
||||
},
|
||||
usd: {
|
||||
count: project.isFunded ? project.fiatnumdonations : 0,
|
||||
amount: project.isFunded ? project.fiattotaldonations : 0,
|
||||
fiatAmount: project.isFunded ? project.fiattotaldonationsinfiat : 0,
|
||||
},
|
||||
}
|
||||
|
||||
if (!project.isFunded) {
|
||||
const donations = await prisma.donation.findMany({
|
||||
where: { projectSlug: params.slug as string, fundSlug },
|
||||
})
|
||||
|
||||
donations.forEach((donation) => {
|
||||
if (donation.cryptoCode === 'XMR') {
|
||||
donationStats.xmr.count += 1
|
||||
donationStats.xmr.amount += donation.cryptoAmount
|
||||
donationStats.xmr.fiatAmount += donation.fiatAmount
|
||||
}
|
||||
|
||||
if (donation.cryptoCode === 'BTC') {
|
||||
donationStats.btc.count += 1
|
||||
donationStats.btc.amount += donation.cryptoAmount
|
||||
donationStats.btc.fiatAmount += donation.fiatAmount
|
||||
}
|
||||
|
||||
if (donation.cryptoCode === null) {
|
||||
donationStats.usd.count += 1
|
||||
donationStats.usd.amount += donation.fiatAmount
|
||||
donationStats.usd.fiatAmount += donation.fiatAmount
|
||||
console.log(donation)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
props: {
|
||||
project: {
|
||||
...project,
|
||||
content,
|
||||
},
|
||||
donationStats,
|
||||
},
|
||||
}
|
||||
}
|
||||
64
pages/[fund]/projects/index.tsx
Normal file
64
pages/[fund]/projects/index.tsx
Normal file
@@ -0,0 +1,64 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import type { NextPage } from 'next'
|
||||
import Head from 'next/head'
|
||||
import ProjectCard from '../../../components/ProjectCard'
|
||||
import { ProjectItem } from '../../../utils/types'
|
||||
import { getProjects } from '../../../utils/md'
|
||||
import { useFundSlug } from '../../../utils/use-fund-slug'
|
||||
|
||||
const AllProjects: NextPage<{ projects: ProjectItem[] }> = ({ projects }) => {
|
||||
const [modalOpen, setModalOpen] = useState(false)
|
||||
const [selectedProject, setSelectedProject] = useState<ProjectItem>()
|
||||
const [sortedProjects, setSortedProjects] = useState<ProjectItem[]>()
|
||||
const fundSlug = useFundSlug()
|
||||
|
||||
useEffect(() => {
|
||||
setSortedProjects(projects.sort(() => 0.5 - Math.random()))
|
||||
}, [projects])
|
||||
|
||||
function closeModal() {
|
||||
setModalOpen(false)
|
||||
}
|
||||
|
||||
function openPaymentModal(project: ProjectItem) {
|
||||
setSelectedProject(project)
|
||||
setModalOpen(true)
|
||||
}
|
||||
|
||||
if (!fundSlug) return <></>
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>MAGIC Monero Fund | Projects</title>
|
||||
</Head>
|
||||
<section className="p-4 md:p-8 flex flex-col items-center">
|
||||
<div className="flex justify-between items-center pb-8 w-full">
|
||||
<h1 className="py-4 text-3xl font-extrabold leading-9 tracking-tight text-gray-900 sm:text-4xl sm:leading-10 md:text-6xl md:leading-14">
|
||||
Projects
|
||||
</h1>
|
||||
</div>
|
||||
<ul className="grid md:grid-cols-3 gap-4 max-w-5xl">
|
||||
{sortedProjects &&
|
||||
sortedProjects.map((p, i) => (
|
||||
<li key={i} className="">
|
||||
<ProjectCard project={p} />
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</section>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default AllProjects
|
||||
|
||||
export async function getStaticProps({ params }: { params: any }) {
|
||||
const projects = getProjects('monero')
|
||||
|
||||
return {
|
||||
props: {
|
||||
projects,
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -66,7 +66,7 @@ function ResetPassword() {
|
||||
variant: 'destructive',
|
||||
})
|
||||
|
||||
router.push('/')
|
||||
router.push(`/${fundSlug}/`)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import markdownToHtml from '../../utils/markdownToHtml'
|
||||
import { getSingleFile } from '../../utils/md'
|
||||
import BigDumbMarkdown from '../../components/BigDumbMarkdown'
|
||||
import { FundSlug, fundSlugs } from '../../utils/funds'
|
||||
import { FundSlug, fundSlugs } from '../../server/utils/funds'
|
||||
|
||||
export default function Terms({ content }: { content: string }) {
|
||||
return <BigDumbMarkdown content={content} />
|
||||
|
||||
@@ -6,13 +6,16 @@ import Head from 'next/head'
|
||||
import Layout from '../components/Layout'
|
||||
import { Toaster } from '../components/ui/toaster'
|
||||
import { trpc } from '../utils/trpc'
|
||||
import { useFundSlug } from '../utils/use-fund-slug'
|
||||
|
||||
import '../styles/globals.css'
|
||||
|
||||
function MyApp({ Component, pageProps }: AppProps) {
|
||||
function MyApp({ Component, pageProps, router }: AppProps) {
|
||||
const fundSlug = useFundSlug()
|
||||
|
||||
return (
|
||||
<SessionProvider session={pageProps.session}>
|
||||
<ThemeProvider attribute="class" defaultTheme="system">
|
||||
<ThemeProvider attribute="class" forcedTheme={fundSlug as string} enableSystem={false}>
|
||||
<Head>
|
||||
<meta content="width=device-width, initial-scale=1" name="viewport" />
|
||||
</Head>
|
||||
|
||||
@@ -21,7 +21,7 @@ export const authOptions: AuthOptions = {
|
||||
authorize: async (credentials) => {
|
||||
try {
|
||||
const { data } = await axios.post(
|
||||
`http://localhost:8080/realms/monerofund/protocol/openid-connect/token`,
|
||||
`${env.KEYCLOAK_URL}/realms/${env.KEYCLOAK_REALM_NAME}/protocol/openid-connect/token`,
|
||||
new URLSearchParams({
|
||||
grant_type: 'password',
|
||||
client_id: env.KEYCLOAK_CLIENT_ID,
|
||||
@@ -32,15 +32,14 @@ export const authOptions: AuthOptions = {
|
||||
{ headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }
|
||||
)
|
||||
|
||||
const keycloakJwtPayload: KeycloakJwtPayload = jwtDecode(
|
||||
data.access_token
|
||||
)
|
||||
const keycloakJwtPayload: KeycloakJwtPayload = jwtDecode(data.access_token)
|
||||
|
||||
return {
|
||||
id: keycloakJwtPayload.sub,
|
||||
email: keycloakJwtPayload.email,
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
const errorMessage = (error as any).response.data.error
|
||||
if (errorMessage === 'invalid_grant') {
|
||||
throw new Error('INVALID_CREDENTIALS')
|
||||
|
||||
@@ -8,4 +8,4 @@ export const config = {
|
||||
},
|
||||
}
|
||||
|
||||
export default getBtcpayWebhookHandler(env.BTCPAY_PRIVACY_GUIDES_WEBHOOK_SECRET)
|
||||
export default getBtcpayWebhookHandler(env.BTCPAY_MONERO_WEBHOOK_SECRET)
|
||||
|
||||
295
pages/firo/___projects/[slug].tsx
Normal file
295
pages/firo/___projects/[slug].tsx
Normal file
@@ -0,0 +1,295 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useSession } from 'next-auth/react'
|
||||
import { useRouter } from 'next/router'
|
||||
import { GetServerSidePropsContext, NextPage } from 'next/types'
|
||||
import Head from 'next/head'
|
||||
import ErrorPage from 'next/error'
|
||||
import Image from 'next/image'
|
||||
import xss from 'xss'
|
||||
|
||||
import { ProjectDonationStats, ProjectItem } from '../../../utils/types'
|
||||
import { getProjectBySlug } from '../../../utils/md'
|
||||
import markdownToHtml from '../../../utils/markdownToHtml'
|
||||
import PageHeading from '../../../components/PageHeading'
|
||||
import Progress from '../../../components/Progress'
|
||||
import { prisma } from '../../../server/services'
|
||||
import { Button } from '../../../components/ui/button'
|
||||
import { Dialog, DialogContent } from '../../../components/ui/dialog'
|
||||
import DonationFormModal from '../../../components/DonationFormModal'
|
||||
import MembershipFormModal from '../../../components/MembershipFormModal'
|
||||
import LoginFormModal from '../../../components/LoginFormModal'
|
||||
import RegisterFormModal from '../../../components/RegisterFormModal'
|
||||
import PasswordResetFormModal from '../../../components/PasswordResetFormModal'
|
||||
import CustomLink from '../../../components/CustomLink'
|
||||
import { trpc } from '../../../utils/trpc'
|
||||
import { getFundSlugFromUrlPath } from '../../../utils/funds'
|
||||
import { useFundSlug } from '../../../utils/use-fund-slug'
|
||||
|
||||
type SingleProjectPageProps = {
|
||||
project: ProjectItem
|
||||
projects: ProjectItem[]
|
||||
donationStats: ProjectDonationStats
|
||||
}
|
||||
|
||||
const Project: NextPage<SingleProjectPageProps> = ({ project, donationStats }) => {
|
||||
const router = useRouter()
|
||||
const [donateModalOpen, setDonateModalOpen] = useState(false)
|
||||
const [memberModalOpen, setMemberModalOpen] = useState(false)
|
||||
const [registerIsOpen, setRegisterIsOpen] = useState(false)
|
||||
const [loginIsOpen, setLoginIsOpen] = useState(false)
|
||||
const [passwordResetIsOpen, setPasswordResetIsOpen] = useState(false)
|
||||
const session = useSession()
|
||||
const fundSlug = useFundSlug()
|
||||
|
||||
const userHasMembershipQuery = trpc.donation.userHasMembership.useQuery(
|
||||
{ projectSlug: project.slug },
|
||||
{ enabled: false }
|
||||
)
|
||||
|
||||
const {
|
||||
slug,
|
||||
title,
|
||||
summary,
|
||||
coverImage,
|
||||
git,
|
||||
twitter,
|
||||
content,
|
||||
nym,
|
||||
website,
|
||||
personalTwitter,
|
||||
personalWebsite,
|
||||
goal,
|
||||
isFunded,
|
||||
} = project
|
||||
|
||||
function formatBtc(bitcoin: number) {
|
||||
if (bitcoin > 0.1) {
|
||||
return `${bitcoin.toFixed(3) || 0.0} BTC`
|
||||
} else {
|
||||
return `${Math.floor(bitcoin * 100000000).toLocaleString()} sats`
|
||||
}
|
||||
}
|
||||
|
||||
function formatUsd(dollars: number): string {
|
||||
if (dollars == 0) {
|
||||
return '$0'
|
||||
} else if (dollars / 1000 > 1) {
|
||||
return `$${Math.round(dollars / 1000)}k+`
|
||||
} else {
|
||||
return `$${dollars.toFixed(0)}`
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (session.status === 'authenticated') {
|
||||
console.log('refetching')
|
||||
userHasMembershipQuery.refetch()
|
||||
}
|
||||
}, [session.status])
|
||||
|
||||
if (!router.isFallback && !slug) {
|
||||
return <ErrorPage statusCode={404} />
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>Monero Fund - {project.title}</title>
|
||||
</Head>
|
||||
|
||||
<div className="divide-y divide-gray-200">
|
||||
<PageHeading project={project}>
|
||||
<div className="flex flex-col items-center space-x-2 pt-8 xl:block">
|
||||
<Image
|
||||
src={coverImage}
|
||||
alt="avatar"
|
||||
width={300}
|
||||
height={300}
|
||||
className="h-72 w-72 mx-auto object-contain xl:hidden"
|
||||
/>
|
||||
|
||||
<div className="space-y-4">
|
||||
{!project.isFunded && (
|
||||
<div className="flex flex-col space-y-2">
|
||||
<Button onClick={() => setDonateModalOpen(true)}>Donate</Button>
|
||||
|
||||
{!userHasMembershipQuery.data && (
|
||||
<Button
|
||||
onClick={() =>
|
||||
session.status === 'authenticated'
|
||||
? setMemberModalOpen(true)
|
||||
: setRegisterIsOpen(true)
|
||||
}
|
||||
variant="outline"
|
||||
>
|
||||
Get Annual Membership
|
||||
</Button>
|
||||
)}
|
||||
|
||||
{!!userHasMembershipQuery.data && (
|
||||
<CustomLink href={`${fundSlug}/account/my-memberships`}>
|
||||
<Button variant="outline">My Memberships</Button>{' '}
|
||||
</CustomLink>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<h1 className="mb-4 font-bold">Raised</h1>
|
||||
|
||||
<Progress
|
||||
percent={Math.floor(
|
||||
((donationStats.xmr.fiatAmount +
|
||||
donationStats.btc.fiatAmount +
|
||||
donationStats.usd.fiatAmount) /
|
||||
goal) *
|
||||
100
|
||||
)}
|
||||
/>
|
||||
|
||||
<ul className="font-semibold space-y-1">
|
||||
<li className="flex items-center space-x-1">
|
||||
<span className="text-green-500 text-xl">{`${formatUsd(donationStats.xmr.fiatAmount + donationStats.btc.fiatAmount + donationStats.usd.fiatAmount)}`}</span>{' '}
|
||||
<span className="font-normal text-sm text-gray">
|
||||
in {donationStats.xmr.count + donationStats.btc.count + donationStats.usd.count}{' '}
|
||||
donations total
|
||||
</span>
|
||||
</li>
|
||||
<li>
|
||||
{donationStats.xmr.amount} XMR{' '}
|
||||
<span className="font-normal text-sm text-gray">
|
||||
in {donationStats.xmr.count} donations
|
||||
</span>
|
||||
</li>
|
||||
<li>
|
||||
{formatBtc(donationStats.btc.amount)}{' '}
|
||||
<span className="font-normal text-sm text-gray">
|
||||
in {donationStats.btc.count} donations
|
||||
</span>
|
||||
</li>
|
||||
<li>
|
||||
{`${formatUsd(donationStats.usd.amount)}`} Fiat{' '}
|
||||
<span className="font-normal text-sm text-gray">
|
||||
in {donationStats.usd.count} donations
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<article
|
||||
className="prose max-w-none pb-8 pt-8 xl:col-span-2"
|
||||
dangerouslySetInnerHTML={{ __html: xss(content || '') }}
|
||||
/>
|
||||
</PageHeading>
|
||||
</div>
|
||||
|
||||
<Dialog open={donateModalOpen} onOpenChange={setDonateModalOpen}>
|
||||
<DialogContent>
|
||||
<DonationFormModal project={project} />
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
<Dialog open={memberModalOpen} onOpenChange={setMemberModalOpen}>
|
||||
<DialogContent>
|
||||
<MembershipFormModal project={project} />
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
{session.status !== 'authenticated' && (
|
||||
<>
|
||||
<Dialog open={loginIsOpen} onOpenChange={setLoginIsOpen}>
|
||||
<DialogContent>
|
||||
<LoginFormModal
|
||||
close={() => setLoginIsOpen(false)}
|
||||
openRegisterModal={() => setRegisterIsOpen(true)}
|
||||
openPasswordResetModal={() => setPasswordResetIsOpen(true)}
|
||||
/>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
<Dialog open={registerIsOpen} onOpenChange={setRegisterIsOpen}>
|
||||
<DialogContent>
|
||||
<RegisterFormModal
|
||||
openLoginModal={() => setLoginIsOpen(true)}
|
||||
close={() => setRegisterIsOpen(false)}
|
||||
/>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
<Dialog open={passwordResetIsOpen} onOpenChange={setPasswordResetIsOpen}>
|
||||
<DialogContent>
|
||||
<PasswordResetFormModal close={() => setPasswordResetIsOpen(false)} />
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default Project
|
||||
|
||||
export async function getServerSideProps({ params, resolvedUrl }: GetServerSidePropsContext) {
|
||||
const fundSlug = getFundSlugFromUrlPath(resolvedUrl)
|
||||
|
||||
if (!params?.slug) return {}
|
||||
if (!fundSlug) return {}
|
||||
|
||||
const project = getProjectBySlug(params.slug as string, fundSlug)
|
||||
const content = await markdownToHtml(project.content || '')
|
||||
|
||||
const donationStats = {
|
||||
xmr: {
|
||||
count: project.isFunded ? project.numdonationsxmr : 0,
|
||||
amount: project.isFunded ? project.totaldonationsxmr : 0,
|
||||
fiatAmount: project.isFunded ? project.totaldonationsinfiatxmr : 0,
|
||||
},
|
||||
btc: {
|
||||
count: project.isFunded ? project.numdonationsbtc : 0,
|
||||
amount: project.isFunded ? project.totaldonationsbtc : 0,
|
||||
fiatAmount: project.isFunded ? project.totaldonationsinfiatbtc : 0,
|
||||
},
|
||||
usd: {
|
||||
count: project.isFunded ? project.fiatnumdonations : 0,
|
||||
amount: project.isFunded ? project.fiattotaldonations : 0,
|
||||
fiatAmount: project.isFunded ? project.fiattotaldonationsinfiat : 0,
|
||||
},
|
||||
}
|
||||
|
||||
if (!project.isFunded) {
|
||||
const donations = await prisma.donation.findMany({
|
||||
where: { projectSlug: params.slug as string, fundSlug },
|
||||
})
|
||||
|
||||
donations.forEach((donation) => {
|
||||
if (donation.cryptoCode === 'XMR') {
|
||||
donationStats.xmr.count += 1
|
||||
donationStats.xmr.amount += donation.cryptoAmount
|
||||
donationStats.xmr.fiatAmount += donation.fiatAmount
|
||||
}
|
||||
|
||||
if (donation.cryptoCode === 'BTC') {
|
||||
donationStats.btc.count += 1
|
||||
donationStats.btc.amount += donation.cryptoAmount
|
||||
donationStats.btc.fiatAmount += donation.fiatAmount
|
||||
}
|
||||
|
||||
if (donation.cryptoCode === null) {
|
||||
donationStats.usd.count += 1
|
||||
donationStats.usd.amount += donation.fiatAmount
|
||||
donationStats.usd.fiatAmount += donation.fiatAmount
|
||||
console.log(donation)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
props: {
|
||||
project: {
|
||||
...project,
|
||||
content,
|
||||
},
|
||||
donationStats,
|
||||
},
|
||||
}
|
||||
}
|
||||
64
pages/firo/___projects/index.tsx
Normal file
64
pages/firo/___projects/index.tsx
Normal file
@@ -0,0 +1,64 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import type { NextPage } from 'next'
|
||||
import Head from 'next/head'
|
||||
import ProjectCard from '../../../components/ProjectCard'
|
||||
import { ProjectItem } from '../../../utils/types'
|
||||
import { getProjects } from '../../../utils/md'
|
||||
import { useFundSlug } from '../../../utils/use-fund-slug'
|
||||
|
||||
const AllProjects: NextPage<{ projects: ProjectItem[] }> = ({ projects }) => {
|
||||
const [modalOpen, setModalOpen] = useState(false)
|
||||
const [selectedProject, setSelectedProject] = useState<ProjectItem>()
|
||||
const [sortedProjects, setSortedProjects] = useState<ProjectItem[]>()
|
||||
const fundSlug = useFundSlug()
|
||||
|
||||
useEffect(() => {
|
||||
setSortedProjects(projects.sort(() => 0.5 - Math.random()))
|
||||
}, [projects])
|
||||
|
||||
function closeModal() {
|
||||
setModalOpen(false)
|
||||
}
|
||||
|
||||
function openPaymentModal(project: ProjectItem) {
|
||||
setSelectedProject(project)
|
||||
setModalOpen(true)
|
||||
}
|
||||
|
||||
if (!fundSlug) return <></>
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>MAGIC Monero Fund | Projects</title>
|
||||
</Head>
|
||||
<section className="p-4 md:p-8 flex flex-col items-center">
|
||||
<div className="flex justify-between items-center pb-8 w-full">
|
||||
<h1 className="py-4 text-3xl font-extrabold leading-9 tracking-tight text-gray-900 sm:text-4xl sm:leading-10 md:text-6xl md:leading-14">
|
||||
Projects
|
||||
</h1>
|
||||
</div>
|
||||
<ul className="grid md:grid-cols-3 gap-4 max-w-5xl">
|
||||
{sortedProjects &&
|
||||
sortedProjects.map((p, i) => (
|
||||
<li key={i} className="">
|
||||
<ProjectCard project={p} />
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</section>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default AllProjects
|
||||
|
||||
export async function getStaticProps({ params }: { params: any }) {
|
||||
const projects = getProjects('monero')
|
||||
|
||||
return {
|
||||
props: {
|
||||
projects,
|
||||
},
|
||||
}
|
||||
}
|
||||
290
pages/firo/apply.tsx
Normal file
290
pages/firo/apply.tsx
Normal file
@@ -0,0 +1,290 @@
|
||||
import { useRouter } from 'next/router'
|
||||
import { useState } from 'react'
|
||||
import { useForm } from 'react-hook-form'
|
||||
import Link from 'next/link'
|
||||
|
||||
import { Button } from '../../components/ui/button'
|
||||
|
||||
export default function Apply() {
|
||||
const [loading, setLoading] = useState(false)
|
||||
const router = useRouter()
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
watch,
|
||||
formState: { errors },
|
||||
} = useForm()
|
||||
|
||||
const onSubmit = async (data: any) => {
|
||||
setLoading(true)
|
||||
console.log(data)
|
||||
// TODO: fix dis
|
||||
// const res = await fetchPostJSON('/api/sendgrid', data)
|
||||
// if (res.message === 'success') {
|
||||
// router.push('/submitted')
|
||||
// }
|
||||
// console.log(res)
|
||||
setLoading(false)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="mx-auto flex-1 flex flex-col items-center justify-center gap-4 py-8 prose">
|
||||
<form onSubmit={handleSubmit(onSubmit)} className="max-w-5xl flex flex-col gap-4 p-4">
|
||||
<div>
|
||||
<h1>Application for Monero Fund Project Listing or General Fund Grant</h1>
|
||||
<p>Thanks for your interest in the Monero Fund!</p>
|
||||
<p>
|
||||
We're incredibly grateful to contributors like you working to support Monero,
|
||||
Bitcoin and other free and open source projects.
|
||||
</p>
|
||||
<p>
|
||||
The MAGIC Monero Fund is offering a grant program and fundraising platform to support
|
||||
Monero research and development, especially relating to privacy, security, user
|
||||
experience, and efficiency. Proposals can be related to the Monero protocol directly, or
|
||||
they can be related to other areas of the Monero ecosystem. For research projects,
|
||||
please refer to special instructions
|
||||
<Link href="/apply_research"> here</Link>.
|
||||
</p>
|
||||
<h2>Proposal Evaluation Criteria</h2>
|
||||
<div>
|
||||
Submitted proposals will be evaluated by the committee based on the following criteria:
|
||||
<ul>
|
||||
<li>
|
||||
<b>Impact:</b> The proposal should have a clear impact on the Monero Project.
|
||||
</li>
|
||||
<li>
|
||||
<b>Originality:</b> The proposal should be original and not a rehash of existing
|
||||
work.
|
||||
</li>
|
||||
<li>
|
||||
<b>Feasibility:</b> The proposal should be feasible to complete within the proposed
|
||||
time frame.
|
||||
</li>
|
||||
<li>
|
||||
<b>Quality:</b> The proposal should be well-written and well-organized.
|
||||
</li>
|
||||
<li>
|
||||
<b>Relevance:</b> The proposal should be relevant to the Monero Project.
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<h2 id="Eligibility">Eligibility</h2>
|
||||
<p>
|
||||
All qualified researchers are eligible to apply, regardless of educational attainment or
|
||||
occupation. However, as a nonprofit organization registered under U.S. tax laws, MAGIC
|
||||
Grants is required to comply with certain laws when disbursing funds to grant
|
||||
recipients. Grant recipients must complete a Due Diligence checklist, which are the last
|
||||
two pages of{' '}
|
||||
<a href="https://magicgrants.org/funds/MAGIC%20Fund%20Grant%20Disbursement%20Process%20and%20Requirements.pdf">
|
||||
this document
|
||||
</a>
|
||||
. This includes the collection of your ID and tax information. We will conduct sanctions
|
||||
checks.
|
||||
</p>
|
||||
<h2>How to Submit a Proposal</h2>
|
||||
<p>
|
||||
To submit a proposal, please complete the form below or create an issue on{' '}
|
||||
<a href="https://github.com/MAGICGrants/Monero-Fund/issues/new?assignees=&labels=&template=grant-application.md&title=[Grant+Title]">
|
||||
Github
|
||||
</a>
|
||||
. Applicants are free to use their legal name or a pseudonym at this step, although note
|
||||
the{' '}
|
||||
<a href="#Eligibility">
|
||||
<b>Eligibility</b>
|
||||
</a>{' '}
|
||||
section. You can choose to apply for a direct grant from the MAGIC Monero Fund's
|
||||
General Fund and/or request that your project be listed on MoneroFund.org to raise funds
|
||||
from Monero community members.
|
||||
</p>
|
||||
<p>
|
||||
Please note this form is not considered confidential and is effectively equivalent to a
|
||||
public GitHub issue. In order to reach out privately, please send an email to
|
||||
MoneroFund@magicgrants.org.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<label className="checkbox">
|
||||
<input type="checkbox" {...register('general_fund')} />
|
||||
Apply to receive a grant from the Magic Monero Fund.
|
||||
</label>
|
||||
|
||||
<label className="checkbox">
|
||||
<input type="checkbox" {...register('explore_page')} />
|
||||
Apply for project to be listed on the Monero Fund Donation Page.
|
||||
</label>
|
||||
|
||||
<div className="w-full flex flex-col">
|
||||
<label htmlFor="project_name">Project Name *</label>
|
||||
<input
|
||||
className="appearance-none block w-full text-gray-700 border rounded py-2 px-3 mb-3 leading-tight focus:outline-none focus:ring-0"
|
||||
id="project_name"
|
||||
type="text"
|
||||
{...register('project_name', { required: true })}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="w-full flex flex-col">
|
||||
<label htmlFor="your_name">Your Name or Pseudonym *</label>
|
||||
<input
|
||||
className="appearance-none block w-full text-gray-700 border rounded py-2 px-3 mb-3 leading-tight focus:outline-none focus:ring-0"
|
||||
id="your_name"
|
||||
type="text"
|
||||
{...register('your_name', { required: true })}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="w-full flex flex-col">
|
||||
<label htmlFor="email">Email *</label>
|
||||
<input
|
||||
className="appearance-none block w-full text-gray-700 border rounded py-2 px-3 mb-3 leading-tight focus:outline-none focus:ring-0"
|
||||
id="email"
|
||||
type="text"
|
||||
{...register('email', { required: true })}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="w-full flex flex-col">
|
||||
<label htmlFor="github">Project GitHub (if applicable)</label>
|
||||
<input
|
||||
className="appearance-none block w-full text-gray-700 border rounded py-2 px-3 mb-3 leading-tight focus:outline-none focus:ring-0"
|
||||
id="github"
|
||||
type="text"
|
||||
{...register('github')}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="w-full flex flex-col">
|
||||
<label htmlFor="personal_github">Personal GitHub (if applicable)</label>
|
||||
<input
|
||||
className="appearance-none block w-full text-gray-700 border rounded py-2 px-3 mb-3 leading-tight focus:outline-none focus:ring-0"
|
||||
id="personal_github"
|
||||
type="text"
|
||||
{...register('personal_github')}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="w-full flex flex-col">
|
||||
<label htmlFor="other_contact">Other Contact Details (if applicable)</label>
|
||||
<small>
|
||||
Please list any other relevant contact details you are comfortable sharing in case we
|
||||
need to reach out with questions. These could include github username, twitter username,
|
||||
LinkedIn, Reddit handle, other social media handles, emails, phone numbers, usernames,
|
||||
etc.
|
||||
</small>
|
||||
<textarea
|
||||
className="appearance-none block w-full text-gray-700 border rounded py-2 px-3 mb-3 leading-tight focus:outline-none focus:ring-0"
|
||||
id="other_contact"
|
||||
{...register('other_contact')}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="w-full flex flex-col">
|
||||
<label htmlFor="short_description">Short Project Description *</label>
|
||||
<small>
|
||||
This will be listed on the explore projects page of the Monero Fund website. 2-3
|
||||
sentences.
|
||||
</small>
|
||||
<textarea
|
||||
className="appearance-none block w-full text-gray-700 border rounded py-2 px-3 mb-3 leading-tight focus:outline-none focus:ring-0"
|
||||
id="short_description"
|
||||
{...register('short_description', { required: true })}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="w-full flex flex-col">
|
||||
<label htmlFor="long_description">Long Project Description</label>
|
||||
<small>
|
||||
This will be listed on your personal project page of the Monero Fund website. It can be
|
||||
longer and go into detail about your project.
|
||||
</small>
|
||||
<textarea
|
||||
className="appearance-none block w-full text-gray-700 border rounded py-2 px-3 mb-3 leading-tight focus:outline-none focus:ring-0"
|
||||
id="long_description"
|
||||
{...register('long_description')}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<label className="checkbox">
|
||||
<input type="checkbox" {...register('free_open_source')} />
|
||||
Is the project free and open source?
|
||||
</label>
|
||||
|
||||
<label className="checkbox">
|
||||
<input type="checkbox" {...register('are_you_lead')} />
|
||||
Are you the Project Lead / Lead Contributor
|
||||
</label>
|
||||
|
||||
<div className="w-full flex flex-col">
|
||||
<label htmlFor="other_lead">
|
||||
If someone else, please list the project's Lead Contributor or Maintainer
|
||||
</label>
|
||||
<input
|
||||
className="appearance-none block w-full text-gray-700 border rounded py-2 px-3 mb-3 leading-tight focus:outline-none focus:ring-0"
|
||||
id="other_lead"
|
||||
type="text"
|
||||
{...register('other_lead')}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="w-full flex flex-col">
|
||||
<label htmlFor="potential_impact">Potential Impact *</label>
|
||||
<small>Why is this project important to the Monero community?</small>
|
||||
<textarea
|
||||
className="appearance-none block w-full text-gray-700 border rounded py-2 px-3 mb-3 leading-tight focus:outline-none focus:ring-0"
|
||||
id="potential_impact"
|
||||
{...register('potential_impact', { required: true })}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="w-full flex flex-col">
|
||||
<label htmlFor="timelines">Project Timelines and Potential Milestones *</label>
|
||||
<textarea
|
||||
className="appearance-none block w-full text-gray-700 border rounded py-2 px-3 mb-3 leading-tight focus:outline-none focus:ring-0"
|
||||
id="timelines"
|
||||
{...register('timelines', { required: true })}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="w-full flex flex-col">
|
||||
<label htmlFor="proposed_budget">
|
||||
If you're applying for a grant from the general fund, please submit a proposed
|
||||
budget for the requested amount and how it will be used.
|
||||
</label>
|
||||
<input
|
||||
className="appearance-none block w-full text-gray-700 border rounded py-2 px-3 mb-3 leading-tight focus:outline-none focus:ring-0"
|
||||
id="proposed_budget"
|
||||
type="text"
|
||||
{...register('proposed_budget')}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="w-full flex flex-col">
|
||||
<label htmlFor="bios">Applicant Bios (Optional)</label>
|
||||
<small>List relevant accomplishments.</small>
|
||||
<input
|
||||
className="appearance-none block w-full text-gray-700 border rounded py-2 px-3 mb-3 leading-tight focus:outline-none focus:ring-0"
|
||||
id="bios"
|
||||
type="text"
|
||||
{...register('bios')}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<small>
|
||||
The MAGIC Monero Fund may require each recipient to sign a Grant Agreement before any
|
||||
funds are disbursed. This agreement will set milestones and funds will only be released
|
||||
upon completion of milestones. In order to comply with US regulations, recipients will
|
||||
need to identify themselves to MAGIC, in accordance with US law.
|
||||
</small>
|
||||
|
||||
<Button disabled={loading}>Apply</Button>
|
||||
|
||||
<p>
|
||||
After submitting your application, please allow our team up to three weeks to review your
|
||||
application. Email us at{' '}
|
||||
<a href="mailto:monerofund@magicgrants.org">monerofund@magicgrants.org</a> if you have any
|
||||
questions.
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
176
pages/firo/index.tsx
Normal file
176
pages/firo/index.tsx
Normal file
@@ -0,0 +1,176 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import type { NextPage } from 'next'
|
||||
import Head from 'next/head'
|
||||
import { useSession } from 'next-auth/react'
|
||||
import { useTheme } from 'next-themes'
|
||||
|
||||
import { getProjects } from '../../utils/md'
|
||||
import { ProjectItem } from '../../utils/types'
|
||||
import Typing from '../../components/Typing'
|
||||
import CustomLink from '../../components/CustomLink'
|
||||
import { Button } from '../../components/ui/button'
|
||||
import { Dialog, DialogContent, DialogTrigger } from '../../components/ui/dialog'
|
||||
import DonationFormModal from '../../components/DonationFormModal'
|
||||
import MembershipFormModal from '../../components/MembershipFormModal'
|
||||
import ProjectList from '../../components/ProjectList'
|
||||
import LoginFormModal from '../../components/LoginFormModal'
|
||||
import RegisterFormModal from '../../components/RegisterFormModal'
|
||||
import PasswordResetFormModal from '../../components/PasswordResetFormModal'
|
||||
import { trpc } from '../../utils/trpc'
|
||||
import { funds } from '../../utils/funds'
|
||||
|
||||
const fund = funds['firo']
|
||||
|
||||
const Home: NextPage<{ projects: any }> = ({ projects }) => {
|
||||
const [donateModalOpen, setDonateModalOpen] = useState(false)
|
||||
const [memberModalOpen, setMemberModalOpen] = useState(false)
|
||||
const [registerIsOpen, setRegisterIsOpen] = useState(false)
|
||||
const [loginIsOpen, setLoginIsOpen] = useState(false)
|
||||
const [passwordResetIsOpen, setPasswordResetIsOpen] = useState(false)
|
||||
const session = useSession()
|
||||
|
||||
const userHasMembershipQuery = trpc.donation.userHasMembership.useQuery(
|
||||
{ projectSlug: fund.slug },
|
||||
{ enabled: false }
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
if (session.status === 'authenticated') {
|
||||
userHasMembershipQuery.refetch()
|
||||
}
|
||||
}, [session.status])
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>{fund.title}</title>
|
||||
<meta name="description" content="TKTK" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
</Head>
|
||||
|
||||
<div className="divide-y divide-gray-200">
|
||||
<div className="pt-4 md:pb-8">
|
||||
<h1 className="py-4 text-3xl font-extrabold leading-9 tracking-tight text-gray-900 sm:text-4xl sm:leading-10 md:text-6xl md:leading-14">
|
||||
Support <Typing />
|
||||
</h1>
|
||||
<p className="text-xl leading-7 text-gray-500">
|
||||
Help us to provide sustainable funding for free and open-source contributors working on
|
||||
freedom tech and projects that help Monero flourish.
|
||||
</p>
|
||||
|
||||
<div className="flex flex-wrap py-4 space-x-4">
|
||||
<Button onClick={() => setDonateModalOpen(true)} size="lg">
|
||||
Donate to Monero Comittee General Fund
|
||||
</Button>
|
||||
|
||||
{!userHasMembershipQuery.data && (
|
||||
<Button
|
||||
onClick={() =>
|
||||
session.status === 'authenticated'
|
||||
? setMemberModalOpen(true)
|
||||
: setRegisterIsOpen(true)
|
||||
}
|
||||
variant="light"
|
||||
size="lg"
|
||||
>
|
||||
Get Annual Membership
|
||||
</Button>
|
||||
)}
|
||||
|
||||
{!!userHasMembershipQuery.data && (
|
||||
<CustomLink href={`/${fund.slug}/account/my-memberships`}>
|
||||
<Button variant="light" size="lg">
|
||||
My Memberships
|
||||
</Button>{' '}
|
||||
</CustomLink>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="flex flex-row flex-wrap">
|
||||
<p className="text-md leading-7 text-gray-500">
|
||||
Want to receive funding for your work?
|
||||
<CustomLink href={`/${fund.slug}/apply`}>
|
||||
{' '}
|
||||
Apply for a Monero development or research grant!
|
||||
</CustomLink>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<p className="text-sm leading-7 text-gray-400">
|
||||
We are a 501(c)(3) public charity. All donations are tax deductible.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="divide-y divide-gray-200">
|
||||
<div className="xl:pt-18 space-y-2 pt-8 md:space-y-5">
|
||||
<h1 className="text-3xl font-extrabold leading-9 tracking-tight text-gray-900 sm:text-4xl sm:leading-10 md:text-6xl md:leading-14">
|
||||
Explore Projects
|
||||
</h1>
|
||||
<p className="pt-2 text-lg leading-7 text-gray-500">
|
||||
Browse through a showcase of projects supported by us.
|
||||
</p>
|
||||
<ProjectList projects={projects} />
|
||||
<div className="flex justify-end pt-4 text-base font-medium leading-6">
|
||||
<CustomLink href={`/${fund.slug}/projects`} aria-label="View All Projects">
|
||||
View Projects →
|
||||
</CustomLink>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Dialog open={donateModalOpen} onOpenChange={setDonateModalOpen}>
|
||||
<DialogContent>
|
||||
<DonationFormModal project={fund} />
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
<Dialog open={memberModalOpen} onOpenChange={setMemberModalOpen}>
|
||||
<DialogContent>
|
||||
<MembershipFormModal project={fund} />
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
{session.status !== 'authenticated' && (
|
||||
<>
|
||||
<Dialog open={loginIsOpen} onOpenChange={setLoginIsOpen}>
|
||||
<DialogContent>
|
||||
<LoginFormModal
|
||||
close={() => setLoginIsOpen(false)}
|
||||
openRegisterModal={() => setRegisterIsOpen(true)}
|
||||
openPasswordResetModal={() => setPasswordResetIsOpen(true)}
|
||||
/>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
<Dialog open={registerIsOpen} onOpenChange={setRegisterIsOpen}>
|
||||
<DialogContent>
|
||||
<RegisterFormModal
|
||||
openLoginModal={() => setLoginIsOpen(true)}
|
||||
close={() => setRegisterIsOpen(false)}
|
||||
/>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
<Dialog open={passwordResetIsOpen} onOpenChange={setPasswordResetIsOpen}>
|
||||
<DialogContent>
|
||||
<PasswordResetFormModal close={() => setPasswordResetIsOpen(false)} />
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default Home
|
||||
|
||||
export async function getStaticProps({ params }: { params: any }) {
|
||||
const projects = getProjects(fund.slug)
|
||||
|
||||
return {
|
||||
props: {
|
||||
projects,
|
||||
},
|
||||
}
|
||||
}
|
||||
17
pages/firo/submitted.tsx
Normal file
17
pages/firo/submitted.tsx
Normal file
@@ -0,0 +1,17 @@
|
||||
import Link from 'next/link'
|
||||
|
||||
export default function Submitted() {
|
||||
return (
|
||||
<div className="flex-1 flex flex-col items-center justify-center gap-4 py-8">
|
||||
<h2>Thank you for your application!</h2>
|
||||
<p>
|
||||
If you have any questions or need a donation receipt, please reach out to{' '}
|
||||
<a href="mailto:info@magicgrants.org">info@magicgrants.org</a>
|
||||
</p>
|
||||
.
|
||||
<p>
|
||||
<Link href="/">Return Home</Link>
|
||||
</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
25
pages/firo/thankyou.tsx
Normal file
25
pages/firo/thankyou.tsx
Normal file
@@ -0,0 +1,25 @@
|
||||
import Link from 'next/link'
|
||||
import { useFundSlug } from '../../utils/use-fund-slug'
|
||||
import CustomLink from '../../components/CustomLink'
|
||||
import { Button } from '../../components/ui/button'
|
||||
|
||||
export default function ThankYou() {
|
||||
const fundSlug = useFundSlug()
|
||||
return (
|
||||
<div className="flex-1 flex flex-col items-center justify-center gap-4 py-8">
|
||||
<h2 className="font-bold">Thank you for your donation!</h2>
|
||||
<p>
|
||||
If you have any questions, please reach out to{' '}
|
||||
<CustomLink href="mailto:info@magicgrants.org">info@magicgrants.org</CustomLink>
|
||||
</p>
|
||||
|
||||
<br />
|
||||
|
||||
<p>
|
||||
<Button>
|
||||
<Link href={`/${fundSlug}`}>Return Home</Link>
|
||||
</Button>
|
||||
</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
290
pages/general/apply.tsx
Normal file
290
pages/general/apply.tsx
Normal file
@@ -0,0 +1,290 @@
|
||||
import { useRouter } from 'next/router'
|
||||
import { useState } from 'react'
|
||||
import { useForm } from 'react-hook-form'
|
||||
import Link from 'next/link'
|
||||
|
||||
import { Button } from '../../components/ui/button'
|
||||
|
||||
export default function Apply() {
|
||||
const [loading, setLoading] = useState(false)
|
||||
const router = useRouter()
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
watch,
|
||||
formState: { errors },
|
||||
} = useForm()
|
||||
|
||||
const onSubmit = async (data: any) => {
|
||||
setLoading(true)
|
||||
console.log(data)
|
||||
// TODO: fix dis
|
||||
// const res = await fetchPostJSON('/api/sendgrid', data)
|
||||
// if (res.message === 'success') {
|
||||
// router.push('/submitted')
|
||||
// }
|
||||
// console.log(res)
|
||||
setLoading(false)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="mx-auto flex-1 flex flex-col items-center justify-center gap-4 py-8 prose">
|
||||
<form onSubmit={handleSubmit(onSubmit)} className="max-w-5xl flex flex-col gap-4 p-4">
|
||||
<div>
|
||||
<h1>Application for Monero Fund Project Listing or General Fund Grant</h1>
|
||||
<p>Thanks for your interest in the Monero Fund!</p>
|
||||
<p>
|
||||
We're incredibly grateful to contributors like you working to support Monero,
|
||||
Bitcoin and other free and open source projects.
|
||||
</p>
|
||||
<p>
|
||||
The MAGIC Monero Fund is offering a grant program and fundraising platform to support
|
||||
Monero research and development, especially relating to privacy, security, user
|
||||
experience, and efficiency. Proposals can be related to the Monero protocol directly, or
|
||||
they can be related to other areas of the Monero ecosystem. For research projects,
|
||||
please refer to special instructions
|
||||
<Link href="/apply_research"> here</Link>.
|
||||
</p>
|
||||
<h2>Proposal Evaluation Criteria</h2>
|
||||
<div>
|
||||
Submitted proposals will be evaluated by the committee based on the following criteria:
|
||||
<ul>
|
||||
<li>
|
||||
<b>Impact:</b> The proposal should have a clear impact on the Monero Project.
|
||||
</li>
|
||||
<li>
|
||||
<b>Originality:</b> The proposal should be original and not a rehash of existing
|
||||
work.
|
||||
</li>
|
||||
<li>
|
||||
<b>Feasibility:</b> The proposal should be feasible to complete within the proposed
|
||||
time frame.
|
||||
</li>
|
||||
<li>
|
||||
<b>Quality:</b> The proposal should be well-written and well-organized.
|
||||
</li>
|
||||
<li>
|
||||
<b>Relevance:</b> The proposal should be relevant to the Monero Project.
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<h2 id="Eligibility">Eligibility</h2>
|
||||
<p>
|
||||
All qualified researchers are eligible to apply, regardless of educational attainment or
|
||||
occupation. However, as a nonprofit organization registered under U.S. tax laws, MAGIC
|
||||
Grants is required to comply with certain laws when disbursing funds to grant
|
||||
recipients. Grant recipients must complete a Due Diligence checklist, which are the last
|
||||
two pages of{' '}
|
||||
<a href="https://magicgrants.org/funds/MAGIC%20Fund%20Grant%20Disbursement%20Process%20and%20Requirements.pdf">
|
||||
this document
|
||||
</a>
|
||||
. This includes the collection of your ID and tax information. We will conduct sanctions
|
||||
checks.
|
||||
</p>
|
||||
<h2>How to Submit a Proposal</h2>
|
||||
<p>
|
||||
To submit a proposal, please complete the form below or create an issue on{' '}
|
||||
<a href="https://github.com/MAGICGrants/Monero-Fund/issues/new?assignees=&labels=&template=grant-application.md&title=[Grant+Title]">
|
||||
Github
|
||||
</a>
|
||||
. Applicants are free to use their legal name or a pseudonym at this step, although note
|
||||
the{' '}
|
||||
<a href="#Eligibility">
|
||||
<b>Eligibility</b>
|
||||
</a>{' '}
|
||||
section. You can choose to apply for a direct grant from the MAGIC Monero Fund's
|
||||
General Fund and/or request that your project be listed on MoneroFund.org to raise funds
|
||||
from Monero community members.
|
||||
</p>
|
||||
<p>
|
||||
Please note this form is not considered confidential and is effectively equivalent to a
|
||||
public GitHub issue. In order to reach out privately, please send an email to
|
||||
MoneroFund@magicgrants.org.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<label className="checkbox">
|
||||
<input type="checkbox" {...register('general_fund')} />
|
||||
Apply to receive a grant from the Magic Monero Fund.
|
||||
</label>
|
||||
|
||||
<label className="checkbox">
|
||||
<input type="checkbox" {...register('explore_page')} />
|
||||
Apply for project to be listed on the Monero Fund Donation Page.
|
||||
</label>
|
||||
|
||||
<div className="w-full flex flex-col">
|
||||
<label htmlFor="project_name">Project Name *</label>
|
||||
<input
|
||||
className="appearance-none block w-full text-gray-700 border rounded py-2 px-3 mb-3 leading-tight focus:outline-none focus:ring-0"
|
||||
id="project_name"
|
||||
type="text"
|
||||
{...register('project_name', { required: true })}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="w-full flex flex-col">
|
||||
<label htmlFor="your_name">Your Name or Pseudonym *</label>
|
||||
<input
|
||||
className="appearance-none block w-full text-gray-700 border rounded py-2 px-3 mb-3 leading-tight focus:outline-none focus:ring-0"
|
||||
id="your_name"
|
||||
type="text"
|
||||
{...register('your_name', { required: true })}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="w-full flex flex-col">
|
||||
<label htmlFor="email">Email *</label>
|
||||
<input
|
||||
className="appearance-none block w-full text-gray-700 border rounded py-2 px-3 mb-3 leading-tight focus:outline-none focus:ring-0"
|
||||
id="email"
|
||||
type="text"
|
||||
{...register('email', { required: true })}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="w-full flex flex-col">
|
||||
<label htmlFor="github">Project GitHub (if applicable)</label>
|
||||
<input
|
||||
className="appearance-none block w-full text-gray-700 border rounded py-2 px-3 mb-3 leading-tight focus:outline-none focus:ring-0"
|
||||
id="github"
|
||||
type="text"
|
||||
{...register('github')}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="w-full flex flex-col">
|
||||
<label htmlFor="personal_github">Personal GitHub (if applicable)</label>
|
||||
<input
|
||||
className="appearance-none block w-full text-gray-700 border rounded py-2 px-3 mb-3 leading-tight focus:outline-none focus:ring-0"
|
||||
id="personal_github"
|
||||
type="text"
|
||||
{...register('personal_github')}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="w-full flex flex-col">
|
||||
<label htmlFor="other_contact">Other Contact Details (if applicable)</label>
|
||||
<small>
|
||||
Please list any other relevant contact details you are comfortable sharing in case we
|
||||
need to reach out with questions. These could include github username, twitter username,
|
||||
LinkedIn, Reddit handle, other social media handles, emails, phone numbers, usernames,
|
||||
etc.
|
||||
</small>
|
||||
<textarea
|
||||
className="appearance-none block w-full text-gray-700 border rounded py-2 px-3 mb-3 leading-tight focus:outline-none focus:ring-0"
|
||||
id="other_contact"
|
||||
{...register('other_contact')}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="w-full flex flex-col">
|
||||
<label htmlFor="short_description">Short Project Description *</label>
|
||||
<small>
|
||||
This will be listed on the explore projects page of the Monero Fund website. 2-3
|
||||
sentences.
|
||||
</small>
|
||||
<textarea
|
||||
className="appearance-none block w-full text-gray-700 border rounded py-2 px-3 mb-3 leading-tight focus:outline-none focus:ring-0"
|
||||
id="short_description"
|
||||
{...register('short_description', { required: true })}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="w-full flex flex-col">
|
||||
<label htmlFor="long_description">Long Project Description</label>
|
||||
<small>
|
||||
This will be listed on your personal project page of the Monero Fund website. It can be
|
||||
longer and go into detail about your project.
|
||||
</small>
|
||||
<textarea
|
||||
className="appearance-none block w-full text-gray-700 border rounded py-2 px-3 mb-3 leading-tight focus:outline-none focus:ring-0"
|
||||
id="long_description"
|
||||
{...register('long_description')}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<label className="checkbox">
|
||||
<input type="checkbox" {...register('free_open_source')} />
|
||||
Is the project free and open source?
|
||||
</label>
|
||||
|
||||
<label className="checkbox">
|
||||
<input type="checkbox" {...register('are_you_lead')} />
|
||||
Are you the Project Lead / Lead Contributor
|
||||
</label>
|
||||
|
||||
<div className="w-full flex flex-col">
|
||||
<label htmlFor="other_lead">
|
||||
If someone else, please list the project's Lead Contributor or Maintainer
|
||||
</label>
|
||||
<input
|
||||
className="appearance-none block w-full text-gray-700 border rounded py-2 px-3 mb-3 leading-tight focus:outline-none focus:ring-0"
|
||||
id="other_lead"
|
||||
type="text"
|
||||
{...register('other_lead')}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="w-full flex flex-col">
|
||||
<label htmlFor="potential_impact">Potential Impact *</label>
|
||||
<small>Why is this project important to the Monero community?</small>
|
||||
<textarea
|
||||
className="appearance-none block w-full text-gray-700 border rounded py-2 px-3 mb-3 leading-tight focus:outline-none focus:ring-0"
|
||||
id="potential_impact"
|
||||
{...register('potential_impact', { required: true })}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="w-full flex flex-col">
|
||||
<label htmlFor="timelines">Project Timelines and Potential Milestones *</label>
|
||||
<textarea
|
||||
className="appearance-none block w-full text-gray-700 border rounded py-2 px-3 mb-3 leading-tight focus:outline-none focus:ring-0"
|
||||
id="timelines"
|
||||
{...register('timelines', { required: true })}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="w-full flex flex-col">
|
||||
<label htmlFor="proposed_budget">
|
||||
If you're applying for a grant from the general fund, please submit a proposed
|
||||
budget for the requested amount and how it will be used.
|
||||
</label>
|
||||
<input
|
||||
className="appearance-none block w-full text-gray-700 border rounded py-2 px-3 mb-3 leading-tight focus:outline-none focus:ring-0"
|
||||
id="proposed_budget"
|
||||
type="text"
|
||||
{...register('proposed_budget')}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="w-full flex flex-col">
|
||||
<label htmlFor="bios">Applicant Bios (Optional)</label>
|
||||
<small>List relevant accomplishments.</small>
|
||||
<input
|
||||
className="appearance-none block w-full text-gray-700 border rounded py-2 px-3 mb-3 leading-tight focus:outline-none focus:ring-0"
|
||||
id="bios"
|
||||
type="text"
|
||||
{...register('bios')}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<small>
|
||||
The MAGIC Monero Fund may require each recipient to sign a Grant Agreement before any
|
||||
funds are disbursed. This agreement will set milestones and funds will only be released
|
||||
upon completion of milestones. In order to comply with US regulations, recipients will
|
||||
need to identify themselves to MAGIC, in accordance with US law.
|
||||
</small>
|
||||
|
||||
<Button disabled={loading}>Apply</Button>
|
||||
|
||||
<p>
|
||||
After submitting your application, please allow our team up to three weeks to review your
|
||||
application. Email us at{' '}
|
||||
<a href="mailto:monerofund@magicgrants.org">monerofund@magicgrants.org</a> if you have any
|
||||
questions.
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
176
pages/general/index.tsx
Normal file
176
pages/general/index.tsx
Normal file
@@ -0,0 +1,176 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import type { NextPage } from 'next'
|
||||
import Head from 'next/head'
|
||||
import { useSession } from 'next-auth/react'
|
||||
import { useTheme } from 'next-themes'
|
||||
|
||||
import { getProjects } from '../../utils/md'
|
||||
import { ProjectItem } from '../../utils/types'
|
||||
import Typing from '../../components/Typing'
|
||||
import CustomLink from '../../components/CustomLink'
|
||||
import { Button } from '../../components/ui/button'
|
||||
import { Dialog, DialogContent, DialogTrigger } from '../../components/ui/dialog'
|
||||
import DonationFormModal from '../../components/DonationFormModal'
|
||||
import MembershipFormModal from '../../components/MembershipFormModal'
|
||||
import ProjectList from '../../components/ProjectList'
|
||||
import LoginFormModal from '../../components/LoginFormModal'
|
||||
import RegisterFormModal from '../../components/RegisterFormModal'
|
||||
import PasswordResetFormModal from '../../components/PasswordResetFormModal'
|
||||
import { trpc } from '../../utils/trpc'
|
||||
import { funds } from '../../utils/funds'
|
||||
|
||||
const fund = funds['general']
|
||||
|
||||
const Home: NextPage<{ projects: any }> = ({ projects }) => {
|
||||
const [donateModalOpen, setDonateModalOpen] = useState(false)
|
||||
const [memberModalOpen, setMemberModalOpen] = useState(false)
|
||||
const [registerIsOpen, setRegisterIsOpen] = useState(false)
|
||||
const [loginIsOpen, setLoginIsOpen] = useState(false)
|
||||
const [passwordResetIsOpen, setPasswordResetIsOpen] = useState(false)
|
||||
const session = useSession()
|
||||
|
||||
const userHasMembershipQuery = trpc.donation.userHasMembership.useQuery(
|
||||
{ projectSlug: fund.slug },
|
||||
{ enabled: false }
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
if (session.status === 'authenticated') {
|
||||
userHasMembershipQuery.refetch()
|
||||
}
|
||||
}, [session.status])
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>{fund.title}</title>
|
||||
<meta name="description" content="TKTK" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
</Head>
|
||||
|
||||
<div className="divide-y divide-gray-200">
|
||||
<div className="pt-4 md:pb-8">
|
||||
<h1 className="py-4 text-3xl font-extrabold leading-9 tracking-tight text-gray-900 sm:text-4xl sm:leading-10 md:text-6xl md:leading-14">
|
||||
Support <Typing />
|
||||
</h1>
|
||||
<p className="text-xl leading-7 text-gray-500">
|
||||
Help us to provide sustainable funding for free and open-source contributors working on
|
||||
freedom tech and projects that help Monero flourish.
|
||||
</p>
|
||||
|
||||
<div className="flex flex-wrap py-4 space-x-4">
|
||||
<Button onClick={() => setDonateModalOpen(true)} size="lg">
|
||||
Donate to Monero Comittee General Fund
|
||||
</Button>
|
||||
|
||||
{!userHasMembershipQuery.data && (
|
||||
<Button
|
||||
onClick={() =>
|
||||
session.status === 'authenticated'
|
||||
? setMemberModalOpen(true)
|
||||
: setRegisterIsOpen(true)
|
||||
}
|
||||
variant="light"
|
||||
size="lg"
|
||||
>
|
||||
Get Annual Membership
|
||||
</Button>
|
||||
)}
|
||||
|
||||
{!!userHasMembershipQuery.data && (
|
||||
<CustomLink href={`/${fund.slug}/account/my-memberships`}>
|
||||
<Button variant="light" size="lg">
|
||||
My Memberships
|
||||
</Button>{' '}
|
||||
</CustomLink>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="flex flex-row flex-wrap">
|
||||
<p className="text-md leading-7 text-gray-500">
|
||||
Want to receive funding for your work?
|
||||
<CustomLink href={`/${fund.slug}/apply`}>
|
||||
{' '}
|
||||
Apply for a Monero development or research grant!
|
||||
</CustomLink>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<p className="text-sm leading-7 text-gray-400">
|
||||
We are a 501(c)(3) public charity. All donations are tax deductible.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="divide-y divide-gray-200">
|
||||
<div className="xl:pt-18 space-y-2 pt-8 md:space-y-5">
|
||||
<h1 className="text-3xl font-extrabold leading-9 tracking-tight text-gray-900 sm:text-4xl sm:leading-10 md:text-6xl md:leading-14">
|
||||
Explore Projects
|
||||
</h1>
|
||||
<p className="pt-2 text-lg leading-7 text-gray-500">
|
||||
Browse through a showcase of projects supported by us.
|
||||
</p>
|
||||
<ProjectList projects={projects} />
|
||||
<div className="flex justify-end pt-4 text-base font-medium leading-6">
|
||||
<CustomLink href={`/${fund.slug}/projects`} aria-label="View All Projects">
|
||||
View Projects →
|
||||
</CustomLink>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Dialog open={donateModalOpen} onOpenChange={setDonateModalOpen}>
|
||||
<DialogContent>
|
||||
<DonationFormModal project={fund} />
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
<Dialog open={memberModalOpen} onOpenChange={setMemberModalOpen}>
|
||||
<DialogContent>
|
||||
<MembershipFormModal project={fund} />
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
{session.status !== 'authenticated' && (
|
||||
<>
|
||||
<Dialog open={loginIsOpen} onOpenChange={setLoginIsOpen}>
|
||||
<DialogContent>
|
||||
<LoginFormModal
|
||||
close={() => setLoginIsOpen(false)}
|
||||
openRegisterModal={() => setRegisterIsOpen(true)}
|
||||
openPasswordResetModal={() => setPasswordResetIsOpen(true)}
|
||||
/>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
<Dialog open={registerIsOpen} onOpenChange={setRegisterIsOpen}>
|
||||
<DialogContent>
|
||||
<RegisterFormModal
|
||||
openLoginModal={() => setLoginIsOpen(true)}
|
||||
close={() => setRegisterIsOpen(false)}
|
||||
/>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
<Dialog open={passwordResetIsOpen} onOpenChange={setPasswordResetIsOpen}>
|
||||
<DialogContent>
|
||||
<PasswordResetFormModal close={() => setPasswordResetIsOpen(false)} />
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default Home
|
||||
|
||||
export async function getStaticProps({ params }: { params: any }) {
|
||||
const projects = getProjects(fund.slug)
|
||||
|
||||
return {
|
||||
props: {
|
||||
projects,
|
||||
},
|
||||
}
|
||||
}
|
||||
293
pages/general/projects/[slug].tsx
Normal file
293
pages/general/projects/[slug].tsx
Normal file
@@ -0,0 +1,293 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useSession } from 'next-auth/react'
|
||||
import { useRouter } from 'next/router'
|
||||
import { GetServerSidePropsContext, NextPage } from 'next/types'
|
||||
import Head from 'next/head'
|
||||
import ErrorPage from 'next/error'
|
||||
import Image from 'next/image'
|
||||
import xss from 'xss'
|
||||
|
||||
import { ProjectDonationStats, ProjectItem } from '../../../utils/types'
|
||||
import { getProjectBySlug } from '../../../utils/md'
|
||||
import markdownToHtml from '../../../utils/markdownToHtml'
|
||||
import PageHeading from '../../../components/PageHeading'
|
||||
import Progress from '../../../components/Progress'
|
||||
import { prisma } from '../../../server/services'
|
||||
import { Button } from '../../../components/ui/button'
|
||||
import { Dialog, DialogContent } from '../../../components/ui/dialog'
|
||||
import DonationFormModal from '../../../components/DonationFormModal'
|
||||
import MembershipFormModal from '../../../components/MembershipFormModal'
|
||||
import LoginFormModal from '../../../components/LoginFormModal'
|
||||
import RegisterFormModal from '../../../components/RegisterFormModal'
|
||||
import PasswordResetFormModal from '../../../components/PasswordResetFormModal'
|
||||
import CustomLink from '../../../components/CustomLink'
|
||||
import { trpc } from '../../../utils/trpc'
|
||||
import { getFundSlugFromUrlPath } from '../../../utils/funds'
|
||||
|
||||
type SingleProjectPageProps = {
|
||||
project: ProjectItem
|
||||
projects: ProjectItem[]
|
||||
donationStats: ProjectDonationStats
|
||||
}
|
||||
|
||||
const Project: NextPage<SingleProjectPageProps> = ({ project, donationStats }) => {
|
||||
const router = useRouter()
|
||||
const [donateModalOpen, setDonateModalOpen] = useState(false)
|
||||
const [memberModalOpen, setMemberModalOpen] = useState(false)
|
||||
const [registerIsOpen, setRegisterIsOpen] = useState(false)
|
||||
const [loginIsOpen, setLoginIsOpen] = useState(false)
|
||||
const [passwordResetIsOpen, setPasswordResetIsOpen] = useState(false)
|
||||
const session = useSession()
|
||||
|
||||
const userHasMembershipQuery = trpc.donation.userHasMembership.useQuery(
|
||||
{ projectSlug: project.slug },
|
||||
{ enabled: false }
|
||||
)
|
||||
|
||||
const {
|
||||
slug,
|
||||
title,
|
||||
summary,
|
||||
coverImage,
|
||||
git,
|
||||
twitter,
|
||||
content,
|
||||
nym,
|
||||
website,
|
||||
personalTwitter,
|
||||
personalWebsite,
|
||||
goal,
|
||||
isFunded,
|
||||
} = project
|
||||
|
||||
function formatBtc(bitcoin: number) {
|
||||
if (bitcoin > 0.1) {
|
||||
return `${bitcoin.toFixed(3) || 0.0} BTC`
|
||||
} else {
|
||||
return `${Math.floor(bitcoin * 100000000).toLocaleString()} sats`
|
||||
}
|
||||
}
|
||||
|
||||
function formatUsd(dollars: number): string {
|
||||
if (dollars == 0) {
|
||||
return '$0'
|
||||
} else if (dollars / 1000 > 1) {
|
||||
return `$${Math.round(dollars / 1000)}k+`
|
||||
} else {
|
||||
return `$${dollars.toFixed(0)}`
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (session.status === 'authenticated') {
|
||||
console.log('refetching')
|
||||
userHasMembershipQuery.refetch()
|
||||
}
|
||||
}, [session.status])
|
||||
|
||||
if (!router.isFallback && !slug) {
|
||||
return <ErrorPage statusCode={404} />
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>Monero Fund - {project.title}</title>
|
||||
</Head>
|
||||
|
||||
<div className="divide-y divide-gray-200">
|
||||
<PageHeading project={project}>
|
||||
<div className="flex flex-col items-center space-x-2 pt-8 xl:block">
|
||||
<Image
|
||||
src={coverImage}
|
||||
alt="avatar"
|
||||
width={300}
|
||||
height={300}
|
||||
className="h-72 w-72 mx-auto object-contain xl:hidden"
|
||||
/>
|
||||
|
||||
<div className="space-y-4">
|
||||
{!project.isFunded && (
|
||||
<div className="flex flex-col space-y-2">
|
||||
<Button onClick={() => setDonateModalOpen(true)}>Donate</Button>
|
||||
|
||||
{!userHasMembershipQuery.data && (
|
||||
<Button
|
||||
onClick={() =>
|
||||
session.status === 'authenticated'
|
||||
? setMemberModalOpen(true)
|
||||
: setRegisterIsOpen(true)
|
||||
}
|
||||
variant="outline"
|
||||
>
|
||||
Get Annual Membership
|
||||
</Button>
|
||||
)}
|
||||
|
||||
{!!userHasMembershipQuery.data && (
|
||||
<CustomLink href="/account/my-memberships">
|
||||
<Button variant="outline">My Memberships</Button>{' '}
|
||||
</CustomLink>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<h1 className="mb-4 font-bold">Raised</h1>
|
||||
|
||||
<Progress
|
||||
percent={Math.floor(
|
||||
((donationStats.xmr.fiatAmount +
|
||||
donationStats.btc.fiatAmount +
|
||||
donationStats.usd.fiatAmount) /
|
||||
goal) *
|
||||
100
|
||||
)}
|
||||
/>
|
||||
|
||||
<ul className="font-semibold space-y-1">
|
||||
<li className="flex items-center space-x-1">
|
||||
<span className="text-green-500 text-xl">{`${formatUsd(donationStats.xmr.fiatAmount + donationStats.btc.fiatAmount + donationStats.usd.fiatAmount)}`}</span>{' '}
|
||||
<span className="font-normal text-sm text-gray">
|
||||
in {donationStats.xmr.count + donationStats.btc.count + donationStats.usd.count}{' '}
|
||||
donations total
|
||||
</span>
|
||||
</li>
|
||||
<li>
|
||||
{donationStats.xmr.amount} XMR{' '}
|
||||
<span className="font-normal text-sm text-gray">
|
||||
in {donationStats.xmr.count} donations
|
||||
</span>
|
||||
</li>
|
||||
<li>
|
||||
{formatBtc(donationStats.btc.amount)}{' '}
|
||||
<span className="font-normal text-sm text-gray">
|
||||
in {donationStats.btc.count} donations
|
||||
</span>
|
||||
</li>
|
||||
<li>
|
||||
{`${formatUsd(donationStats.usd.amount)}`} Fiat{' '}
|
||||
<span className="font-normal text-sm text-gray">
|
||||
in {donationStats.usd.count} donations
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<article
|
||||
className="prose max-w-none pb-8 pt-8 xl:col-span-2"
|
||||
dangerouslySetInnerHTML={{ __html: xss(content || '') }}
|
||||
/>
|
||||
</PageHeading>
|
||||
</div>
|
||||
|
||||
<Dialog open={donateModalOpen} onOpenChange={setDonateModalOpen}>
|
||||
<DialogContent>
|
||||
<DonationFormModal project={project} />
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
<Dialog open={memberModalOpen} onOpenChange={setMemberModalOpen}>
|
||||
<DialogContent>
|
||||
<MembershipFormModal project={project} />
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
{session.status !== 'authenticated' && (
|
||||
<>
|
||||
<Dialog open={loginIsOpen} onOpenChange={setLoginIsOpen}>
|
||||
<DialogContent>
|
||||
<LoginFormModal
|
||||
close={() => setLoginIsOpen(false)}
|
||||
openRegisterModal={() => setRegisterIsOpen(true)}
|
||||
openPasswordResetModal={() => setPasswordResetIsOpen(true)}
|
||||
/>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
<Dialog open={registerIsOpen} onOpenChange={setRegisterIsOpen}>
|
||||
<DialogContent>
|
||||
<RegisterFormModal
|
||||
openLoginModal={() => setLoginIsOpen(true)}
|
||||
close={() => setRegisterIsOpen(false)}
|
||||
/>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
<Dialog open={passwordResetIsOpen} onOpenChange={setPasswordResetIsOpen}>
|
||||
<DialogContent>
|
||||
<PasswordResetFormModal close={() => setPasswordResetIsOpen(false)} />
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default Project
|
||||
|
||||
export async function getServerSideProps({ params, resolvedUrl }: GetServerSidePropsContext) {
|
||||
const fundSlug = getFundSlugFromUrlPath(resolvedUrl)
|
||||
|
||||
if (!params?.slug) return {}
|
||||
if (!fundSlug) return {}
|
||||
|
||||
const project = getProjectBySlug(params.slug as string, fundSlug)
|
||||
const content = await markdownToHtml(project.content || '')
|
||||
|
||||
const donationStats = {
|
||||
xmr: {
|
||||
count: project.isFunded ? project.numdonationsxmr : 0,
|
||||
amount: project.isFunded ? project.totaldonationsxmr : 0,
|
||||
fiatAmount: project.isFunded ? project.totaldonationsinfiatxmr : 0,
|
||||
},
|
||||
btc: {
|
||||
count: project.isFunded ? project.numdonationsbtc : 0,
|
||||
amount: project.isFunded ? project.totaldonationsbtc : 0,
|
||||
fiatAmount: project.isFunded ? project.totaldonationsinfiatbtc : 0,
|
||||
},
|
||||
usd: {
|
||||
count: project.isFunded ? project.fiatnumdonations : 0,
|
||||
amount: project.isFunded ? project.fiattotaldonations : 0,
|
||||
fiatAmount: project.isFunded ? project.fiattotaldonationsinfiat : 0,
|
||||
},
|
||||
}
|
||||
|
||||
if (!project.isFunded) {
|
||||
const donations = await prisma.donation.findMany({
|
||||
where: { projectSlug: params.slug as string, fundSlug },
|
||||
})
|
||||
|
||||
donations.forEach((donation) => {
|
||||
if (donation.cryptoCode === 'XMR') {
|
||||
donationStats.xmr.count += 1
|
||||
donationStats.xmr.amount += donation.cryptoAmount
|
||||
donationStats.xmr.fiatAmount += donation.fiatAmount
|
||||
}
|
||||
|
||||
if (donation.cryptoCode === 'BTC') {
|
||||
donationStats.btc.count += 1
|
||||
donationStats.btc.amount += donation.cryptoAmount
|
||||
donationStats.btc.fiatAmount += donation.fiatAmount
|
||||
}
|
||||
|
||||
if (donation.cryptoCode === null) {
|
||||
donationStats.usd.count += 1
|
||||
donationStats.usd.amount += donation.fiatAmount
|
||||
donationStats.usd.fiatAmount += donation.fiatAmount
|
||||
console.log(donation)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
props: {
|
||||
project: {
|
||||
...project,
|
||||
content,
|
||||
},
|
||||
donationStats,
|
||||
},
|
||||
}
|
||||
}
|
||||
64
pages/general/projects/index.tsx
Normal file
64
pages/general/projects/index.tsx
Normal file
@@ -0,0 +1,64 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import type { NextPage } from 'next'
|
||||
import Head from 'next/head'
|
||||
import ProjectCard from '../../../components/ProjectCard'
|
||||
import { ProjectItem } from '../../../utils/types'
|
||||
import { getProjects } from '../../../utils/md'
|
||||
import { useFundSlug } from '../../../utils/use-fund-slug'
|
||||
|
||||
const AllProjects: NextPage<{ projects: ProjectItem[] }> = ({ projects }) => {
|
||||
const [modalOpen, setModalOpen] = useState(false)
|
||||
const [selectedProject, setSelectedProject] = useState<ProjectItem>()
|
||||
const [sortedProjects, setSortedProjects] = useState<ProjectItem[]>()
|
||||
const fundSlug = useFundSlug()
|
||||
|
||||
useEffect(() => {
|
||||
setSortedProjects(projects.sort(() => 0.5 - Math.random()))
|
||||
}, [projects])
|
||||
|
||||
function closeModal() {
|
||||
setModalOpen(false)
|
||||
}
|
||||
|
||||
function openPaymentModal(project: ProjectItem) {
|
||||
setSelectedProject(project)
|
||||
setModalOpen(true)
|
||||
}
|
||||
|
||||
if (!fundSlug) return <></>
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>MAGIC Monero Fund | Projects</title>
|
||||
</Head>
|
||||
<section className="p-4 md:p-8 flex flex-col items-center">
|
||||
<div className="flex justify-between items-center pb-8 w-full">
|
||||
<h1 className="py-4 text-3xl font-extrabold leading-9 tracking-tight text-gray-900 sm:text-4xl sm:leading-10 md:text-6xl md:leading-14">
|
||||
Projects
|
||||
</h1>
|
||||
</div>
|
||||
<ul className="grid md:grid-cols-3 gap-4 max-w-5xl">
|
||||
{sortedProjects &&
|
||||
sortedProjects.map((p, i) => (
|
||||
<li key={i} className="">
|
||||
<ProjectCard project={p} />
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</section>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default AllProjects
|
||||
|
||||
export async function getStaticProps({ params }: { params: any }) {
|
||||
const projects = getProjects('monero')
|
||||
|
||||
return {
|
||||
props: {
|
||||
projects,
|
||||
},
|
||||
}
|
||||
}
|
||||
17
pages/general/submitted.tsx
Normal file
17
pages/general/submitted.tsx
Normal file
@@ -0,0 +1,17 @@
|
||||
import Link from 'next/link'
|
||||
|
||||
export default function Submitted() {
|
||||
return (
|
||||
<div className="flex-1 flex flex-col items-center justify-center gap-4 py-8">
|
||||
<h2>Thank you for your application!</h2>
|
||||
<p>
|
||||
If you have any questions or need a donation receipt, please reach out to{' '}
|
||||
<a href="mailto:info@magicgrants.org">info@magicgrants.org</a>
|
||||
</p>
|
||||
.
|
||||
<p>
|
||||
<Link href="/">Return Home</Link>
|
||||
</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
25
pages/general/thankyou.tsx
Normal file
25
pages/general/thankyou.tsx
Normal file
@@ -0,0 +1,25 @@
|
||||
import Link from 'next/link'
|
||||
import { useFundSlug } from '../../utils/use-fund-slug'
|
||||
import CustomLink from '../../components/CustomLink'
|
||||
import { Button } from '../../components/ui/button'
|
||||
|
||||
export default function ThankYou() {
|
||||
const fundSlug = useFundSlug()
|
||||
return (
|
||||
<div className="flex-1 flex flex-col items-center justify-center gap-4 py-8">
|
||||
<h2 className="font-bold">Thank you for your donation!</h2>
|
||||
<p>
|
||||
If you have any questions, please reach out to{' '}
|
||||
<CustomLink href="mailto:info@magicgrants.org">info@magicgrants.org</CustomLink>
|
||||
</p>
|
||||
|
||||
<br />
|
||||
|
||||
<p>
|
||||
<Button>
|
||||
<Link href={`/${fundSlug}`}>Return Home</Link>
|
||||
</Button>
|
||||
</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -9,7 +9,7 @@ export default Root
|
||||
export function getServerSideProps() {
|
||||
return {
|
||||
redirect: {
|
||||
destination: '/monero',
|
||||
destination: '/general',
|
||||
permanent: true,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ export default function Apply() {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="mx-auto flex-1 flex flex-col items-center justify-center gap-4 py-8 prose dark:prose-dark">
|
||||
<div className="mx-auto flex-1 flex flex-col items-center justify-center gap-4 py-8 prose">
|
||||
<form onSubmit={handleSubmit(onSubmit)} className="max-w-5xl flex flex-col gap-4 p-4">
|
||||
<div>
|
||||
<h1>Application for Monero Fund Project Listing or General Fund Grant</h1>
|
||||
|
||||
@@ -2,6 +2,7 @@ import { useEffect, useState } from 'react'
|
||||
import type { NextPage } from 'next'
|
||||
import Head from 'next/head'
|
||||
import { useSession } from 'next-auth/react'
|
||||
import { useTheme } from 'next-themes'
|
||||
|
||||
import { getProjects } from '../../utils/md'
|
||||
import { ProjectItem } from '../../utils/types'
|
||||
@@ -16,21 +17,9 @@ import LoginFormModal from '../../components/LoginFormModal'
|
||||
import RegisterFormModal from '../../components/RegisterFormModal'
|
||||
import PasswordResetFormModal from '../../components/PasswordResetFormModal'
|
||||
import { trpc } from '../../utils/trpc'
|
||||
import { useFundSlug } from '../../utils/use-fund-slug'
|
||||
import { funds } from '../../utils/funds'
|
||||
|
||||
// These shouldn't be swept up in the regular list so we hardcode them
|
||||
const fund: ProjectItem = {
|
||||
slug: 'monero',
|
||||
nym: 'MagicMonero',
|
||||
website: 'https://monerofund.org',
|
||||
personalWebsite: 'https://monerofund.org',
|
||||
title: 'MAGIC Monero General Fund',
|
||||
summary: 'Support contributors to Monero',
|
||||
coverImage: '/img/crystalball.jpg',
|
||||
git: 'magicgrants',
|
||||
twitter: 'magicgrants',
|
||||
goal: 100000,
|
||||
}
|
||||
const fund = funds['monero']
|
||||
|
||||
const Home: NextPage<{ projects: any }> = ({ projects }) => {
|
||||
const [donateModalOpen, setDonateModalOpen] = useState(false)
|
||||
@@ -39,7 +28,6 @@ const Home: NextPage<{ projects: any }> = ({ projects }) => {
|
||||
const [loginIsOpen, setLoginIsOpen] = useState(false)
|
||||
const [passwordResetIsOpen, setPasswordResetIsOpen] = useState(false)
|
||||
const session = useSession()
|
||||
const fundSlug = useFundSlug()
|
||||
|
||||
const userHasMembershipQuery = trpc.donation.userHasMembership.useQuery(
|
||||
{ projectSlug: fund.slug },
|
||||
@@ -55,27 +43,23 @@ const Home: NextPage<{ projects: any }> = ({ projects }) => {
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>Monero Fund</title>
|
||||
<title>{fund.title}</title>
|
||||
<meta name="description" content="TKTK" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
</Head>
|
||||
|
||||
<div className="divide-y divide-gray-200 dark:divide-gray-700">
|
||||
<div className="divide-y divide-gray-200">
|
||||
<div className="pt-4 md:pb-8">
|
||||
<h1 className="py-4 text-3xl font-extrabold leading-9 tracking-tight text-gray-900 dark:text-gray-100 sm:text-4xl sm:leading-10 md:text-6xl md:leading-14">
|
||||
<h1 className="py-4 text-3xl font-extrabold leading-9 tracking-tight text-gray-900 sm:text-4xl sm:leading-10 md:text-6xl md:leading-14">
|
||||
Support <Typing />
|
||||
</h1>
|
||||
<p className="text-xl leading-7 text-gray-500 dark:text-gray-400">
|
||||
<p className="text-xl leading-7 text-gray-500">
|
||||
Help us to provide sustainable funding for free and open-source contributors working on
|
||||
freedom tech and projects that help Monero flourish.
|
||||
</p>
|
||||
|
||||
<div className="flex flex-wrap space-x-4 py-4">
|
||||
<Button
|
||||
onClick={() => setDonateModalOpen(true)}
|
||||
size="lg"
|
||||
className="px-14 text-black font-semibold text-lg"
|
||||
>
|
||||
<div className="flex flex-wrap py-4 space-x-4">
|
||||
<Button onClick={() => setDonateModalOpen(true)} size="lg">
|
||||
Donate to Monero Comittee General Fund
|
||||
</Button>
|
||||
|
||||
@@ -86,21 +70,16 @@ const Home: NextPage<{ projects: any }> = ({ projects }) => {
|
||||
? setMemberModalOpen(true)
|
||||
: setRegisterIsOpen(true)
|
||||
}
|
||||
variant="outline"
|
||||
variant="light"
|
||||
size="lg"
|
||||
className="px-14 font-semibold text-lg"
|
||||
>
|
||||
Get Annual Membership
|
||||
</Button>
|
||||
)}
|
||||
|
||||
{!!userHasMembershipQuery.data && (
|
||||
<CustomLink href={`/${fundSlug}/account/my-memberships`}>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="lg"
|
||||
className="px-14 font-semibold text-lg text-white"
|
||||
>
|
||||
<CustomLink href={`/${fund.slug}/account/my-memberships`}>
|
||||
<Button variant="light" size="lg">
|
||||
My Memberships
|
||||
</Button>{' '}
|
||||
</CustomLink>
|
||||
@@ -108,32 +87,32 @@ const Home: NextPage<{ projects: any }> = ({ projects }) => {
|
||||
</div>
|
||||
|
||||
<div className="flex flex-row flex-wrap">
|
||||
<p className="text-lg leading-7 text-gray-500 dark:text-gray-400">
|
||||
<p className="text-md leading-7 text-gray-500">
|
||||
Want to receive funding for your work?
|
||||
<CustomLink href={`/${fundSlug}/apply`} className="text-orange-500">
|
||||
<CustomLink href={`/${fund.slug}/apply`}>
|
||||
{' '}
|
||||
Apply for a Monero development or research grant!
|
||||
</CustomLink>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<p className="text-md leading-7 text-gray-500 dark:text-gray-400">
|
||||
<p className="text-sm leading-7 text-gray-400">
|
||||
We are a 501(c)(3) public charity. All donations are tax deductible.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="divide-y divide-gray-200 dark:divide-gray-700">
|
||||
<div className="divide-y divide-gray-200">
|
||||
<div className="xl:pt-18 space-y-2 pt-8 md:space-y-5">
|
||||
<h1 className="text-3xl font-extrabold leading-9 tracking-tight text-gray-900 dark:text-gray-100 sm:text-4xl sm:leading-10 md:text-6xl md:leading-14">
|
||||
<h1 className="text-3xl font-extrabold leading-9 tracking-tight text-gray-900 sm:text-4xl sm:leading-10 md:text-6xl md:leading-14">
|
||||
Explore Projects
|
||||
</h1>
|
||||
<p className="pt-2 text-lg leading-7 text-gray-500 dark:text-gray-400">
|
||||
<p className="pt-2 text-lg leading-7 text-gray-500">
|
||||
Browse through a showcase of projects supported by us.
|
||||
</p>
|
||||
<ProjectList projects={projects} />
|
||||
<div className="flex justify-end pt-4 text-base font-medium leading-6">
|
||||
<CustomLink href={`/${fundSlug}/projects`} aria-label="View All Projects">
|
||||
<CustomLink href={`/${fund.slug}/projects`} aria-label="View All Projects">
|
||||
View Projects →
|
||||
</CustomLink>
|
||||
</div>
|
||||
@@ -187,7 +166,7 @@ const Home: NextPage<{ projects: any }> = ({ projects }) => {
|
||||
export default Home
|
||||
|
||||
export async function getStaticProps({ params }: { params: any }) {
|
||||
const projects = getProjects('monero')
|
||||
const projects = getProjects(fund.slug)
|
||||
|
||||
return {
|
||||
props: {
|
||||
|
||||
@@ -95,7 +95,7 @@ const Project: NextPage<SingleProjectPageProps> = ({ project, donationStats }) =
|
||||
<title>Monero Fund - {project.title}</title>
|
||||
</Head>
|
||||
|
||||
<div className="divide-y divide-gray-200 dark:divide-gray-700">
|
||||
<div className="divide-y divide-gray-200">
|
||||
<PageHeading project={project}>
|
||||
<div className="flex flex-col items-center space-x-2 pt-8 xl:block">
|
||||
<Image
|
||||
@@ -119,7 +119,6 @@ const Project: NextPage<SingleProjectPageProps> = ({ project, donationStats }) =
|
||||
: setRegisterIsOpen(true)
|
||||
}
|
||||
variant="outline"
|
||||
className="text-white"
|
||||
>
|
||||
Get Annual Membership
|
||||
</Button>
|
||||
@@ -127,9 +126,7 @@ const Project: NextPage<SingleProjectPageProps> = ({ project, donationStats }) =
|
||||
|
||||
{!!userHasMembershipQuery.data && (
|
||||
<CustomLink href="/account/my-memberships">
|
||||
<Button variant="outline" className="text-white">
|
||||
My Memberships
|
||||
</Button>{' '}
|
||||
<Button variant="outline">My Memberships</Button>{' '}
|
||||
</CustomLink>
|
||||
)}
|
||||
</div>
|
||||
@@ -178,7 +175,7 @@ const Project: NextPage<SingleProjectPageProps> = ({ project, donationStats }) =
|
||||
</div>
|
||||
|
||||
<article
|
||||
className="prose max-w-none pb-8 pt-8 dark:prose-dark xl:col-span-2"
|
||||
className="prose max-w-none pb-8 pt-8 xl:col-span-2"
|
||||
dangerouslySetInnerHTML={{ __html: xss(content || '') }}
|
||||
/>
|
||||
</PageHeading>
|
||||
|
||||
@@ -34,7 +34,9 @@ const AllProjects: NextPage<{ projects: ProjectItem[] }> = ({ projects }) => {
|
||||
</Head>
|
||||
<section className="p-4 md:p-8 flex flex-col items-center">
|
||||
<div className="flex justify-between items-center pb-8 w-full">
|
||||
<h1>Projects</h1>
|
||||
<h1 className="py-4 text-3xl font-extrabold leading-9 tracking-tight text-gray-900 sm:text-4xl sm:leading-10 md:text-6xl md:leading-14">
|
||||
Projects
|
||||
</h1>
|
||||
</div>
|
||||
<ul className="grid md:grid-cols-3 gap-4 max-w-5xl">
|
||||
{sortedProjects &&
|
||||
|
||||
@@ -1,28 +1,24 @@
|
||||
import Link from 'next/link'
|
||||
import { useFundSlug } from '../../utils/use-fund-slug'
|
||||
import CustomLink from '../../components/CustomLink'
|
||||
import { Button } from '../../components/ui/button'
|
||||
|
||||
export default function ThankYou() {
|
||||
const fundSlug = useFundSlug()
|
||||
return (
|
||||
<div className="flex-1 flex flex-col items-center justify-center gap-4 py-8">
|
||||
<h2>Thank you for your donation!</h2>
|
||||
<h2 className="font-bold">Thank you for your donation!</h2>
|
||||
<p>
|
||||
If you have any questions, please reach out to{' '}
|
||||
<a
|
||||
className="text-primary-500 hover:text-primary-600 dark:hover:text-primary-400"
|
||||
href="mailto:info@magicgrants.org"
|
||||
>
|
||||
info@magicgrants.org
|
||||
</a>
|
||||
<CustomLink href="mailto:info@magicgrants.org">info@magicgrants.org</CustomLink>
|
||||
</p>
|
||||
|
||||
<br />
|
||||
|
||||
<p>
|
||||
<Link
|
||||
className="text-primary-500 hover:text-primary-600 dark:hover:text-primary-400"
|
||||
href="/"
|
||||
>
|
||||
Return Home
|
||||
</Link>
|
||||
<Button>
|
||||
<Link href={`/${fundSlug}`}>Return Home</Link>
|
||||
</Button>
|
||||
</p>
|
||||
</div>
|
||||
)
|
||||
|
||||
290
pages/privacyguides/apply.tsx
Normal file
290
pages/privacyguides/apply.tsx
Normal file
@@ -0,0 +1,290 @@
|
||||
import { useRouter } from 'next/router'
|
||||
import { useState } from 'react'
|
||||
import { useForm } from 'react-hook-form'
|
||||
import Link from 'next/link'
|
||||
|
||||
import { Button } from '../../components/ui/button'
|
||||
|
||||
export default function Apply() {
|
||||
const [loading, setLoading] = useState(false)
|
||||
const router = useRouter()
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
watch,
|
||||
formState: { errors },
|
||||
} = useForm()
|
||||
|
||||
const onSubmit = async (data: any) => {
|
||||
setLoading(true)
|
||||
console.log(data)
|
||||
// TODO: fix dis
|
||||
// const res = await fetchPostJSON('/api/sendgrid', data)
|
||||
// if (res.message === 'success') {
|
||||
// router.push('/submitted')
|
||||
// }
|
||||
// console.log(res)
|
||||
setLoading(false)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="mx-auto flex-1 flex flex-col items-center justify-center gap-4 py-8 prose">
|
||||
<form onSubmit={handleSubmit(onSubmit)} className="max-w-5xl flex flex-col gap-4 p-4">
|
||||
<div>
|
||||
<h1>Application for Monero Fund Project Listing or General Fund Grant</h1>
|
||||
<p>Thanks for your interest in the Monero Fund!</p>
|
||||
<p>
|
||||
We're incredibly grateful to contributors like you working to support Monero,
|
||||
Bitcoin and other free and open source projects.
|
||||
</p>
|
||||
<p>
|
||||
The MAGIC Monero Fund is offering a grant program and fundraising platform to support
|
||||
Monero research and development, especially relating to privacy, security, user
|
||||
experience, and efficiency. Proposals can be related to the Monero protocol directly, or
|
||||
they can be related to other areas of the Monero ecosystem. For research projects,
|
||||
please refer to special instructions
|
||||
<Link href="/apply_research"> here</Link>.
|
||||
</p>
|
||||
<h2>Proposal Evaluation Criteria</h2>
|
||||
<div>
|
||||
Submitted proposals will be evaluated by the committee based on the following criteria:
|
||||
<ul>
|
||||
<li>
|
||||
<b>Impact:</b> The proposal should have a clear impact on the Monero Project.
|
||||
</li>
|
||||
<li>
|
||||
<b>Originality:</b> The proposal should be original and not a rehash of existing
|
||||
work.
|
||||
</li>
|
||||
<li>
|
||||
<b>Feasibility:</b> The proposal should be feasible to complete within the proposed
|
||||
time frame.
|
||||
</li>
|
||||
<li>
|
||||
<b>Quality:</b> The proposal should be well-written and well-organized.
|
||||
</li>
|
||||
<li>
|
||||
<b>Relevance:</b> The proposal should be relevant to the Monero Project.
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<h2 id="Eligibility">Eligibility</h2>
|
||||
<p>
|
||||
All qualified researchers are eligible to apply, regardless of educational attainment or
|
||||
occupation. However, as a nonprofit organization registered under U.S. tax laws, MAGIC
|
||||
Grants is required to comply with certain laws when disbursing funds to grant
|
||||
recipients. Grant recipients must complete a Due Diligence checklist, which are the last
|
||||
two pages of{' '}
|
||||
<a href="https://magicgrants.org/funds/MAGIC%20Fund%20Grant%20Disbursement%20Process%20and%20Requirements.pdf">
|
||||
this document
|
||||
</a>
|
||||
. This includes the collection of your ID and tax information. We will conduct sanctions
|
||||
checks.
|
||||
</p>
|
||||
<h2>How to Submit a Proposal</h2>
|
||||
<p>
|
||||
To submit a proposal, please complete the form below or create an issue on{' '}
|
||||
<a href="https://github.com/MAGICGrants/Monero-Fund/issues/new?assignees=&labels=&template=grant-application.md&title=[Grant+Title]">
|
||||
Github
|
||||
</a>
|
||||
. Applicants are free to use their legal name or a pseudonym at this step, although note
|
||||
the{' '}
|
||||
<a href="#Eligibility">
|
||||
<b>Eligibility</b>
|
||||
</a>{' '}
|
||||
section. You can choose to apply for a direct grant from the MAGIC Monero Fund's
|
||||
General Fund and/or request that your project be listed on MoneroFund.org to raise funds
|
||||
from Monero community members.
|
||||
</p>
|
||||
<p>
|
||||
Please note this form is not considered confidential and is effectively equivalent to a
|
||||
public GitHub issue. In order to reach out privately, please send an email to
|
||||
MoneroFund@magicgrants.org.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<label className="checkbox">
|
||||
<input type="checkbox" {...register('general_fund')} />
|
||||
Apply to receive a grant from the Magic Monero Fund.
|
||||
</label>
|
||||
|
||||
<label className="checkbox">
|
||||
<input type="checkbox" {...register('explore_page')} />
|
||||
Apply for project to be listed on the Monero Fund Donation Page.
|
||||
</label>
|
||||
|
||||
<div className="w-full flex flex-col">
|
||||
<label htmlFor="project_name">Project Name *</label>
|
||||
<input
|
||||
className="appearance-none block w-full text-gray-700 border rounded py-2 px-3 mb-3 leading-tight focus:outline-none focus:ring-0"
|
||||
id="project_name"
|
||||
type="text"
|
||||
{...register('project_name', { required: true })}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="w-full flex flex-col">
|
||||
<label htmlFor="your_name">Your Name or Pseudonym *</label>
|
||||
<input
|
||||
className="appearance-none block w-full text-gray-700 border rounded py-2 px-3 mb-3 leading-tight focus:outline-none focus:ring-0"
|
||||
id="your_name"
|
||||
type="text"
|
||||
{...register('your_name', { required: true })}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="w-full flex flex-col">
|
||||
<label htmlFor="email">Email *</label>
|
||||
<input
|
||||
className="appearance-none block w-full text-gray-700 border rounded py-2 px-3 mb-3 leading-tight focus:outline-none focus:ring-0"
|
||||
id="email"
|
||||
type="text"
|
||||
{...register('email', { required: true })}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="w-full flex flex-col">
|
||||
<label htmlFor="github">Project GitHub (if applicable)</label>
|
||||
<input
|
||||
className="appearance-none block w-full text-gray-700 border rounded py-2 px-3 mb-3 leading-tight focus:outline-none focus:ring-0"
|
||||
id="github"
|
||||
type="text"
|
||||
{...register('github')}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="w-full flex flex-col">
|
||||
<label htmlFor="personal_github">Personal GitHub (if applicable)</label>
|
||||
<input
|
||||
className="appearance-none block w-full text-gray-700 border rounded py-2 px-3 mb-3 leading-tight focus:outline-none focus:ring-0"
|
||||
id="personal_github"
|
||||
type="text"
|
||||
{...register('personal_github')}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="w-full flex flex-col">
|
||||
<label htmlFor="other_contact">Other Contact Details (if applicable)</label>
|
||||
<small>
|
||||
Please list any other relevant contact details you are comfortable sharing in case we
|
||||
need to reach out with questions. These could include github username, twitter username,
|
||||
LinkedIn, Reddit handle, other social media handles, emails, phone numbers, usernames,
|
||||
etc.
|
||||
</small>
|
||||
<textarea
|
||||
className="appearance-none block w-full text-gray-700 border rounded py-2 px-3 mb-3 leading-tight focus:outline-none focus:ring-0"
|
||||
id="other_contact"
|
||||
{...register('other_contact')}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="w-full flex flex-col">
|
||||
<label htmlFor="short_description">Short Project Description *</label>
|
||||
<small>
|
||||
This will be listed on the explore projects page of the Monero Fund website. 2-3
|
||||
sentences.
|
||||
</small>
|
||||
<textarea
|
||||
className="appearance-none block w-full text-gray-700 border rounded py-2 px-3 mb-3 leading-tight focus:outline-none focus:ring-0"
|
||||
id="short_description"
|
||||
{...register('short_description', { required: true })}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="w-full flex flex-col">
|
||||
<label htmlFor="long_description">Long Project Description</label>
|
||||
<small>
|
||||
This will be listed on your personal project page of the Monero Fund website. It can be
|
||||
longer and go into detail about your project.
|
||||
</small>
|
||||
<textarea
|
||||
className="appearance-none block w-full text-gray-700 border rounded py-2 px-3 mb-3 leading-tight focus:outline-none focus:ring-0"
|
||||
id="long_description"
|
||||
{...register('long_description')}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<label className="checkbox">
|
||||
<input type="checkbox" {...register('free_open_source')} />
|
||||
Is the project free and open source?
|
||||
</label>
|
||||
|
||||
<label className="checkbox">
|
||||
<input type="checkbox" {...register('are_you_lead')} />
|
||||
Are you the Project Lead / Lead Contributor
|
||||
</label>
|
||||
|
||||
<div className="w-full flex flex-col">
|
||||
<label htmlFor="other_lead">
|
||||
If someone else, please list the project's Lead Contributor or Maintainer
|
||||
</label>
|
||||
<input
|
||||
className="appearance-none block w-full text-gray-700 border rounded py-2 px-3 mb-3 leading-tight focus:outline-none focus:ring-0"
|
||||
id="other_lead"
|
||||
type="text"
|
||||
{...register('other_lead')}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="w-full flex flex-col">
|
||||
<label htmlFor="potential_impact">Potential Impact *</label>
|
||||
<small>Why is this project important to the Monero community?</small>
|
||||
<textarea
|
||||
className="appearance-none block w-full text-gray-700 border rounded py-2 px-3 mb-3 leading-tight focus:outline-none focus:ring-0"
|
||||
id="potential_impact"
|
||||
{...register('potential_impact', { required: true })}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="w-full flex flex-col">
|
||||
<label htmlFor="timelines">Project Timelines and Potential Milestones *</label>
|
||||
<textarea
|
||||
className="appearance-none block w-full text-gray-700 border rounded py-2 px-3 mb-3 leading-tight focus:outline-none focus:ring-0"
|
||||
id="timelines"
|
||||
{...register('timelines', { required: true })}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="w-full flex flex-col">
|
||||
<label htmlFor="proposed_budget">
|
||||
If you're applying for a grant from the general fund, please submit a proposed
|
||||
budget for the requested amount and how it will be used.
|
||||
</label>
|
||||
<input
|
||||
className="appearance-none block w-full text-gray-700 border rounded py-2 px-3 mb-3 leading-tight focus:outline-none focus:ring-0"
|
||||
id="proposed_budget"
|
||||
type="text"
|
||||
{...register('proposed_budget')}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="w-full flex flex-col">
|
||||
<label htmlFor="bios">Applicant Bios (Optional)</label>
|
||||
<small>List relevant accomplishments.</small>
|
||||
<input
|
||||
className="appearance-none block w-full text-gray-700 border rounded py-2 px-3 mb-3 leading-tight focus:outline-none focus:ring-0"
|
||||
id="bios"
|
||||
type="text"
|
||||
{...register('bios')}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<small>
|
||||
The MAGIC Monero Fund may require each recipient to sign a Grant Agreement before any
|
||||
funds are disbursed. This agreement will set milestones and funds will only be released
|
||||
upon completion of milestones. In order to comply with US regulations, recipients will
|
||||
need to identify themselves to MAGIC, in accordance with US law.
|
||||
</small>
|
||||
|
||||
<Button disabled={loading}>Apply</Button>
|
||||
|
||||
<p>
|
||||
After submitting your application, please allow our team up to three weeks to review your
|
||||
application. Email us at{' '}
|
||||
<a href="mailto:monerofund@magicgrants.org">monerofund@magicgrants.org</a> if you have any
|
||||
questions.
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
176
pages/privacyguides/index.tsx
Normal file
176
pages/privacyguides/index.tsx
Normal file
@@ -0,0 +1,176 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import type { NextPage } from 'next'
|
||||
import Head from 'next/head'
|
||||
import { useSession } from 'next-auth/react'
|
||||
import { useTheme } from 'next-themes'
|
||||
|
||||
import { getProjects } from '../../utils/md'
|
||||
import { ProjectItem } from '../../utils/types'
|
||||
import Typing from '../../components/Typing'
|
||||
import CustomLink from '../../components/CustomLink'
|
||||
import { Button } from '../../components/ui/button'
|
||||
import { Dialog, DialogContent, DialogTrigger } from '../../components/ui/dialog'
|
||||
import DonationFormModal from '../../components/DonationFormModal'
|
||||
import MembershipFormModal from '../../components/MembershipFormModal'
|
||||
import ProjectList from '../../components/ProjectList'
|
||||
import LoginFormModal from '../../components/LoginFormModal'
|
||||
import RegisterFormModal from '../../components/RegisterFormModal'
|
||||
import PasswordResetFormModal from '../../components/PasswordResetFormModal'
|
||||
import { trpc } from '../../utils/trpc'
|
||||
import { funds } from '../../utils/funds'
|
||||
|
||||
const fund = funds['privacyguides']
|
||||
|
||||
const Home: NextPage<{ projects: any }> = ({ projects }) => {
|
||||
const [donateModalOpen, setDonateModalOpen] = useState(false)
|
||||
const [memberModalOpen, setMemberModalOpen] = useState(false)
|
||||
const [registerIsOpen, setRegisterIsOpen] = useState(false)
|
||||
const [loginIsOpen, setLoginIsOpen] = useState(false)
|
||||
const [passwordResetIsOpen, setPasswordResetIsOpen] = useState(false)
|
||||
const session = useSession()
|
||||
|
||||
const userHasMembershipQuery = trpc.donation.userHasMembership.useQuery(
|
||||
{ projectSlug: fund.slug },
|
||||
{ enabled: false }
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
if (session.status === 'authenticated') {
|
||||
userHasMembershipQuery.refetch()
|
||||
}
|
||||
}, [session.status])
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>{fund.title}</title>
|
||||
<meta name="description" content="TKTK" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
</Head>
|
||||
|
||||
<div className="divide-y divide-gray-200">
|
||||
<div className="pt-4 md:pb-8">
|
||||
<h1 className="py-4 text-3xl font-extrabold leading-9 tracking-tight text-gray-900 sm:text-4xl sm:leading-10 md:text-6xl md:leading-14">
|
||||
Support <Typing />
|
||||
</h1>
|
||||
<p className="text-xl leading-7 text-gray-500">
|
||||
Help us to provide sustainable funding for free and open-source contributors working on
|
||||
freedom tech and projects that help Monero flourish.
|
||||
</p>
|
||||
|
||||
<div className="flex flex-wrap py-4 space-x-4">
|
||||
<Button onClick={() => setDonateModalOpen(true)} size="lg">
|
||||
Donate to Monero Comittee General Fund
|
||||
</Button>
|
||||
|
||||
{!userHasMembershipQuery.data && (
|
||||
<Button
|
||||
onClick={() =>
|
||||
session.status === 'authenticated'
|
||||
? setMemberModalOpen(true)
|
||||
: setRegisterIsOpen(true)
|
||||
}
|
||||
variant="light"
|
||||
size="lg"
|
||||
>
|
||||
Get Annual Membership
|
||||
</Button>
|
||||
)}
|
||||
|
||||
{!!userHasMembershipQuery.data && (
|
||||
<CustomLink href={`/${fund.slug}/account/my-memberships`}>
|
||||
<Button variant="light" size="lg">
|
||||
My Memberships
|
||||
</Button>{' '}
|
||||
</CustomLink>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="flex flex-row flex-wrap">
|
||||
<p className="text-md leading-7 text-gray-500">
|
||||
Want to receive funding for your work?
|
||||
<CustomLink href={`/${fund.slug}/apply`}>
|
||||
{' '}
|
||||
Apply for a Monero development or research grant!
|
||||
</CustomLink>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<p className="text-sm leading-7 text-gray-400">
|
||||
We are a 501(c)(3) public charity. All donations are tax deductible.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="divide-y divide-gray-200">
|
||||
<div className="xl:pt-18 space-y-2 pt-8 md:space-y-5">
|
||||
<h1 className="text-3xl font-extrabold leading-9 tracking-tight text-gray-900 sm:text-4xl sm:leading-10 md:text-6xl md:leading-14">
|
||||
Explore Projects
|
||||
</h1>
|
||||
<p className="pt-2 text-lg leading-7 text-gray-500">
|
||||
Browse through a showcase of projects supported by us.
|
||||
</p>
|
||||
<ProjectList projects={projects} />
|
||||
<div className="flex justify-end pt-4 text-base font-medium leading-6">
|
||||
<CustomLink href={`/${fund.slug}/projects`} aria-label="View All Projects">
|
||||
View Projects →
|
||||
</CustomLink>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Dialog open={donateModalOpen} onOpenChange={setDonateModalOpen}>
|
||||
<DialogContent>
|
||||
<DonationFormModal project={fund} />
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
<Dialog open={memberModalOpen} onOpenChange={setMemberModalOpen}>
|
||||
<DialogContent>
|
||||
<MembershipFormModal project={fund} />
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
{session.status !== 'authenticated' && (
|
||||
<>
|
||||
<Dialog open={loginIsOpen} onOpenChange={setLoginIsOpen}>
|
||||
<DialogContent>
|
||||
<LoginFormModal
|
||||
close={() => setLoginIsOpen(false)}
|
||||
openRegisterModal={() => setRegisterIsOpen(true)}
|
||||
openPasswordResetModal={() => setPasswordResetIsOpen(true)}
|
||||
/>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
<Dialog open={registerIsOpen} onOpenChange={setRegisterIsOpen}>
|
||||
<DialogContent>
|
||||
<RegisterFormModal
|
||||
openLoginModal={() => setLoginIsOpen(true)}
|
||||
close={() => setRegisterIsOpen(false)}
|
||||
/>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
<Dialog open={passwordResetIsOpen} onOpenChange={setPasswordResetIsOpen}>
|
||||
<DialogContent>
|
||||
<PasswordResetFormModal close={() => setPasswordResetIsOpen(false)} />
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default Home
|
||||
|
||||
export async function getStaticProps({ params }: { params: any }) {
|
||||
const projects = getProjects(fund.slug)
|
||||
|
||||
return {
|
||||
props: {
|
||||
projects,
|
||||
},
|
||||
}
|
||||
}
|
||||
293
pages/privacyguides/projects/[slug].tsx
Normal file
293
pages/privacyguides/projects/[slug].tsx
Normal file
@@ -0,0 +1,293 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useSession } from 'next-auth/react'
|
||||
import { useRouter } from 'next/router'
|
||||
import { GetServerSidePropsContext, NextPage } from 'next/types'
|
||||
import Head from 'next/head'
|
||||
import ErrorPage from 'next/error'
|
||||
import Image from 'next/image'
|
||||
import xss from 'xss'
|
||||
|
||||
import { ProjectDonationStats, ProjectItem } from '../../../utils/types'
|
||||
import { getProjectBySlug } from '../../../utils/md'
|
||||
import markdownToHtml from '../../../utils/markdownToHtml'
|
||||
import PageHeading from '../../../components/PageHeading'
|
||||
import Progress from '../../../components/Progress'
|
||||
import { prisma } from '../../../server/services'
|
||||
import { Button } from '../../../components/ui/button'
|
||||
import { Dialog, DialogContent } from '../../../components/ui/dialog'
|
||||
import DonationFormModal from '../../../components/DonationFormModal'
|
||||
import MembershipFormModal from '../../../components/MembershipFormModal'
|
||||
import LoginFormModal from '../../../components/LoginFormModal'
|
||||
import RegisterFormModal from '../../../components/RegisterFormModal'
|
||||
import PasswordResetFormModal from '../../../components/PasswordResetFormModal'
|
||||
import CustomLink from '../../../components/CustomLink'
|
||||
import { trpc } from '../../../utils/trpc'
|
||||
import { getFundSlugFromUrlPath } from '../../../utils/funds'
|
||||
|
||||
type SingleProjectPageProps = {
|
||||
project: ProjectItem
|
||||
projects: ProjectItem[]
|
||||
donationStats: ProjectDonationStats
|
||||
}
|
||||
|
||||
const Project: NextPage<SingleProjectPageProps> = ({ project, donationStats }) => {
|
||||
const router = useRouter()
|
||||
const [donateModalOpen, setDonateModalOpen] = useState(false)
|
||||
const [memberModalOpen, setMemberModalOpen] = useState(false)
|
||||
const [registerIsOpen, setRegisterIsOpen] = useState(false)
|
||||
const [loginIsOpen, setLoginIsOpen] = useState(false)
|
||||
const [passwordResetIsOpen, setPasswordResetIsOpen] = useState(false)
|
||||
const session = useSession()
|
||||
|
||||
const userHasMembershipQuery = trpc.donation.userHasMembership.useQuery(
|
||||
{ projectSlug: project.slug },
|
||||
{ enabled: false }
|
||||
)
|
||||
|
||||
const {
|
||||
slug,
|
||||
title,
|
||||
summary,
|
||||
coverImage,
|
||||
git,
|
||||
twitter,
|
||||
content,
|
||||
nym,
|
||||
website,
|
||||
personalTwitter,
|
||||
personalWebsite,
|
||||
goal,
|
||||
isFunded,
|
||||
} = project
|
||||
|
||||
function formatBtc(bitcoin: number) {
|
||||
if (bitcoin > 0.1) {
|
||||
return `${bitcoin.toFixed(3) || 0.0} BTC`
|
||||
} else {
|
||||
return `${Math.floor(bitcoin * 100000000).toLocaleString()} sats`
|
||||
}
|
||||
}
|
||||
|
||||
function formatUsd(dollars: number): string {
|
||||
if (dollars == 0) {
|
||||
return '$0'
|
||||
} else if (dollars / 1000 > 1) {
|
||||
return `$${Math.round(dollars / 1000)}k+`
|
||||
} else {
|
||||
return `$${dollars.toFixed(0)}`
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (session.status === 'authenticated') {
|
||||
console.log('refetching')
|
||||
userHasMembershipQuery.refetch()
|
||||
}
|
||||
}, [session.status])
|
||||
|
||||
if (!router.isFallback && !slug) {
|
||||
return <ErrorPage statusCode={404} />
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>Monero Fund - {project.title}</title>
|
||||
</Head>
|
||||
|
||||
<div className="divide-y divide-gray-200">
|
||||
<PageHeading project={project}>
|
||||
<div className="flex flex-col items-center space-x-2 pt-8 xl:block">
|
||||
<Image
|
||||
src={coverImage}
|
||||
alt="avatar"
|
||||
width={300}
|
||||
height={300}
|
||||
className="h-72 w-72 mx-auto object-contain xl:hidden"
|
||||
/>
|
||||
|
||||
<div className="space-y-4">
|
||||
{!project.isFunded && (
|
||||
<div className="flex flex-col space-y-2">
|
||||
<Button onClick={() => setDonateModalOpen(true)}>Donate</Button>
|
||||
|
||||
{!userHasMembershipQuery.data && (
|
||||
<Button
|
||||
onClick={() =>
|
||||
session.status === 'authenticated'
|
||||
? setMemberModalOpen(true)
|
||||
: setRegisterIsOpen(true)
|
||||
}
|
||||
variant="outline"
|
||||
>
|
||||
Get Annual Membership
|
||||
</Button>
|
||||
)}
|
||||
|
||||
{!!userHasMembershipQuery.data && (
|
||||
<CustomLink href="/account/my-memberships">
|
||||
<Button variant="outline">My Memberships</Button>{' '}
|
||||
</CustomLink>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<h1 className="mb-4 font-bold">Raised</h1>
|
||||
|
||||
<Progress
|
||||
percent={Math.floor(
|
||||
((donationStats.xmr.fiatAmount +
|
||||
donationStats.btc.fiatAmount +
|
||||
donationStats.usd.fiatAmount) /
|
||||
goal) *
|
||||
100
|
||||
)}
|
||||
/>
|
||||
|
||||
<ul className="font-semibold space-y-1">
|
||||
<li className="flex items-center space-x-1">
|
||||
<span className="text-green-500 text-xl">{`${formatUsd(donationStats.xmr.fiatAmount + donationStats.btc.fiatAmount + donationStats.usd.fiatAmount)}`}</span>{' '}
|
||||
<span className="font-normal text-sm text-gray">
|
||||
in {donationStats.xmr.count + donationStats.btc.count + donationStats.usd.count}{' '}
|
||||
donations total
|
||||
</span>
|
||||
</li>
|
||||
<li>
|
||||
{donationStats.xmr.amount} XMR{' '}
|
||||
<span className="font-normal text-sm text-gray">
|
||||
in {donationStats.xmr.count} donations
|
||||
</span>
|
||||
</li>
|
||||
<li>
|
||||
{formatBtc(donationStats.btc.amount)}{' '}
|
||||
<span className="font-normal text-sm text-gray">
|
||||
in {donationStats.btc.count} donations
|
||||
</span>
|
||||
</li>
|
||||
<li>
|
||||
{`${formatUsd(donationStats.usd.amount)}`} Fiat{' '}
|
||||
<span className="font-normal text-sm text-gray">
|
||||
in {donationStats.usd.count} donations
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<article
|
||||
className="prose max-w-none pb-8 pt-8 xl:col-span-2"
|
||||
dangerouslySetInnerHTML={{ __html: xss(content || '') }}
|
||||
/>
|
||||
</PageHeading>
|
||||
</div>
|
||||
|
||||
<Dialog open={donateModalOpen} onOpenChange={setDonateModalOpen}>
|
||||
<DialogContent>
|
||||
<DonationFormModal project={project} />
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
<Dialog open={memberModalOpen} onOpenChange={setMemberModalOpen}>
|
||||
<DialogContent>
|
||||
<MembershipFormModal project={project} />
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
{session.status !== 'authenticated' && (
|
||||
<>
|
||||
<Dialog open={loginIsOpen} onOpenChange={setLoginIsOpen}>
|
||||
<DialogContent>
|
||||
<LoginFormModal
|
||||
close={() => setLoginIsOpen(false)}
|
||||
openRegisterModal={() => setRegisterIsOpen(true)}
|
||||
openPasswordResetModal={() => setPasswordResetIsOpen(true)}
|
||||
/>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
<Dialog open={registerIsOpen} onOpenChange={setRegisterIsOpen}>
|
||||
<DialogContent>
|
||||
<RegisterFormModal
|
||||
openLoginModal={() => setLoginIsOpen(true)}
|
||||
close={() => setRegisterIsOpen(false)}
|
||||
/>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
<Dialog open={passwordResetIsOpen} onOpenChange={setPasswordResetIsOpen}>
|
||||
<DialogContent>
|
||||
<PasswordResetFormModal close={() => setPasswordResetIsOpen(false)} />
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default Project
|
||||
|
||||
export async function getServerSideProps({ params, resolvedUrl }: GetServerSidePropsContext) {
|
||||
const fundSlug = getFundSlugFromUrlPath(resolvedUrl)
|
||||
|
||||
if (!params?.slug) return {}
|
||||
if (!fundSlug) return {}
|
||||
|
||||
const project = getProjectBySlug(params.slug as string, fundSlug)
|
||||
const content = await markdownToHtml(project.content || '')
|
||||
|
||||
const donationStats = {
|
||||
xmr: {
|
||||
count: project.isFunded ? project.numdonationsxmr : 0,
|
||||
amount: project.isFunded ? project.totaldonationsxmr : 0,
|
||||
fiatAmount: project.isFunded ? project.totaldonationsinfiatxmr : 0,
|
||||
},
|
||||
btc: {
|
||||
count: project.isFunded ? project.numdonationsbtc : 0,
|
||||
amount: project.isFunded ? project.totaldonationsbtc : 0,
|
||||
fiatAmount: project.isFunded ? project.totaldonationsinfiatbtc : 0,
|
||||
},
|
||||
usd: {
|
||||
count: project.isFunded ? project.fiatnumdonations : 0,
|
||||
amount: project.isFunded ? project.fiattotaldonations : 0,
|
||||
fiatAmount: project.isFunded ? project.fiattotaldonationsinfiat : 0,
|
||||
},
|
||||
}
|
||||
|
||||
if (!project.isFunded) {
|
||||
const donations = await prisma.donation.findMany({
|
||||
where: { projectSlug: params.slug as string, fundSlug },
|
||||
})
|
||||
|
||||
donations.forEach((donation) => {
|
||||
if (donation.cryptoCode === 'XMR') {
|
||||
donationStats.xmr.count += 1
|
||||
donationStats.xmr.amount += donation.cryptoAmount
|
||||
donationStats.xmr.fiatAmount += donation.fiatAmount
|
||||
}
|
||||
|
||||
if (donation.cryptoCode === 'BTC') {
|
||||
donationStats.btc.count += 1
|
||||
donationStats.btc.amount += donation.cryptoAmount
|
||||
donationStats.btc.fiatAmount += donation.fiatAmount
|
||||
}
|
||||
|
||||
if (donation.cryptoCode === null) {
|
||||
donationStats.usd.count += 1
|
||||
donationStats.usd.amount += donation.fiatAmount
|
||||
donationStats.usd.fiatAmount += donation.fiatAmount
|
||||
console.log(donation)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
props: {
|
||||
project: {
|
||||
...project,
|
||||
content,
|
||||
},
|
||||
donationStats,
|
||||
},
|
||||
}
|
||||
}
|
||||
64
pages/privacyguides/projects/index.tsx
Normal file
64
pages/privacyguides/projects/index.tsx
Normal file
@@ -0,0 +1,64 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import type { NextPage } from 'next'
|
||||
import Head from 'next/head'
|
||||
import ProjectCard from '../../../components/ProjectCard'
|
||||
import { ProjectItem } from '../../../utils/types'
|
||||
import { getProjects } from '../../../utils/md'
|
||||
import { useFundSlug } from '../../../utils/use-fund-slug'
|
||||
|
||||
const AllProjects: NextPage<{ projects: ProjectItem[] }> = ({ projects }) => {
|
||||
const [modalOpen, setModalOpen] = useState(false)
|
||||
const [selectedProject, setSelectedProject] = useState<ProjectItem>()
|
||||
const [sortedProjects, setSortedProjects] = useState<ProjectItem[]>()
|
||||
const fundSlug = useFundSlug()
|
||||
|
||||
useEffect(() => {
|
||||
setSortedProjects(projects.sort(() => 0.5 - Math.random()))
|
||||
}, [projects])
|
||||
|
||||
function closeModal() {
|
||||
setModalOpen(false)
|
||||
}
|
||||
|
||||
function openPaymentModal(project: ProjectItem) {
|
||||
setSelectedProject(project)
|
||||
setModalOpen(true)
|
||||
}
|
||||
|
||||
if (!fundSlug) return <></>
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>MAGIC Monero Fund | Projects</title>
|
||||
</Head>
|
||||
<section className="p-4 md:p-8 flex flex-col items-center">
|
||||
<div className="flex justify-between items-center pb-8 w-full">
|
||||
<h1 className="py-4 text-3xl font-extrabold leading-9 tracking-tight text-gray-900 sm:text-4xl sm:leading-10 md:text-6xl md:leading-14">
|
||||
Projects
|
||||
</h1>
|
||||
</div>
|
||||
<ul className="grid md:grid-cols-3 gap-4 max-w-5xl">
|
||||
{sortedProjects &&
|
||||
sortedProjects.map((p, i) => (
|
||||
<li key={i} className="">
|
||||
<ProjectCard project={p} />
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</section>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default AllProjects
|
||||
|
||||
export async function getStaticProps({ params }: { params: any }) {
|
||||
const projects = getProjects('monero')
|
||||
|
||||
return {
|
||||
props: {
|
||||
projects,
|
||||
},
|
||||
}
|
||||
}
|
||||
17
pages/privacyguides/submitted.tsx
Normal file
17
pages/privacyguides/submitted.tsx
Normal file
@@ -0,0 +1,17 @@
|
||||
import Link from 'next/link'
|
||||
|
||||
export default function Submitted() {
|
||||
return (
|
||||
<div className="flex-1 flex flex-col items-center justify-center gap-4 py-8">
|
||||
<h2>Thank you for your application!</h2>
|
||||
<p>
|
||||
If you have any questions or need a donation receipt, please reach out to{' '}
|
||||
<a href="mailto:info@magicgrants.org">info@magicgrants.org</a>
|
||||
</p>
|
||||
.
|
||||
<p>
|
||||
<Link href="/">Return Home</Link>
|
||||
</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
25
pages/privacyguides/thankyou.tsx
Normal file
25
pages/privacyguides/thankyou.tsx
Normal file
@@ -0,0 +1,25 @@
|
||||
import Link from 'next/link'
|
||||
import { useFundSlug } from '../../utils/use-fund-slug'
|
||||
import CustomLink from '../../components/CustomLink'
|
||||
import { Button } from '../../components/ui/button'
|
||||
|
||||
export default function ThankYou() {
|
||||
const fundSlug = useFundSlug()
|
||||
return (
|
||||
<div className="flex-1 flex flex-col items-center justify-center gap-4 py-8">
|
||||
<h2 className="font-bold">Thank you for your donation!</h2>
|
||||
<p>
|
||||
If you have any questions, please reach out to{' '}
|
||||
<CustomLink href="mailto:info@magicgrants.org">info@magicgrants.org</CustomLink>
|
||||
</p>
|
||||
|
||||
<br />
|
||||
|
||||
<p>
|
||||
<Button>
|
||||
<Link href={`/${fundSlug}`}>Return Home</Link>
|
||||
</Button>
|
||||
</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
-- CreateEnum
|
||||
CREATE TYPE "FundSlug" AS ENUM ('monero', 'firo', 'privacy_guides', 'general');
|
||||
CREATE TYPE "FundSlug" AS ENUM ('monero', 'firo', 'privacyguides', 'general');
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Donation" (
|
||||
@@ -39,6 +39,6 @@ model Donation {
|
||||
enum FundSlug {
|
||||
monero
|
||||
firo
|
||||
privacy_guides
|
||||
privacyguides
|
||||
general
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"id": "69206f5b-3557-4d79-aa26-e42faeaa6004",
|
||||
"realm": "monerofund",
|
||||
"realm": "magicgrants",
|
||||
"notBefore": 0,
|
||||
"defaultSignatureAlgorithm": "RS256",
|
||||
"revokeRefreshToken": false,
|
||||
@@ -46,15 +46,13 @@
|
||||
"failureFactor": 30,
|
||||
"defaultRole": {
|
||||
"id": "8da73bcf-9240-4091-9c16-10e94eb64504",
|
||||
"name": "default-roles-monerofund",
|
||||
"name": "default-roles-magicgrants",
|
||||
"description": "${role_default-roles}",
|
||||
"composite": true,
|
||||
"clientRole": false,
|
||||
"containerId": "69206f5b-3557-4d79-aa26-e42faeaa6004"
|
||||
},
|
||||
"requiredCredentials": [
|
||||
"password"
|
||||
],
|
||||
"requiredCredentials": ["password"],
|
||||
"otpPolicyType": "totp",
|
||||
"otpPolicyAlgorithm": "HmacSHA1",
|
||||
"otpPolicyInitialCounter": 0,
|
||||
@@ -69,9 +67,7 @@
|
||||
],
|
||||
"localizationTexts": {},
|
||||
"webAuthnPolicyRpEntityName": "keycloak",
|
||||
"webAuthnPolicySignatureAlgorithms": [
|
||||
"ES256"
|
||||
],
|
||||
"webAuthnPolicySignatureAlgorithms": ["ES256"],
|
||||
"webAuthnPolicyRpId": "",
|
||||
"webAuthnPolicyAttestationConveyancePreference": "not specified",
|
||||
"webAuthnPolicyAuthenticatorAttachment": "not specified",
|
||||
@@ -82,9 +78,7 @@
|
||||
"webAuthnPolicyAcceptableAaguids": [],
|
||||
"webAuthnPolicyExtraOrigins": [],
|
||||
"webAuthnPolicyPasswordlessRpEntityName": "keycloak",
|
||||
"webAuthnPolicyPasswordlessSignatureAlgorithms": [
|
||||
"ES256"
|
||||
],
|
||||
"webAuthnPolicyPasswordlessSignatureAlgorithms": ["ES256"],
|
||||
"webAuthnPolicyPasswordlessRpId": "",
|
||||
"webAuthnPolicyPasswordlessAttestationConveyancePreference": "not specified",
|
||||
"webAuthnPolicyPasswordlessAuthenticatorAttachment": "not specified",
|
||||
@@ -97,9 +91,7 @@
|
||||
"scopeMappings": [
|
||||
{
|
||||
"clientScope": "offline_access",
|
||||
"roles": [
|
||||
"offline_access"
|
||||
]
|
||||
"roles": ["offline_access"]
|
||||
}
|
||||
],
|
||||
"clientScopes": [
|
||||
@@ -640,20 +632,8 @@
|
||||
]
|
||||
}
|
||||
],
|
||||
"defaultDefaultClientScopes": [
|
||||
"role_list",
|
||||
"profile",
|
||||
"email",
|
||||
"roles",
|
||||
"web-origins",
|
||||
"acr"
|
||||
],
|
||||
"defaultOptionalClientScopes": [
|
||||
"offline_access",
|
||||
"address",
|
||||
"phone",
|
||||
"microprofile-jwt"
|
||||
],
|
||||
"defaultDefaultClientScopes": ["role_list", "profile", "email", "roles", "web-origins", "acr"],
|
||||
"defaultOptionalClientScopes": ["offline_access", "address", "phone", "microprofile-jwt"],
|
||||
"browserSecurityHeaders": {
|
||||
"contentSecurityPolicyReportOnly": "",
|
||||
"xContentTypeOptions": "nosniff",
|
||||
@@ -666,9 +646,7 @@
|
||||
},
|
||||
"smtpServer": {},
|
||||
"eventsEnabled": false,
|
||||
"eventsListeners": [
|
||||
"jboss-logging"
|
||||
],
|
||||
"eventsListeners": ["jboss-logging"],
|
||||
"enabledEventTypes": [],
|
||||
"adminEventsEnabled": false,
|
||||
"adminEventsDetailsEnabled": false,
|
||||
@@ -683,9 +661,7 @@
|
||||
"subType": "anonymous",
|
||||
"subComponents": {},
|
||||
"config": {
|
||||
"max-clients": [
|
||||
"200"
|
||||
]
|
||||
"max-clients": ["200"]
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -730,9 +706,7 @@
|
||||
"subType": "anonymous",
|
||||
"subComponents": {},
|
||||
"config": {
|
||||
"allow-default-scopes": [
|
||||
"true"
|
||||
]
|
||||
"allow-default-scopes": ["true"]
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -742,12 +716,8 @@
|
||||
"subType": "anonymous",
|
||||
"subComponents": {},
|
||||
"config": {
|
||||
"host-sending-registration-request-must-match": [
|
||||
"true"
|
||||
],
|
||||
"client-uris-must-match": [
|
||||
"true"
|
||||
]
|
||||
"host-sending-registration-request-must-match": ["true"],
|
||||
"client-uris-must-match": ["true"]
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -776,9 +746,7 @@
|
||||
"subType": "authenticated",
|
||||
"subComponents": {},
|
||||
"config": {
|
||||
"allow-default-scopes": [
|
||||
"true"
|
||||
]
|
||||
"allow-default-scopes": ["true"]
|
||||
}
|
||||
}
|
||||
],
|
||||
@@ -801,12 +769,8 @@
|
||||
"providerId": "rsa-enc-generated",
|
||||
"subComponents": {},
|
||||
"config": {
|
||||
"priority": [
|
||||
"100"
|
||||
],
|
||||
"algorithm": [
|
||||
"RSA-OAEP"
|
||||
]
|
||||
"priority": ["100"],
|
||||
"algorithm": ["RSA-OAEP"]
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -815,9 +779,7 @@
|
||||
"providerId": "aes-generated",
|
||||
"subComponents": {},
|
||||
"config": {
|
||||
"priority": [
|
||||
"100"
|
||||
]
|
||||
"priority": ["100"]
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -826,9 +788,7 @@
|
||||
"providerId": "rsa-generated",
|
||||
"subComponents": {},
|
||||
"config": {
|
||||
"priority": [
|
||||
"100"
|
||||
]
|
||||
"priority": ["100"]
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -837,12 +797,8 @@
|
||||
"providerId": "hmac-generated",
|
||||
"subComponents": {},
|
||||
"config": {
|
||||
"priority": [
|
||||
"100"
|
||||
],
|
||||
"algorithm": [
|
||||
"HS512"
|
||||
]
|
||||
"priority": ["100"],
|
||||
"algorithm": ["HS512"]
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -1516,4 +1472,4 @@
|
||||
"clientPolicies": {
|
||||
"policies": []
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import { publicProcedure, router } from '../trpc'
|
||||
import { authenticateKeycloakClient } from '../utils/keycloak'
|
||||
import { keycloak, transporter } from '../services'
|
||||
import { env } from '../../env.mjs'
|
||||
import { fundSlugs } from '../../utils/funds'
|
||||
|
||||
type EmailVerifyJwtPayload = {
|
||||
action: 'email_verify'
|
||||
@@ -27,6 +28,7 @@ export const authRouter = router({
|
||||
name: z.string().trim().min(1),
|
||||
email: z.string().email(),
|
||||
password: z.string(),
|
||||
fundSlug: z.enum(fundSlugs),
|
||||
})
|
||||
)
|
||||
.mutation(async ({ input }) => {
|
||||
@@ -36,20 +38,15 @@ export const authRouter = router({
|
||||
|
||||
try {
|
||||
user = await keycloak.users.create({
|
||||
realm: 'monerofund',
|
||||
realm: env.KEYCLOAK_REALM_NAME,
|
||||
email: input.email,
|
||||
credentials: [
|
||||
{ type: 'password', value: input.password, temporary: false },
|
||||
],
|
||||
credentials: [{ type: 'password', value: input.password, temporary: false }],
|
||||
requiredActions: ['VERIFY_EMAIL'],
|
||||
attributes: { name: input.name, passwordResetTokenVersion: 1 },
|
||||
enabled: true,
|
||||
})
|
||||
} catch (error) {
|
||||
if (
|
||||
(error as any).responseData.errorMessage ===
|
||||
'User exists with same email'
|
||||
) {
|
||||
if ((error as any).responseData.errorMessage === 'User exists with same email') {
|
||||
throw new TRPCError({ code: 'BAD_REQUEST', message: 'EMAIL_TAKEN' })
|
||||
}
|
||||
|
||||
@@ -71,7 +68,7 @@ export const authRouter = router({
|
||||
from: env.SENDGRID_VERIFIED_SENDER,
|
||||
to: input.email,
|
||||
subject: 'Verify your email',
|
||||
html: `<a href="${env.APP_URL}/verify-email/${emailVerifyToken}" target="_blank">Verify email</a>`,
|
||||
html: `<a href="${env.APP_URL}/${input.fundSlug}/verify-email/${emailVerifyToken}" target="_blank">Verify email</a>`,
|
||||
})
|
||||
}),
|
||||
|
||||
@@ -81,10 +78,7 @@ export const authRouter = router({
|
||||
let decoded: EmailVerifyJwtPayload
|
||||
|
||||
try {
|
||||
decoded = jwt.verify(
|
||||
input.token,
|
||||
env.NEXTAUTH_SECRET
|
||||
) as EmailVerifyJwtPayload
|
||||
decoded = jwt.verify(input.token, env.NEXTAUTH_SECRET) as EmailVerifyJwtPayload
|
||||
} catch (error) {
|
||||
throw new TRPCError({
|
||||
code: 'FORBIDDEN',
|
||||
@@ -126,9 +120,7 @@ export const authRouter = router({
|
||||
parseInt(user.attributes.passwordResetTokenVersion?.[0]) || null
|
||||
|
||||
if (!passwordResetTokenVersion) {
|
||||
console.error(
|
||||
`User ${user.id} has no passwordResetTokenVersion attribute`
|
||||
)
|
||||
console.error(`User ${user.id} has no passwordResetTokenVersion attribute`)
|
||||
|
||||
throw new TRPCError({
|
||||
code: 'INTERNAL_SERVER_ERROR',
|
||||
@@ -161,10 +153,7 @@ export const authRouter = router({
|
||||
let decoded: PasswordResetJwtPayload
|
||||
|
||||
try {
|
||||
decoded = jwt.verify(
|
||||
input.token,
|
||||
env.NEXTAUTH_SECRET
|
||||
) as PasswordResetJwtPayload
|
||||
decoded = jwt.verify(input.token, env.NEXTAUTH_SECRET) as PasswordResetJwtPayload
|
||||
} catch (error) {
|
||||
throw new TRPCError({
|
||||
code: 'FORBIDDEN',
|
||||
@@ -192,9 +181,7 @@ export const authRouter = router({
|
||||
parseInt(user.attributes.passwordResetTokenVersion?.[0]) || null
|
||||
|
||||
if (!passwordResetTokenVersion) {
|
||||
console.error(
|
||||
`User ${user.id} has no passwordResetTokenVersion attribute`
|
||||
)
|
||||
console.error(`User ${user.id} has no passwordResetTokenVersion attribute`)
|
||||
|
||||
throw new TRPCError({
|
||||
code: 'INTERNAL_SERVER_ERROR',
|
||||
@@ -211,13 +198,9 @@ export const authRouter = router({
|
||||
{ id: decoded.userId },
|
||||
{
|
||||
email: decoded.email,
|
||||
credentials: [
|
||||
{ type: 'password', value: input.password, temporary: false },
|
||||
],
|
||||
credentials: [{ type: 'password', value: input.password, temporary: false }],
|
||||
attributes: {
|
||||
passwordResetTokenVersion: (
|
||||
passwordResetTokenVersion + 1
|
||||
).toString(),
|
||||
passwordResetTokenVersion: (passwordResetTokenVersion + 1).toString(),
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
@@ -9,7 +9,8 @@ import { env } from '../../env.mjs'
|
||||
import { btcpayApi as _btcpayApi, keycloak, prisma, stripe as _stripe } from '../services'
|
||||
import { authenticateKeycloakClient } from '../utils/keycloak'
|
||||
import { DonationMetadata } from '../types'
|
||||
import { btcpayFundSlugToStoreId, fundSlugs } from '../../utils/funds'
|
||||
import { fundSlugs } from '../../utils/funds'
|
||||
import { fundSlugToCustomerIdAttr } from '../utils/funds'
|
||||
|
||||
export const donationRouter = router({
|
||||
donateWithFiat: publicProcedure
|
||||
@@ -34,7 +35,7 @@ export const donationRouter = router({
|
||||
const user = await keycloak.users.findOne({ id: userId })!
|
||||
email = user?.email!
|
||||
name = user?.attributes?.name?.[0]
|
||||
stripeCustomerId = user?.attributes?.fundSlugToCustomerIdAttr[input.fundSlug]?.[0] || null
|
||||
stripeCustomerId = user?.attributes?.[fundSlugToCustomerIdAttr[input.fundSlug]]?.[0] || null
|
||||
}
|
||||
|
||||
const stripe = _stripe[input.fundSlug]
|
||||
@@ -82,7 +83,7 @@ export const donationRouter = router({
|
||||
},
|
||||
],
|
||||
metadata,
|
||||
success_url: `${env.APP_URL}/thankyou`,
|
||||
success_url: `${env.APP_URL}/${input.fundSlug}/thankyou`,
|
||||
cancel_url: `${env.APP_URL}/`,
|
||||
// We need metadata in here for some reason
|
||||
payment_intent_data: { metadata },
|
||||
@@ -133,7 +134,7 @@ export const donationRouter = router({
|
||||
amount: input.amount,
|
||||
currency: CURRENCY,
|
||||
metadata,
|
||||
checkout: { redirectURL: `${env.APP_URL}/thankyou` },
|
||||
checkout: { redirectURL: `${env.APP_URL}/${input.fundSlug}/thankyou` },
|
||||
})
|
||||
|
||||
return { url: response.data.checkoutLink }
|
||||
@@ -171,7 +172,8 @@ export const donationRouter = router({
|
||||
const user = await keycloak.users.findOne({ id: userId })
|
||||
const email = user?.email!
|
||||
const name = user?.attributes?.name?.[0]!
|
||||
let stripeCustomerId = user?.attributes?.fundSlugToCustomerIdAttr[input.fundSlug]?.[0] || null
|
||||
let stripeCustomerId =
|
||||
user?.attributes?.[fundSlugToCustomerIdAttr[input.fundSlug]]?.[0] || null
|
||||
|
||||
if (!stripeCustomerId) {
|
||||
const customer = await stripe.customers.create({ email, name })
|
||||
@@ -213,7 +215,7 @@ export const donationRouter = router({
|
||||
},
|
||||
],
|
||||
metadata,
|
||||
success_url: `${env.APP_URL}/thankyou`,
|
||||
success_url: `${env.APP_URL}/${input.fundSlug}/thankyou`,
|
||||
cancel_url: `${env.APP_URL}/`,
|
||||
payment_intent_data: { metadata },
|
||||
}
|
||||
@@ -236,7 +238,7 @@ export const donationRouter = router({
|
||||
},
|
||||
],
|
||||
metadata,
|
||||
success_url: `${env.APP_URL}/thankyou`,
|
||||
success_url: `${env.APP_URL}/${input.fundSlug}/thankyou`,
|
||||
cancel_url: `${env.APP_URL}/`,
|
||||
subscription_data: { metadata },
|
||||
}
|
||||
@@ -296,7 +298,7 @@ export const donationRouter = router({
|
||||
amount: MEMBERSHIP_PRICE,
|
||||
currency: CURRENCY,
|
||||
metadata,
|
||||
checkout: { redirectURL: `${env.APP_URL}/thankyou` },
|
||||
checkout: { redirectURL: `${env.APP_URL}/${input.fundSlug}/thankyou` },
|
||||
})
|
||||
|
||||
return { url: response.data.checkoutLink }
|
||||
@@ -326,7 +328,7 @@ export const donationRouter = router({
|
||||
await authenticateKeycloakClient()
|
||||
const userId = ctx.session.user.sub
|
||||
const user = await keycloak.users.findOne({ id: userId })
|
||||
const stripeCustomerId = user?.attributes?.fundSlugToCustomerIdAttr[input.fundSlug]?.[0]
|
||||
const stripeCustomerId = user?.attributes?.[fundSlugToCustomerIdAttr[input.fundSlug]]?.[0]
|
||||
let billingPortalUrl: string | null = null
|
||||
|
||||
if (stripeCustomerId) {
|
||||
@@ -342,6 +344,7 @@ export const donationRouter = router({
|
||||
where: {
|
||||
userId,
|
||||
membershipExpiresAt: { not: null },
|
||||
fundSlug: input.fundSlug,
|
||||
},
|
||||
orderBy: { createdAt: 'desc' },
|
||||
})
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { PrismaClient } from '@prisma/client'
|
||||
import { FundSlug, PrismaClient } from '@prisma/client'
|
||||
import Stripe from 'stripe'
|
||||
import sendgrid from '@sendgrid/mail'
|
||||
import KeycloakAdminClient from '@keycloak/keycloak-admin-client'
|
||||
@@ -6,7 +6,6 @@ import nodemailer from 'nodemailer'
|
||||
import axios, { AxiosInstance } from 'axios'
|
||||
|
||||
import { env } from '../env.mjs'
|
||||
import { FundSlug } from '../utils/funds'
|
||||
|
||||
sendgrid.setApiKey(env.SENDGRID_API_KEY)
|
||||
|
||||
@@ -21,7 +20,7 @@ const prisma =
|
||||
if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma
|
||||
|
||||
const keycloak = new KeycloakAdminClient({
|
||||
baseUrl: 'http://localhost:8080',
|
||||
baseUrl: env.KEYCLOAK_URL,
|
||||
realmName: env.KEYCLOAK_REALM_NAME,
|
||||
})
|
||||
|
||||
@@ -43,7 +42,7 @@ const btcpayApi: Record<FundSlug, AxiosInstance> = {
|
||||
baseURL: `${env.BTCPAY_URL}/api/v1/stores/${env.BTCPAY_FIRO_STORE_ID}`,
|
||||
headers: { Authorization: `token ${env.BTCPAY_API_KEY}` },
|
||||
}),
|
||||
privacy_guides: axios.create({
|
||||
privacyguides: axios.create({
|
||||
baseURL: `${env.BTCPAY_URL}/api/v1/stores/${env.BTCPAY_PRIVACY_GUIDES_STORE_ID}`,
|
||||
headers: { Authorization: `token ${env.BTCPAY_API_KEY}` },
|
||||
}),
|
||||
@@ -56,7 +55,7 @@ const btcpayApi: Record<FundSlug, AxiosInstance> = {
|
||||
const stripe: Record<FundSlug, Stripe> = {
|
||||
monero: new Stripe(env.STRIPE_MONERO_SECRET_KEY, { apiVersion: '2024-04-10' }),
|
||||
firo: new Stripe(env.STRIPE_MONERO_SECRET_KEY, { apiVersion: '2024-04-10' }),
|
||||
privacy_guides: new Stripe(env.STRIPE_MONERO_SECRET_KEY, { apiVersion: '2024-04-10' }),
|
||||
privacyguides: new Stripe(env.STRIPE_MONERO_SECRET_KEY, { apiVersion: '2024-04-10' }),
|
||||
general: new Stripe(env.STRIPE_MONERO_SECRET_KEY, { apiVersion: '2024-04-10' }),
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { FundSlug } from '../utils/funds'
|
||||
import { FundSlug } from '@prisma/client'
|
||||
|
||||
export type DonationMetadata = {
|
||||
userId: string | null
|
||||
|
||||
29
server/utils/funds.ts
Normal file
29
server/utils/funds.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { FundSlug } from '@prisma/client'
|
||||
import { env } from '../../env.mjs'
|
||||
|
||||
export const btcpayFundSlugToStoreId: Record<FundSlug, string> = {
|
||||
monero: env.BTCPAY_MONERO_STORE_ID,
|
||||
firo: env.BTCPAY_FIRO_STORE_ID,
|
||||
privacyguides: env.BTCPAY_PRIVACY_GUIDES_STORE_ID,
|
||||
general: env.BTCPAY_GENERAL_STORE_ID,
|
||||
}
|
||||
|
||||
export const btcpayFundSlugToWebhookSecret: Record<FundSlug, string> = {
|
||||
monero: env.BTCPAY_MONERO_WEBHOOK_SECRET,
|
||||
firo: env.BTCPAY_FIRO_WEBHOOK_SECRET,
|
||||
privacyguides: env.BTCPAY_PRIVACY_GUIDES_WEBHOOK_SECRET,
|
||||
general: env.BTCPAY_GENERAL_WEBHOOK_SECRET,
|
||||
}
|
||||
|
||||
export const btcpayStoreIdToFundSlug: Record<string, FundSlug> = {}
|
||||
|
||||
Object.entries(btcpayFundSlugToStoreId).forEach(
|
||||
([fundSlug, storeId]) => (btcpayStoreIdToFundSlug[storeId] = fundSlug as FundSlug)
|
||||
)
|
||||
|
||||
export const fundSlugToCustomerIdAttr: Record<FundSlug, string> = {
|
||||
monero: 'stripeMoneroCustomerId',
|
||||
firo: 'stripeFiroCustomerId',
|
||||
privacyguides: 'stripePgCustomerId',
|
||||
general: 'stripeGeneralCustomerId',
|
||||
}
|
||||
@@ -6,7 +6,7 @@ import crypto from 'crypto'
|
||||
|
||||
import { btcpayApi as _btcpayApi, prisma, stripe } from '../../server/services'
|
||||
import { DonationMetadata } from '../../server/types'
|
||||
import { btcpayStoreIdToFundSlug } from '../../utils/funds'
|
||||
import { btcpayStoreIdToFundSlug } from '../../server/utils/funds'
|
||||
|
||||
export function getStripeWebhookHandler(secret: string) {
|
||||
return async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
@@ -112,6 +112,7 @@ export function getBtcpayWebhookHandler(secret: string) {
|
||||
const rawBody = await getRawBody(req)
|
||||
const body: BtcpayBody = JSON.parse(Buffer.from(rawBody).toString('utf8'))
|
||||
const fundSlug = btcpayStoreIdToFundSlug[body.storeId]
|
||||
console.log(fundSlug)
|
||||
|
||||
const expectedSigHash = crypto.createHmac('sha256', secret).update(rawBody).digest('hex')
|
||||
const incomingSigHash = (req.headers['btcpay-sig'] as string).split('=')[1]
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
/* #3a76f0 (Signal blue) as the default accent color
|
||||
#F1F5FF as the default background color
|
||||
#ff6600 (monero orange) as the accent color for the MAGIC Monero Fund
|
||||
#9b1c2e (firo red) as the accent color for the MAGIC Firo Fund
|
||||
#f7f0f1 (firo off-white background) as the background color for the MAGIC Firo Fund
|
||||
#FFD06F (privacy guides yellow) as the accent color for the MAGIC Privacy Guides Fund */
|
||||
@layer base {
|
||||
:root {
|
||||
--background: 0 0% 100%;
|
||||
--foreground: 222.2 84% 4.9%;
|
||||
.monero {
|
||||
--background: 223, 100%, 97%;
|
||||
--foreground: 223, 84%, 5%;
|
||||
|
||||
--card: 0 0% 100%;
|
||||
--card-foreground: 222.2 84% 4.9%;
|
||||
@@ -13,56 +18,98 @@
|
||||
--popover: 0 0% 100%;
|
||||
--popover-foreground: 222.2 84% 4.9%;
|
||||
|
||||
--primary: 25 95% 53%;
|
||||
--primary-foreground: 210 40% 98%;
|
||||
--primary: 24 100% 50%;
|
||||
--primary-foreground: 0 0% 100%;
|
||||
--primary-hover: 24 100% 45%;
|
||||
|
||||
--secondary: 210 40% 96.1%;
|
||||
--secondary-foreground: 222.2 47.4% 11.2%;
|
||||
|
||||
--muted: 210 40% 96.1%;
|
||||
--muted-foreground: 215.4 16.3% 46.9%;
|
||||
|
||||
--accent: 0 0% 92;
|
||||
--accent-foreground: 222.2 47.4% 11.2%;
|
||||
--muted: 214.3 31.8% 87%;
|
||||
--muted-foreground: 218 11% 65%;
|
||||
|
||||
--destructive: 0 84% 60%;
|
||||
--destructive-foreground: 210 40% 98%;
|
||||
|
||||
--border: 214.3 31.8% 91.4%;
|
||||
--input: 214.3 31.8% 91.4%;
|
||||
--border: 214.3 31.8% 87%;
|
||||
--ring: 222.2 84% 4.9%;
|
||||
|
||||
--radius: 0.5rem;
|
||||
}
|
||||
|
||||
.dark {
|
||||
--background: 0, 0%, 9%;
|
||||
--foreground: 210 40% 98%;
|
||||
.firo {
|
||||
--background: 351 30% 95%;
|
||||
--foreground: 223 84% 5%;
|
||||
|
||||
--card: 25 95% 53%;
|
||||
--card-foreground: 210 40% 98%;
|
||||
--card: 0 0% 100%;
|
||||
--card-foreground: 222.2 84% 4.9%;
|
||||
|
||||
--popover: 0 0% 10;
|
||||
--popover-foreground: 210 40% 98%;
|
||||
--popover: 0 0% 100%;
|
||||
--popover-foreground: 222.2 84% 4.9%;
|
||||
|
||||
--primary: 25 95% 53%;
|
||||
--primary: 351 69% 36%;
|
||||
--primary-foreground: 0 0% 100%;
|
||||
--primary-hover: 351 69% 26%;
|
||||
|
||||
--secondary: 217.2 32.6% 17.5%;
|
||||
--secondary-foreground: 210 40% 98%;
|
||||
|
||||
--muted: 0 0% 20;
|
||||
--muted-foreground: 0 0% 60%;
|
||||
|
||||
--accent: 0 0% 20;
|
||||
--accent-foreground: 210 40% 98%;
|
||||
--muted: 214.3 31.8% 87%;
|
||||
--muted-foreground: 218 11% 65%;
|
||||
|
||||
--destructive: 0 84% 60%;
|
||||
--destructive-foreground: 210 40% 98%;
|
||||
|
||||
--border: 0 0% 20%;
|
||||
--input: 0 0% 20%;
|
||||
--ring: var(--primary);
|
||||
--border: 214.3 31.8% 87%;
|
||||
--ring: 222.2 84% 4.9%;
|
||||
|
||||
--radius: 0.5rem;
|
||||
}
|
||||
|
||||
.privacyguides {
|
||||
--background: 223, 100%, 97%;
|
||||
--foreground: 223, 84%, 5%;
|
||||
|
||||
--card: 0 0% 100%;
|
||||
--card-foreground: 222.2 84% 4.9%;
|
||||
|
||||
--popover: 0 0% 100%;
|
||||
--popover-foreground: 222.2 84% 4.9%;
|
||||
|
||||
--primary: 40 100% 72%;
|
||||
--primary-foreground: 0 0% 100%;
|
||||
--primary-hover: 40 100% 62%;
|
||||
|
||||
--muted: 214.3 31.8% 87%;
|
||||
--muted-foreground: 218 11% 65%;
|
||||
|
||||
--destructive: 0 84% 60%;
|
||||
--destructive-foreground: 210 40% 98%;
|
||||
|
||||
--border: 214.3 31.8% 87%;
|
||||
--ring: 222.2 84% 4.9%;
|
||||
|
||||
--radius: 0.5rem;
|
||||
}
|
||||
|
||||
.general {
|
||||
--background: 223, 100%, 97%;
|
||||
--foreground: 223, 84%, 5%;
|
||||
|
||||
--card: 0 0% 100%;
|
||||
--card-foreground: 222.2 84% 4.9%;
|
||||
|
||||
--popover: 0 0% 100%;
|
||||
--popover-foreground: 222.2 84% 4.9%;
|
||||
|
||||
--primary: 220 86% 58%;
|
||||
--primary-foreground: 0 0% 100%;
|
||||
--primary-hover: 220 86% 48%;
|
||||
|
||||
--muted: 214.3 31.8% 87%;
|
||||
--muted-foreground: 218 11% 65%;
|
||||
|
||||
--destructive: 0 84% 60%;
|
||||
--destructive-foreground: 210 40% 98%;
|
||||
|
||||
--border: 214.3 31.8% 87%;
|
||||
--ring: 222.2 84% 4.9%;
|
||||
|
||||
--radius: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,7 +132,7 @@ body {
|
||||
}
|
||||
|
||||
.footnotes {
|
||||
@apply mt-12 border-t border-gray-200 pt-8 dark:border-gray-700;
|
||||
@apply mt-12 border-t border-gray-200 pt-8;
|
||||
}
|
||||
|
||||
.data-footnote-backref {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
darkMode: ['class'],
|
||||
content: [
|
||||
'./pages/**/*.{ts,tsx}',
|
||||
'./components/**/*.{ts,tsx}',
|
||||
@@ -19,13 +18,12 @@ module.exports = {
|
||||
extend: {
|
||||
colors: {
|
||||
border: 'hsl(var(--border))',
|
||||
input: 'hsl(var(--input))',
|
||||
ring: 'hsl(var(--ring))',
|
||||
background: 'hsl(var(--background))',
|
||||
foreground: 'hsl(var(--foreground))',
|
||||
primary: {
|
||||
DEFAULT: 'hsl(var(--primary))',
|
||||
DEFAULT_HOVER: 'hsl(var(--primary) / 0.7)',
|
||||
hover: 'hsl(var(--primary-hover))',
|
||||
foreground: 'hsl(var(--primary-foreground))',
|
||||
},
|
||||
secondary: {
|
||||
@@ -73,7 +71,7 @@ module.exports = {
|
||||
'accordion-up': 'accordion-up 0.2s ease-out',
|
||||
},
|
||||
typography: (theme) => ({
|
||||
DEFAULT: {
|
||||
assds: {
|
||||
css: {
|
||||
color: theme('colors.gray.700'),
|
||||
a: {
|
||||
@@ -141,7 +139,7 @@ module.exports = {
|
||||
},
|
||||
},
|
||||
},
|
||||
dark: {
|
||||
boo: {
|
||||
css: {
|
||||
color: theme('colors.gray.300'),
|
||||
a: {
|
||||
|
||||
@@ -1,46 +1,61 @@
|
||||
import { env } from '../env.mjs'
|
||||
import { FundSlug } from '@prisma/client'
|
||||
import { ProjectItem } from './types'
|
||||
|
||||
type FundSlugs = ['monero', 'firo', 'privacy_guides', 'general']
|
||||
export type FundSlug = FundSlugs[number]
|
||||
|
||||
export const funds: Record<FundSlug, Record<string, any>> = {
|
||||
monero: {},
|
||||
firo: {},
|
||||
privacy_guides: {},
|
||||
general: {},
|
||||
export const funds: Record<FundSlug, ProjectItem & { slug: FundSlug }> = {
|
||||
monero: {
|
||||
slug: 'monero',
|
||||
nym: 'MagicMonero',
|
||||
website: 'https://monerofund.org',
|
||||
personalWebsite: 'https://monerofund.org',
|
||||
title: 'MAGIC Monero Fund',
|
||||
summary: 'Support contributors to Monero',
|
||||
coverImage: '/img/crystalball.jpg',
|
||||
git: 'magicgrants',
|
||||
twitter: 'magicgrants',
|
||||
goal: 100000,
|
||||
},
|
||||
firo: {
|
||||
slug: 'firo',
|
||||
nym: 'MagicFiro',
|
||||
website: 'https://monerofund.org',
|
||||
personalWebsite: 'https://monerofund.org',
|
||||
title: 'MAGIC Firo Fund',
|
||||
summary: 'Support contributors to Firo',
|
||||
coverImage: '/img/crystalball.jpg',
|
||||
git: 'magicgrants',
|
||||
twitter: 'magicgrants',
|
||||
goal: 100000,
|
||||
},
|
||||
privacyguides: {
|
||||
slug: 'privacyguides',
|
||||
nym: 'MagicPrivacyGuides',
|
||||
website: 'https://monerofund.org',
|
||||
personalWebsite: 'https://monerofund.org',
|
||||
title: 'MAGIC Privacy Guides Fund',
|
||||
summary: 'Support contributors to Privacy Guides',
|
||||
coverImage: '/img/crystalball.jpg',
|
||||
git: 'magicgrants',
|
||||
twitter: 'magicgrants',
|
||||
goal: 100000,
|
||||
},
|
||||
general: {
|
||||
slug: 'general',
|
||||
nym: 'MagicGeneral',
|
||||
website: 'https://monerofund.org',
|
||||
personalWebsite: 'https://monerofund.org',
|
||||
title: 'MAGIC General Fund',
|
||||
summary: 'Support contributors to MAGIC',
|
||||
coverImage: '/img/crystalball.jpg',
|
||||
git: 'magicgrants',
|
||||
twitter: 'magicgrants',
|
||||
goal: 100000,
|
||||
},
|
||||
}
|
||||
|
||||
export const fundSlugs = Object.keys(funds) as FundSlugs
|
||||
|
||||
export const btcpayFundSlugToStoreId: Record<FundSlug, string> = {
|
||||
monero: env.BTCPAY_MONERO_STORE_ID,
|
||||
firo: env.BTCPAY_FIRO_STORE_ID,
|
||||
privacy_guides: env.BTCPAY_PRIVACY_GUIDES_STORE_ID,
|
||||
general: env.BTCPAY_GENERAL_STORE_ID,
|
||||
}
|
||||
|
||||
export const btcpayFundSlugToWebhookSecret: Record<FundSlug, string> = {
|
||||
monero: env.BTCPAY_MONERO_WEBHOOK_SECRET,
|
||||
firo: env.BTCPAY_FIRO_WEBHOOK_SECRET,
|
||||
privacy_guides: env.BTCPAY_PRIVACY_GUIDES_WEBHOOK_SECRET,
|
||||
general: env.BTCPAY_GENERAL_WEBHOOK_SECRET,
|
||||
}
|
||||
|
||||
export const btcpayStoreIdToFundSlug: Record<string, FundSlug> = {}
|
||||
|
||||
Object.entries(btcpayFundSlugToStoreId).forEach(
|
||||
([fundSlug, storeId]) => (btcpayStoreIdToFundSlug[storeId] = fundSlug as FundSlug)
|
||||
)
|
||||
|
||||
export const fundSlugToCustomerIdAttr: Record<FundSlug, string> = {
|
||||
monero: 'stripeMoneroCustomerId',
|
||||
firo: 'stripeFiroCustomerId',
|
||||
privacy_guides: 'stripePgCustomerId',
|
||||
general: 'stripeGeneralCustomerId',
|
||||
}
|
||||
export const fundSlugs = Object.keys(funds) as ['monero', 'firo', 'privacyguides', 'general']
|
||||
|
||||
export function getFundSlugFromUrlPath(urlPath: string) {
|
||||
const fundSlug = urlPath.split('/')[1]
|
||||
const fundSlug = urlPath.replace(/(\?.*)$/, '').split('/')[1]
|
||||
|
||||
return fundSlugs.includes(fundSlug as any) ? (fundSlug as FundSlug) : null
|
||||
}
|
||||
|
||||
@@ -2,13 +2,12 @@ import fs from 'fs'
|
||||
import { join } from 'path'
|
||||
import matter from 'gray-matter'
|
||||
import sanitize from 'sanitize-filename'
|
||||
|
||||
import { FundSlug } from './funds'
|
||||
import { FundSlug } from '@prisma/client'
|
||||
|
||||
const directories: Record<FundSlug, string> = {
|
||||
monero: join(process.cwd(), 'docs/monero/projects'),
|
||||
firo: join(process.cwd(), 'docs/firo/projects'),
|
||||
privacy_guides: join(process.cwd(), 'docs/privacy-guides/projects'),
|
||||
privacyguides: join(process.cwd(), 'docs/privacyguides/projects'),
|
||||
general: join(process.cwd(), 'docs/general/projects'),
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import { useRouter } from 'next/router'
|
||||
import { FundSlug } from '@prisma/client'
|
||||
|
||||
import { getFundSlugFromUrlPath } from './funds'
|
||||
|
||||
export function useFundSlug() {
|
||||
|
||||
Reference in New Issue
Block a user