feat: add CoopCredits Solana media rewards ecosystem

Add complete  token system with Plex/Tautulli/Overseer integration:
- Anchor program for SPL token mint/burn/transfer
- Express backend with OAuth, webhooks, Solana integration
- Next.js frontend with dashboard, admin panel, wallet management
- Docker deployment for 172.20.1.0/24 infrastructure
- Production configs with SSL, Nginx, health monitoring

Tautulli webhooks auto-mint  on watch events.
Overseer integration burns  for content requests.
This commit is contained in:
2026-04-14 11:09:50 -04:00
parent f106328f6a
commit e8d9b1fd42
69 changed files with 11382 additions and 0 deletions
+95
View File
@@ -0,0 +1,95 @@
import * as anchor from "@coral-xyz/anchor";
import { Program } from "@coral-xyz/anchor";
import { CoopCredits } from "../target/types/coop_credits";
import { expect } from "chai";
describe("coop-credits", () => {
// Configure the client to use the local cluster.
anchor.setProvider(anchor.AnchorProvider.env());
const program = anchor.workspace.CoopCredits as Program<CoopCredits>;
const provider = anchor.getProvider();
let globalStatePDA: anchor.web3.PublicKey;
let mintPDA: anchor.web3.PublicKey;
let mintAuthorityPDA: anchor.web3.PublicKey;
before(async () => {
// Find PDAs
[globalStatePDA] = anchor.web3.PublicKey.findProgramAddressSync(
[Buffer.from("global_state")],
program.programId,
);
[mintAuthorityPDA] = anchor.web3.PublicKey.findProgramAddressSync(
[Buffer.from("mint_authority")],
program.programId,
);
});
it("Initializes the program", async () => {
const tx = await program.methods
.initialize()
.accounts({
globalState: globalStatePDA,
authority: provider.publicKey,
systemProgram: anchor.web3.SystemProgram.programId,
tokenProgram: anchor.utils.token.TOKEN_PROGRAM_ID,
rent: anchor.web3.SYSVAR_RENT_PUBKEY,
})
.rpc();
console.log("Initialize transaction signature", tx);
// Verify global state
const globalState = await program.account.globalState.fetch(globalStatePDA);
expect(globalState.authority.toString()).to.equal(
provider.publicKey.toString(),
);
expect(globalState.paused).to.be.false;
expect(globalState.creditsPerMinute).to.equal(10);
});
it("Updates minting rate", async () => {
const newRate = 20;
const tx = await program.methods
.updateMintingRate(newRate)
.accounts({
globalState: globalStatePDA,
authority: provider.publicKey,
})
.rpc();
console.log("Update rate transaction signature", tx);
const globalState = await program.account.globalState.fetch(globalStatePDA);
expect(globalState.creditsPerMinute).to.equal(newRate);
});
it("Pauses and resumes minting", async () => {
// Pause
let tx = await program.methods
.pauseMinting()
.accounts({
globalState: globalStatePDA,
authority: provider.publicKey,
})
.rpc();
let globalState = await program.account.globalState.fetch(globalStatePDA);
expect(globalState.paused).to.be.true;
// Resume
tx = await program.methods
.resumeMinting()
.accounts({
globalState: globalStatePDA,
authority: provider.publicKey,
})
.rpc();
globalState = await program.account.globalState.fetch(globalStatePDA);
expect(globalState.paused).to.be.false;
});
});