-
Notifications
You must be signed in to change notification settings - Fork 28
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
7,868 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} | ||
} |
Oops, something went wrong.