Skip to content

Commit 55d2d98

Browse files
committed
adding secret santa cordapp
1 parent c434d5a commit 55d2d98

File tree

62 files changed

+20893
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+20893
-0
lines changed

Advanced/secret-santa/LICENCE

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
Copyright 2016, R3 Limited.
2+
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
7+
http://www.apache.org/licenses/LICENSE-2.0
8+
9+
Unless required by applicable law or agreed to in writing, software
10+
distributed under the License is distributed on an "AS IS" BASIS,
11+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
See the License for the specific language governing permissions and
13+
limitations under the License.

Advanced/secret-santa/README.md

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
![](./clients/src/main/webapp/src/Components/img/secret_corda.png)
2+
3+
# Corda Secret Santa
4+
5+
This is an imlementation of Secret Santa using Corda as a tool to store multiple game states.
6+
7+
It has a material-ui frontend that lets users create and self-service their own secret santa games. The frontend is implemented in ReactJS and the backend is implemented with a Spring Boot server and some corda flows.
8+
9+
You can create a game using the web frontend (or just calling the api directly with Postman), and once the game is stored, players can look up their assignments using their game id, and the app also supports an optional sendgrid integration so that you can have emails sent to the players as well.
10+
11+
> One tip if you're using intellij one recommendation is to open the project from the intellij dialog, don't import the project directly.
12+
13+
## Usage
14+
15+
There's essentially five processes you'll need to be aware of.
16+
17+
- Three Corda nodes, a notary, santa, and an elf
18+
- The backend webserver that runs the REST endpoints for the corda nodes
19+
- The frontend webserver, a react app that sends requests to the backend.
20+
21+
22+
#### Pre-Requisites
23+
24+
If you've never built a cordapp before you may need to configure gradle and java in order for this code example to run. See [our setup guide](https://docs.corda.net/getting-set-up.html).
25+
26+
27+
### Running these services
28+
29+
#### The three Corda nodes
30+
To run the corda nodes you just need to run the `deployNodes` gradle task and the nodes will be available for you to run directly.
31+
32+
```
33+
./gradlew deployNodes
34+
./build/nodes/runnodes
35+
```
36+
37+
#### The backend webserver
38+
39+
Run the `runSantaServer` Gradle task. By default, it connects to the node with RPC address `localhost:10006` with
40+
the username `user1` and the password `test`, and serves the webserver on port `localhost:10056`.
41+
42+
```
43+
./gradlew runSantaServer
44+
```
45+
46+
The frontend will be visible on [localhost:10056](http://localhost:10056)
47+
48+
##### Background Information
49+
50+
`clients/src/main/java/com/secretsanta/webserver/` defines a simple Spring webserver that connects to a node via RPC and allows you to interact with the node over HTTP.
51+
52+
The API endpoints are defined in `clients/src/main/java/com/secretsanta/webserver/Controller.java`
53+
54+
55+
#### The frontend webserver
56+
57+
The react server can be started by going to `clients/src/main/webapp`, running `npm install` and then `npm start`.
58+
59+
```
60+
cd clients/src/main/webapp
61+
npm install
62+
npm start
63+
```
64+
65+
The frontend will be visible on [localhost:8888](http://localhost:8888)
66+
67+
#### Configuring Email with SendGrid
68+
69+
If you'd like to start sending email you'll need to make an account on [sendgrid.com](http://sendgrid.com) and configure a verified sender identity.
70+
71+
Once you've done that, create an API key and place it into `Controller.java`(the webserver for the corda nodes). After which point you can set the `sendEmail` param to `true` in your requests. In order to configure the frontend to send emails, just open `CONSTANTS.js` and set the `SEND_EMAIL` param to `true` instead of `false`.
72+
73+
74+
### Testing Utilities
75+
76+
77+
#### Using Postman for backend testing
78+
79+
I've included some simple postman tests to run against the santa server that will be helpful to you if you plan on using this. You'll find them in the `postman` folder.
80+
81+
82+
#### Running tests inside IntelliJ
83+
84+
There are unit tests for the corda state, contract, and tests for both flows used here. You'll find them inside of the various test folders.
85+

Advanced/secret-santa/TRADEMARK

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Corda and the Corda logo are trademarks of R3CEV LLC and its affiliates. All rights reserved.
2+
3+
For R3CEV LLC's trademark and logo usage information, please consult our Trademark Usage Policy at
4+
https://www.r3.com/trademark-policy/.

Advanced/secret-santa/build.gradle

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
buildscript { //properties that you need to build the project
2+
Properties constants = new Properties()
3+
file("$projectDir/./constants.properties").withInputStream { constants.load(it) }
4+
5+
ext {
6+
corda_release_group = constants.getProperty("cordaReleaseGroup")
7+
corda_core_release_group = constants.getProperty("cordaCoreReleaseGroup")
8+
corda_release_version = constants.getProperty("cordaVersion")
9+
corda_core_release_version = constants.getProperty("cordaCoreVersion")
10+
corda_gradle_plugins_version = constants.getProperty("gradlePluginsVersion")
11+
kotlin_version = constants.getProperty("kotlinVersion")
12+
junit_version = constants.getProperty("junitVersion")
13+
quasar_version = constants.getProperty("quasarVersion")
14+
log4j_version = constants.getProperty("log4jVersion")
15+
slf4j_version = constants.getProperty("slf4jVersion")
16+
corda_platform_version = constants.getProperty("platformVersion").toInteger()
17+
18+
// springboot
19+
spring_boot_version = '2.0.2.RELEASE'
20+
spring_boot_gradle_plugin_version = '2.0.2.RELEASE'
21+
22+
accounts_release_version = '1.0'
23+
accounts_release_group = 'com.r3.corda.lib.accounts'
24+
confidential_id_release_group = "com.r3.corda.lib.ci"
25+
confidential_id_release_version = "1.0"
26+
}
27+
28+
repositories {
29+
mavenLocal()
30+
mavenCentral()
31+
jcenter()
32+
maven { url 'https://jitpack.io' }
33+
maven { url 'https://repo.gradle.org/gradle/libs-releases' }
34+
maven { url 'http://software.r3.com/artifactory/corda-lib' }
35+
maven { url 'https://software.r3.com/artifactory/corda-releases' }
36+
}
37+
38+
dependencies {
39+
classpath "net.corda.plugins:cordapp:$corda_gradle_plugins_version"
40+
classpath "net.corda.plugins:cordformation:$corda_gradle_plugins_version"
41+
classpath "net.corda.plugins:quasar-utils:$corda_gradle_plugins_version"
42+
classpath "org.springframework.boot:spring-boot-gradle-plugin:$spring_boot_gradle_plugin_version"
43+
classpath "net.corda.plugins:cordapp:$corda_gradle_plugins_version"
44+
45+
classpath "com.sendgrid:sendgrid-java:4.7.0"
46+
classpath "com.sendgrid:java-http-client:4.3.6"
47+
}
48+
}
49+
50+
allprojects {//Properties that you need to compile your project (The application)
51+
apply from: "${rootProject.projectDir}/repositories.gradle"
52+
apply plugin: 'java'
53+
54+
repositories {
55+
mavenLocal()
56+
jcenter()
57+
mavenCentral()
58+
maven { url 'https://jitpack.io' }
59+
maven { url 'https://software.r3.com/artifactory/corda' }
60+
}
61+
62+
tasks.withType(JavaCompile) {
63+
options.compilerArgs << "-parameters" // Required by Corda's serialisation framework.
64+
}
65+
66+
// tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile) {
67+
// kotlinOptions {
68+
// languageVersion = "1.2"
69+
// apiVersion = "1.2"
70+
// jvmTarget = "1.8"
71+
// javaParameters = true // Useful for reflection.
72+
// }
73+
// }
74+
75+
jar {
76+
// This makes the JAR's SHA-256 hash repeatable.
77+
preserveFileTimestamps = false
78+
reproducibleFileOrder = true
79+
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
80+
}
81+
}
82+
83+
apply plugin: 'net.corda.plugins.cordapp'
84+
apply plugin: 'net.corda.plugins.cordformation'
85+
apply plugin: 'net.corda.plugins.quasar-utils'
86+
87+
sourceSets {
88+
main {
89+
resources {
90+
srcDir rootProject.file("config/dev")
91+
}
92+
}
93+
}
94+
95+
//Module dependencis
96+
dependencies {
97+
// Corda dependencies.
98+
cordaCompile "$corda_core_release_group:corda-core:$corda_core_release_version"
99+
cordaCompile "$corda_release_group:corda-node-api:$corda_release_version"
100+
cordaRuntime "$corda_release_group:corda:$corda_release_version"
101+
102+
// CorDapp dependencies.
103+
cordapp project(":workflows")
104+
cordapp project(":contracts")
105+
106+
cordaCompile "org.slf4j:jul-to-slf4j:$slf4j_version"
107+
cordaCompile "org.apache.logging.log4j:log4j-web:${log4j_version}"
108+
cordaCompile "org.apache.logging.log4j:log4j-slf4j-impl:${log4j_version}"
109+
}
110+
111+
//Task to build the jar for ganache.
112+
task ganache {
113+
subprojects {
114+
if (it.project.name != "clients") {
115+
dependsOn jar
116+
doLast {
117+
copy {
118+
from "${buildDir}/libs"
119+
into "${rootDir}/build/libs"
120+
}
121+
}
122+
}
123+
}
124+
}
125+
126+
//Task to deploy the nodes in order to bootstrap a network
127+
task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
128+
129+
/* This property will load the CorDapps to each of the node by default, including the Notary. You can find them
130+
* in the cordapps folder of the node at build/nodes/Notary/cordapps. However, the notary doesn't really understand
131+
* the notion of cordapps. In production, Notary does not need cordapps as well. This is just a short cut to load
132+
* the Corda network bootstrapper.
133+
*/
134+
135+
//Java version check
136+
if (JavaVersion.current() != JavaVersion.VERSION_1_8){
137+
throw new GradleException("This build must be run with java 8")
138+
}
139+
140+
nodeDefaults {
141+
projectCordapp { deploy = true }
142+
cordapp project(':contracts')
143+
cordapp project(':workflows')
144+
}
145+
146+
node {
147+
name "O=Notary,L=London,C=GB"
148+
notary = [validating : false]
149+
p2pPort 10002
150+
rpcSettings {
151+
address("localhost:10003")
152+
adminAddress("localhost:10043")
153+
}
154+
}
155+
node {
156+
name "O=Santa,L=London,C=GB"
157+
p2pPort 10006
158+
rpcSettings {
159+
address("localhost:10016")
160+
adminAddress("localhost:10046")
161+
}
162+
rpcUsers = [[ user: "user1", "password": "test", "permissions": ["ALL"]]]
163+
}
164+
165+
node {
166+
name "O=Elf,L=London,C=GB"
167+
p2pPort 10007
168+
rpcSettings {
169+
address("localhost:10017")
170+
adminAddress("localhost:10027")
171+
}
172+
173+
rpcUsers = [[ user: "user1", "password": "test", "permissions": ["ALL"]]]
174+
}
175+
176+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
buildscript {
2+
repositories {
3+
maven {
4+
url = uri("https://plugins.gradle.org/m2/")
5+
}
6+
}
7+
}
8+
9+
apply plugin: 'org.springframework.boot'
10+
11+
sourceSets {
12+
main {
13+
resources {
14+
srcDir rootProject.file("config/dev")
15+
}
16+
}
17+
}
18+
19+
dependencies {
20+
implementation 'com.google.code.gson:gson:2.8.5'
21+
22+
// Corda dependencies.
23+
compile "$corda_release_group:corda-rpc:$corda_release_version"
24+
25+
// CorDapp dependencies.
26+
compile project(":contracts")
27+
compile project(":workflows")
28+
compile("org.springframework.boot:spring-boot-starter-websocket:$spring_boot_version") {
29+
exclude group: "org.springframework.boot", module: "spring-boot-starter-logging"
30+
}
31+
compile "org.apache.logging.log4j:log4j-slf4j-impl:${log4j_version}"
32+
compile "org.apache.logging.log4j:log4j-web:${log4j_version}"
33+
compile "org.slf4j:jul-to-slf4j:$slf4j_version"
34+
35+
// SendGrid
36+
implementation 'com.sendgrid:sendgrid-java:4.7.0'
37+
compile 'com.sendgrid:sendgrid-java:4.7.0'
38+
}
39+
40+
springBoot {
41+
mainClassName = "net.corda.samples.secretsanta.webserver.Server"
42+
}
43+
44+
/* The Client is the communication channel between the external and the node. This task will help you immediately
45+
* execute your rpc methods in the main method of the client.kt. You can somewhat see this as a quick test of making
46+
* RPC calls to your nodes.
47+
*/
48+
task runSantaClient(type: JavaExec, dependsOn: assemble) {
49+
classpath = sourceSets.main.runtimeClasspath
50+
main = 'net.corda.samples.secretsanta.Client'
51+
args 'localhost:10016', 'user1', 'test'
52+
}
53+
54+
/**
55+
* This task will start the springboot server that connects to the santa node (via RPC connection). All of the http requests
56+
* are in the Controller file.
57+
*
58+
*/
59+
task runSantaServer(type: JavaExec, dependsOn: assemble) {
60+
classpath = sourceSets.main.runtimeClasspath
61+
main = 'net.corda.samples.secretsanta.webserver.Starter'
62+
args '--server.port=10056', '--config.rpc.host=localhost', '--config.rpc.port=10016', '--config.rpc.username=user1', '--config.rpc.password=test'
63+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package net.corda.samples.secretsanta;
2+
3+
import net.corda.client.rpc.CordaRPCClient;
4+
import net.corda.client.rpc.CordaRPCConnection;
5+
import net.corda.core.identity.CordaX500Name;
6+
import net.corda.core.messaging.CordaRPCOps;
7+
import net.corda.core.node.NodeInfo;
8+
import net.corda.core.utilities.NetworkHostAndPort;
9+
import org.slf4j.Logger;
10+
import org.slf4j.LoggerFactory;
11+
12+
import java.util.List;
13+
14+
import static net.corda.core.utilities.NetworkHostAndPort.parse;
15+
16+
/**
17+
* Connects to a Corda node via RPC and performs RPC operations on the node.
18+
*
19+
* The RPC connection is configured using command line arguments.
20+
*/
21+
public class Client {
22+
private static final Logger logger = LoggerFactory.getLogger(Client.class);
23+
24+
public static void main(String[] args) {
25+
// Create an RPC connection to the node.
26+
if (args.length != 3) throw new IllegalArgumentException("Usage: Client <node address> <rpc username> <rpc password>");
27+
final NetworkHostAndPort nodeAddress = parse(args[0]);
28+
final String rpcUsername = args[1];
29+
final String rpcPassword = args[2];
30+
final CordaRPCClient client = new CordaRPCClient(nodeAddress);
31+
final CordaRPCConnection clientConnection = client.start(rpcUsername, rpcPassword);
32+
final CordaRPCOps proxy = clientConnection.getProxy();
33+
34+
// Interact with the node.
35+
// Example #1, here we print the nodes on the network.
36+
final List<NodeInfo> nodes = proxy.networkMapSnapshot();
37+
System.out.println("\n-- Here is the networkMap snapshot --");
38+
logger.info("{}", nodes);
39+
40+
// Example #2, here we print the PartyA's node info
41+
CordaX500Name name = proxy.nodeInfo().getLegalIdentities().get(0).getName();//nodeInfo().legalIdentities.first().name
42+
System.out.println("\n-- Here is the node info of the node that the client connected to --");
43+
logger.info("{}", name);
44+
45+
//Close the client connection
46+
clientConnection.close();
47+
}
48+
}

0 commit comments

Comments
 (0)