Skip to content

Commit

Permalink
chore: open source squash
Browse files Browse the repository at this point in the history
Co-authored-by: Drew Edwards <[email protected]>
  • Loading branch information
emmachase and Lemmmy committed Jul 29, 2024
0 parents commit fd12f83
Show file tree
Hide file tree
Showing 160 changed files with 9,633 additions and 0 deletions.
9 changes: 9 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
root = true

[*]
end_of_line = lf
insert_final_newline = true

[*.{java,kt,kts,lua}]
indent_style = space
indent_size = 4
38 changes: 38 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Copyright (c) 2024 tmpim All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.

name: build
on:
push:
tags:
- 'v*'
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2

- name: Setup JDK 17
uses: actions/setup-java@v2
with:
distribution: 'temurin'
java-version: 17

- name: Make Gradle wrapper executable
if: ${{ runner.os != 'Windows' }}
run: chmod +x ./gradlew

- name: Validate Gradle wrapper
uses: gradle/wrapper-validation-action@v1

- name: Build and publish
uses: nick-fields/retry@v2
with:
command: ./gradlew --no-parallel publishKristpay
timeout_minutes: 69
max_attempts: 5
retry_on: error
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
34 changes: 34 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# gradle

.gradle/
build/
out/
classes/

# eclipse

*.launch

# idea

.idea/
*.iml
*.ipr
*.iws

# vscode

.settings/
.vscode/
bin/
.classpath
.project

# macos

*.DS_Store

# fabric

run/
logs/
28 changes: 28 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
BSD 3-Clause License

Copyright (c) 2022-2024, tmpim

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
71 changes: 71 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# KristPay3

## Commands

### For Players
- `/bal[ance]` (kristpay.balance.get.base)<br />View your own Krist balance
- `/txs` `/transactions` (kristpay.list.base)<br />View your own transaction history
- `/pay <address> <amount>` (kristpay.pay.address)<br />Pay another player or Krist address
- `/deposit` (no permission node)<br />View your own deposit address
- `/welfare` (kristpay.welfare.check.base)<br />Check whether you are opted into welfare
- `/welfare opt in` (kristpay.welfare.opt.in.base)<br />Opt into welfare
- `/welfare opt out` (kristpay.welfare.opt.out.base)<br />Opt out of welfare
- `/welfare return` (kristpay.welfare.return.base)<br />Return your welfare rewards to the master wallet

### For Staff
- `/bal[ance] <player>` (kristpay.balance.get.others)<br />View another player's Krist balance
- `/setbal [player] <amount>` (kristpay.balance.set)<br />Set a player's Krist balance
- `/grant <player> <amount>` (kristpay.balance.grant)<br />Grant a player Krist (semantically equivalent to `/setbal oldBal+delta`)
- `/txs <player>` `/transactions <player>` (kristpay.list.others)<br />View another player's transaction history
- `/masterbal` (kristpay.masterbal.check)<br />View the master wallet and the allocated / unallocated amounts
- `/welfare <player>` (kristpay.welfare.check.others)<br />Check whether a player is opted into welfare
- `/welfare return <player>` (kristpay.welfare.return.others)<br />Return a player's welfare rewards to the master wallet

## Permissions
Permission | Role | Description
-|-|-
kristpay.balance.get.base | USER | Allows the user to view their own Krist balance
kristpay.balance.get.others | MOD | Allows the user to view another user's Krist balance
kristpay.balance.set.base | ADMIN | Set your Krist balance
kristpay.balance.set.others | ADMIN | Set another user's Krist balance
kristpay.grant.base | ADMIN | Grant yourself Krist
kristpay.grant.others | ADMIN | Grant another user Krist
kristpay.list.base | USER | List your own transactions
kristpay.list.others | MOD | List another user's transactions
kristpay.masterbal.check | MOD | Allow the user to check the master wallet balance
kristpay.pay.address | USER | Allow the user to pay another user or address
kristpay.welfare.check.base | USER | Allow the user to check whether they are opted into welfare
kristpay.welfare.check.others | MOD | Check whether another user is opted into welfare
kristpay.welfare.claim | NONE | Allow the user to claim all types of welfare
kristpay.welfare.claim.faucet | USER | Allow the user to run /faucet
kristpay.welfare.claim.login | USER | Allow the user to claim the daily login bonus
kristpay.welfare.opt.in | USER | Allow the user to opt in to welfare
kristpay.welfare.opt.out | USER | Allow the user to opt out of welfare
kristpay.welfare.return.base | USER | Allows the user to return the welfare rewards they have received back to the server
kristpay.welfare.return.others | ADMIN | Force another user to return the welfare rewards they have received

## API Usage

![](https://maven.pkg.github.com/SwitchCraftCC/KristPay3-OSS/api/badge/latest/releases/io/sc3/kristpay-api?name=Latest%20version)
```properties
# gradle.properties
kristpayVersion = <version>
```

```kotlin
// build.gradle.kts
val kristpayVersion: String by project

repositories {
maven {
url = uri("https://maven.pkg.github.com/SwitchCraftCC/KristPay3-OSS/releases")
content {
includeGroup("io.sc3")
}
}
}

dependencies {
compileOnly("io.sc3", "kristpay-api", kristpayVersion)
}
```
9 changes: 9 additions & 0 deletions api/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* Copyright (c) 2024 tmpim All rights reserved.
* Use of this source code is governed by a BSD-style
* license that can be found in the LICENSE file.
*/

base {
archivesName.set("kristpay-api")
}
74 changes: 74 additions & 0 deletions api/src/main/kotlin/io/sc3/kristpay/api/KristPayAPI.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* Copyright (c) 2024 tmpim All rights reserved.
* Use of this source code is governed by a BSD-style
* license that can be found in the LICENSE file.
*/

package io.sc3.kristpay.api

import io.sc3.kristpay.api.model.*
import io.sc3.kristpay.api.model.frontend.TransactionSymbol
import kotlinx.serialization.json.JsonObject
import org.jetbrains.annotations.ApiStatus.Internal
import java.util.*

typealias UserID = UUID
typealias WalletID = UUID
typealias UserGroupID = UUID

interface KristPayAPI {

fun acquireServiceWallet(id: String): WalletID

suspend fun planServicePayment(request: ServicePaymentRequest): ServicePaymentPlan?
fun subscribeToPaymentGroup(pluginID: PluginID, groupID: GroupID, callback: (ServicePayment) -> Unit)

/** Callback should return a TransactionSymbol object, or null if it doesn't want to handle the transaction. */
fun registerTransactionSymbol(callback: (KristPayWallet, TransactionSnapshot) -> TransactionSymbol?)
/** Callback should return a list of Minecraft Text objects, serialised to JSON, or null if it doesn't want to
* handle the transaction. */
fun registerTransactionDescriptor(callback: (KristPayWallet, TransactionSnapshot) -> List<String>?)

fun getMasterWallet(): MasterWallet

fun getWalletSnapshot(wallet: WalletID): WalletSnapshot?
fun getWalletName(wallet: WalletID): String?

fun findWalletByName(name: String): WalletSnapshot?

fun getDefaultWallet(userID: UserID): WalletID?
fun getDefaultWalletSnapshot(userID: UserID): WalletSnapshot? = getDefaultWallet(userID)?.let { getWalletSnapshot(it) }

fun getNotifications(userID: UserID): List<NotificationSnapshot>
fun clearNotifications(userID: UserID)

// True if user was created, False if user already existed
fun initializeUser(userID: UserID, userReferenceName: String, giveStartingBalance: Boolean = true): Boolean

fun initializeTransaction(
from: PaymentActor,
to: PaymentActor,
amount: MonetaryAmount,
metadata: String? = null,
initiator: Initiator,
systemMetadata: JsonObject? = null,
sendNotification: Boolean = true,
externalReference: Int? = null,
allowDebt: Boolean = false
): PaymentResult

// The list returned is lazy, and will only fetch more pages as needed
// Because of this, never fully iterate over the list unless you're sure you want to
// Use lazyMap to transform the list when necessary
fun listTransactions(
wallet: WalletID,
pageSize: Int = 100,
): List<TransactionSnapshot>

fun getTransaction(id: UUID): TransactionSnapshot?

fun getFrontend(): KristPayFrontend

@Internal
fun cleanup()
}
11 changes: 11 additions & 0 deletions api/src/main/kotlin/io/sc3/kristpay/api/KristPayConsumer.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
* Copyright (c) 2024 tmpim All rights reserved.
* Use of this source code is governed by a BSD-style
* license that can be found in the LICENSE file.
*/

package io.sc3.kristpay.api

abstract class KristPayConsumer {
protected val API: KristPayAPI by lazy { KristPayProvider.get() }
}
25 changes: 25 additions & 0 deletions api/src/main/kotlin/io/sc3/kristpay/api/KristPayFrontend.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright (c) 2024 tmpim All rights reserved.
* Use of this source code is governed by a BSD-style
* license that can be found in the LICENSE file.
*/

package io.sc3.kristpay.api

import io.sc3.kristpay.api.model.MonetaryAmount
import io.sc3.kristpay.api.model.NotificationSnapshot
import io.sc3.kristpay.api.model.PaymentResult
import io.sc3.kristpay.api.model.ServicePaymentRequest
import io.sc3.kristpay.api.model.frontend.PaymentRequestResponse

interface KristPayFrontend {

suspend fun presentPaymentRequest(request: ServicePaymentRequest): PaymentRequestResponse

fun presentNotification(notification: NotificationSnapshot): Boolean

fun sendBalance(user: UserID, amount: MonetaryAmount)

fun notifyServicePaymentSuccess(request: ServicePaymentRequest, response: PaymentRequestResponse)
fun notifyServicePaymentFailure(result: PaymentResult, request: ServicePaymentRequest, response: PaymentRequestResponse)
}
34 changes: 34 additions & 0 deletions api/src/main/kotlin/io/sc3/kristpay/api/KristPayProvider.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright (c) 2024 tmpim All rights reserved.
* Use of this source code is governed by a BSD-style
* license that can be found in the LICENSE file.
*/

package io.sc3.kristpay.api

import org.jetbrains.annotations.ApiStatus.Internal

object KristPayProvider {
private var instance: KristPayAPI? = null

fun get() = instance ?: throw NotLoadedException

@Internal
fun register(kristPay: KristPayAPI) {
instance = kristPay
}

@Internal
fun unregister() {
instance = null
}

private object NotLoadedException : IllegalStateException() {
private const val MESSAGE = "The KristPay API isn't loaded yet!\n" +
"This could be because:\n" +
" a) the KristPay plugin is not installed or it failed to enable\n" +
" b) the plugin in the stacktrace does not declare a dependency on KristPay\n" +
" c) the plugin in the stacktrace is retrieving the API before the plugin 'enable' phase\n" +
" (call the #get method in onEnable, not the constructor!)\n"
}
}
44 changes: 44 additions & 0 deletions api/src/main/kotlin/io/sc3/kristpay/api/model/Initiator.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright (c) 2024 tmpim All rights reserved.
* Use of this source code is governed by a BSD-style
* license that can be found in the LICENSE file.
*/

package io.sc3.kristpay.api.model

import java.util.UUID

sealed class Initiator {
data class User(val id: UUID): Initiator()
data class KristAddress(val address: String): Initiator()
data class ServerPlugin(val pluginID: String): Initiator()
object Server: Initiator()

fun serialize(): String {
return when (this) {
is User -> "$UserKey:$id"
is KristAddress -> "$AddressKey:$address"
is ServerPlugin -> "$PluginKey:$pluginID"
is Server -> ServerKey
}
}

companion object {
private const val UserKey = "User"
private const val AddressKey = "Krist"
private const val PluginKey = "Plugin"
private const val ServerKey = "Server"

fun deserialize(record: String): Initiator {
val prefix = record.substringBefore(":")
val value = record.substringAfter(":")
return when (prefix) {
UserKey -> User(UUID.fromString(value))
AddressKey -> KristAddress(value)
PluginKey -> ServerPlugin(value)
ServerKey -> Server
else -> throw IllegalArgumentException("Invalid initiator record: $record")
}
}
}
}
Loading

0 comments on commit fd12f83

Please sign in to comment.