Mage Hands - Crowdfunding Dapp

Hey everyone,

I created a simple crowdfunding dapp called Mage Hands that is running on holodeck-2: . Please let me know what you think! (The holodeck API seems sluggish so things might be a bit slow).


As far as I know, there are two main ways to get funded for projects in the Secret ecosystem. The first is to apply for a grant that is approved by Enigma or Secret Foundation, and the other is to make an on-chain proposal. In the first case, the decision is necessarily made by a small number of people, and for the second there is still a high bar that must be met–reaching quorum, etc. I think there are likely a number of smaller/bespoke projects that could be crowdfunded by interested backers, which would not be funded otherwise because maybe they are only of interest to a minority of stakeholders or they are not seen as a central priority for the network. In my opinion, having a way for these projects to still get funded will help create a more vibrant community all around. This would also not preclude Enigma or the foundation contributing to projects if they wanted to.

Besides projects that are specifically about secret network, this dapp could also be used to crowdsource projects that have nothing to do with the network at all.


I’ve built the dapp to have a main platform contract that spins up a new contract for each crowdfunding project. A project has a deadline, a goal (target funding), and one of three states: fundraising, expired, and successful. The fundraising ends at the deadline. If the goal is met, then it is successful, otherwise it is expired. A project is successful the moment the goal is met, but people can still contribute more up to the deadline. While a project is still fundraising (not yet successful) a contributor can request a refund, but once the goal has been met they cannot. A project is expired if the deadline has been reached without getting to the goal. Refunds can always be requested for expired projects. Once a project’s deadline is past and it is successful, then the creator of the project can Pay out.

Each project has a title, description, category labels (up to 5), deadline. In addition, optionally a message can be added that is shown as soon as someone pledges money (while still fundraising), and another message can be added that is only visible to contributors if the project is successful and paid out. This could be used to share information about an airdrop for contributors or in other creative ways.

At the moment, it only uses SCRT. If there’s interest in this project going forward, then I’ll add in sSCRT and other tokens people might want.

Additional comments

I think some kind of deadman switch would be good. E.g. if the creator does not pay out from a successful project within 1 month, then the project is treated as expired and people can get refunds.

Personally, I think that the creator of the project should always have a public address. I certainly would be uneasy about contributing to a project where the creator is completely anonymous. Ideally, the project description should have links that go to more information about the creator, etc. Contributors, on the other hand, should have an option to be anonymous (to the creator), though that would mean that the creator cannot send them airdrops etc. Also, with SCRT it is pretty much not anonymous anyway once you look on the chain. Even with secret wrapped tokens, I need to think about it because each project is its own contract so it might be hard to hide if someone has contributed to a project (even if you don’t know how much). Maybe this is not such a big issue? (I suppose people could always create a burner scrt account to contribute if they want).

In the platform contract I added an option to require a payment of some nominal amount of SCRT (e.g. 3) to create a new crowdfunding project. I think this would be necessary to prevent spam projects.

Are there other features people would like to see?


Here’s the contract code:


I’ve noticed that the slow response from the testnet API means that it sometimes returns 502 errors when creating or contributing, even though they are being correctly executed in the contract (page re-load shows it). That means, e.g., that the viewing key generated for contributors is not returned and the option for a refund doesn’t show in the UI. This is just due to issues with testnet, but I’ll add in a “generate viewing key” option to the projects to get around that, so people can play around with that option if they want.

Hi Ben, this is very cool!

Here’s my feedback.

  • Black text on dark background isn’t so pleasant to look at
  • The “Goal” field was not clear to me, I tried writing “My goal is to buy a bus ticket” :sweat_smile:

  • IMO hours should be in UTC or local time. Right now I’m not sure what 22:00 means, is it my time or UTC?
  • Loved the hour picker background for day/night! But I noticed that it overlaps with the “Continue” button.

  • Why am I sending 1 SCRT when creating a fundraiser? The UI should say that it costs something to create a fundraiser.

  • When contributing it should be clear what coin I’m sending.

  • Wen anonymous in the UI? :stuck_out_tongue:


  • The link at returns 404, but I suspect that when you call secretjs.execute() if you’ll also pass in the contractCodeHash of the called contract it’ll save your UI a roundtrip to the node for fetching the contractCodeHash before being able to prompt the user for approval. This will result in a much snappier UI, especially when nodes are overloaded (source).

  • The UI didn’t warn me when I tried to contribute more than the remaining amount, not sure if this is intentional.

  • Do funds go directly to the fundraising user after each contribution, or only after the deadline? As a fundraising user, how can I know when funds go to me after a contribution? EDIT: NVM, re-read you’re description above. Anyway I think the UI should explain how this works.

Good luck!


Thanks for the feedback @assafmo, that’s all very helpful! The black text is a surprise-- it is white on mine (and looks a lot nicer :slight_smile: ). Maybe it is a dark mode CSS thing? The UI definitely needs some more tweaking before it is ready. And whoops I forgot to make the repo public! It is now. That’s cool about sending in the code hash in the exec, I didn’t realise about that.

Yeah, definitely I plan to add in the anonymous field-- it needs helper text throughout to explain what all the fields mean like that one, since they are not all clear without explanation. In the case of “anonymous”, it means that if the fundraising is successful, then the creator gets a list of the donations and addresses, so that they can send airdrops etc… But it might be that the contributor does not want their address shared with the creator so it is not made available (anonymous=true).

Initially I was going to have it close as soon as the goal was met, but I realised that sometimes with crowdfunding things are much more popular than anticipated, so why not let more people donate? So I decided to make it so that you could contribute more than the “goal” but I agree it should give some more prompts/feedback to make sure it is not a mistake.


Colors should be better. I was developing on dark mode and didn’t check it in light mode. I used building this app as an way to learn Svelte at the same time, so still working my way around how it works! :sweat_smile: