Skip to content

Commit

Permalink
Move crank
Browse files Browse the repository at this point in the history
  • Loading branch information
jpbogle committed Apr 26, 2022
1 parent 7091738 commit b1e6a4f
Show file tree
Hide file tree
Showing 10 changed files with 7,868 additions and 0 deletions.
10 changes: 10 additions & 0 deletions api/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
root = true

[*]
end_of_line = lf
insert_final_newline = true

[*.{js,json,yml}]
charset = utf-8
indent_style = space
indent_size = 2
15 changes: 15 additions & 0 deletions api/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
node_modules
.DS_Store
.build
.serverless

node_modules
.eslintcache

.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions
40 changes: 40 additions & 0 deletions api/common/connection.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { Connection } from "@solana/web3.js";

const networkURLs: { [key: string]: { primary: string; secondary?: string } } =
{
["mainnet-beta"]: {
primary:
"https://solana-api.syndica.io/access-token/sAVBWmmS5tiEVca9BZki5DKRGFssefsicszEOE4uGG3vDVr4mOZwMw83jpcMbhz2/rpc",
secondary: "https://ssc-dao.genesysgo.net/",
},
mainnet: {
primary:
"https://solana-api.syndica.io/access-token/sAVBWmmS5tiEVca9BZki5DKRGFssefsicszEOE4uGG3vDVr4mOZwMw83jpcMbhz2/rpc",
secondary: "https://ssc-dao.genesysgo.net/",
},
devnet: { primary: "https://api.devnet.solana.com/" },
testnet: { primary: "https://api.testnet.solana.com/" },
localnet: { primary: "http://localhost:8899/" },
};

export const connectionFor = (
cluster: string | null,
defaultCluster = "mainnet"
) => {
return new Connection(
process.env.RPC_URL || networkURLs[cluster || defaultCluster]!.primary,
"recent"
);
};

export const secondaryConnectionFor = (
cluster: string | null,
defaultCluster = "mainnet"
) => {
return new Connection(
process.env.RPC_URL ||
networkURLs[cluster || defaultCluster]?.secondary ||
networkURLs[cluster || defaultCluster]!.primary,
"recent"
);
};
14 changes: 14 additions & 0 deletions api/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"devDependencies": {
"serverless": "^2.72.0",
"serverless-plugin-include-dependencies": "^5.0.0",
"serverless-plugin-typescript": "^2.1.0",
"serverless-step-functions": "^3.5.1",
"typescript": "^4.5.4"
},
"dependencies": {
"@cardinal/token-manager": "^1.1.0",
"@project-serum/anchor": "^0.21.0",
"ts-node": "^10.5.0"
}
}
50 changes: 50 additions & 0 deletions api/serverless.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
org: jpbogle
app: cardinal
service: cardinal-apis
frameworkVersion: "2 || 3"

provider:
name: aws
runtime: nodejs14.x
lambdaHashingVersion: "20201221"

stepFunctions:
stateMachines:
everyminute:
type: EXPRESS
events:
- schedule:
rate: rate(1 minute)
id: loop-${opt:stage}
name: loop-${opt:stage}
definition:
StartAt: Create Loop Items
States:
Create Loop Items:
Type: Pass
Next: Loop
Result:
items: [1, 2, 3, 4, 5, 6]
Loop:
Type: Map
ItemsPath: "$.items"
MaxConcurrency: 1
Iterator:
StartAt: Wait 10 Seconds
States:
Wait 10 Seconds:
Type: Wait
Seconds: 10
Next: TimeInvalidatorCrank
TimeInvalidatorCrank:
Type: Task
Resource: arn:aws:states:::lambda:invoke
Parameters:
FunctionName: !GetAtt time-invalidate-crank.Arn
InvocationType: Event
End: true
End: true

plugins:
- serverless-plugin-typescript
- serverless-step-functions
19 changes: 19 additions & 0 deletions api/time-invalidate-crank/handler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { invalidateAll } from "./invalidate";

// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
module.exports.invalidate = async (event: any) => {
console.log(
`--------------- Expiring time-invalidators on ${new Date().toDateString()} ---------------`
);
console.log(process.env, process.env.CRANK_DISABLED);
if (process.env.CRANK_DISABLED === "true") {
console.log("Crank disabled");
} else {
await invalidateAll();
}
console.log(
`--------------- Finished expiring time-invalidators on ${new Date().toDateString()} ---------------`
);
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
return event;
};
134 changes: 134 additions & 0 deletions api/time-invalidate-crank/invalidate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import {
programs,
tryGetAccount,
withInvalidate,
} from "@cardinal/token-manager";
import { timeInvalidator } from "@cardinal/token-manager/dist/cjs/programs";
import { TokenManagerState } from "@cardinal/token-manager/dist/cjs/programs/tokenManager";
import { BN, utils } from "@project-serum/anchor";
import { SignerWallet } from "@saberhq/solana-contrib";
import {
Keypair,
sendAndConfirmRawTransaction,
Transaction,
} from "@solana/web3.js";

import { connectionFor, secondaryConnectionFor } from "../common/connection";

// crkdpVWjHWdggGgBuSyAqSmZUmAjYLzD435tcLDRLXr
const wallet = Keypair.fromSecretKey(
utils.bytes.bs58.decode(process.env.SOLANA_CRANK_KEY || "")
);

const main = async (cluster: string) => {
const connection = connectionFor(cluster);

const invalidTimeInvalidators =
await programs.timeInvalidator.accounts.getAllTimeInvalidators(connection);

console.log(
`--------------- ${wallet.publicKey.toString()} found ${
invalidTimeInvalidators.length
} expired invalidators found on ${cluster} ---------------`
);

for (let i = 0; i < invalidTimeInvalidators.length; i++) {
const timeInvalidatorData = invalidTimeInvalidators[i]!;
try {
console.log(
`\n\n\n\n\n--------------- ${i}/${invalidTimeInvalidators.length}`,
timeInvalidatorData.pubkey.toString(),
timeInvalidatorData.parsed.tokenManager.toString(),
"---------------"
);
const tokenManagerData = await tryGetAccount(() =>
programs.tokenManager.accounts.getTokenManager(
connection,
timeInvalidatorData.parsed.tokenManager
)
);

const transaction = new Transaction();
if (!tokenManagerData) {
transaction.add(
timeInvalidator.instruction.close(
connection,
new SignerWallet(wallet),
timeInvalidatorData.pubkey,
timeInvalidatorData.parsed.tokenManager
)
);
} else if (
tokenManagerData?.parsed.state !== TokenManagerState.Invalidated &&
((timeInvalidatorData.parsed.expiration &&
new BN(Date.now() / 1000).gte(
timeInvalidatorData.parsed.expiration
)) ||
(timeInvalidatorData.parsed.durationSeconds &&
tokenManagerData.parsed.state === TokenManagerState.Claimed &&
new BN(Date.now() / 1000).gte(
tokenManagerData.parsed.stateChangedAt.add(
timeInvalidatorData.parsed.durationSeconds
)
)))
) {
await withInvalidate(
transaction,
tokenManagerData?.parsed.receiptMint
? secondaryConnectionFor(cluster)
: connection,
new SignerWallet(wallet),
tokenManagerData.parsed.mint
);
} else {
console.log(
`Skipping this time invalidator for mint (${tokenManagerData.parsed.mint.toString()})`
);
}

if (transaction && transaction.instructions.length > 0) {
transaction.feePayer = wallet.publicKey;
transaction.recentBlockhash = (
await connection.getRecentBlockhash("max")
).blockhash;
transaction.sign(wallet);
const txid = await sendAndConfirmRawTransaction(
connection,
transaction.serialize()
);
console.log(
`Succesfully invalidated time invalidator (${timeInvalidatorData.pubkey.toBase58()}) token manager id (${
tokenManagerData?.pubkey.toBase58() || ""
}) with txid (${txid})`
);
} else {
console.log(
`No transaction for time invalidator (${timeInvalidatorData.pubkey.toBase58()}) token manager id (${
tokenManagerData?.pubkey.toBase58() || ""
}) mint (${tokenManagerData?.parsed.mint.toBase58() || ""})`
);
}
} catch (e) {
console.log(
`Failed to invalidate time invalidator (${timeInvalidatorData.pubkey.toBase58()})`,
e
);
}
}
};

export const invalidateAll = async (mainnet = true) => {
if (mainnet) {
try {
await main("mainnet");
} catch (e) {
console.log("Failed to invalidate on mainnet: ", e);
}
}

try {
await main("devnet");
} catch (e) {
console.log("Failed to invalidate on devnet: ", e);
}
};
3 changes: 3 additions & 0 deletions api/time-invalidator-crank.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { invalidateAll } from "./time-invalidate-crank/invalidate";

invalidateAll().catch((e) => console.log(e));
14 changes: 14 additions & 0 deletions api/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"compilerOptions": {
"preserveConstEnums": true,
"strictNullChecks": true,
"sourceMap": true,
"allowJs": true,
"target": "es5",
"outDir": ".build",
"moduleResolution": "node",
"lib": ["es2015"],
"rootDir": "./",
"esModuleInterop": true
}
}
Loading

0 comments on commit b1e6a4f

Please sign in to comment.