@voidifydao/sdk 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/dist/cli/config/command.d.ts +2 -0
  2. package/dist/cli/config/command.js +91 -0
  3. package/dist/cli/config/init.d.ts +3 -0
  4. package/dist/cli/config/init.js +88 -0
  5. package/dist/cli/config/keypair.d.ts +4 -0
  6. package/dist/cli/config/keypair.js +35 -0
  7. package/dist/cli/config/loader.d.ts +11 -0
  8. package/dist/cli/config/loader.js +65 -0
  9. package/dist/cli/config/types.d.ts +50 -0
  10. package/dist/cli/config/types.js +33 -0
  11. package/dist/cli/deposit.d.ts +2 -0
  12. package/dist/cli/deposit.js +58 -0
  13. package/dist/cli/helpers.d.ts +12 -0
  14. package/dist/cli/helpers.js +53 -0
  15. package/dist/cli/note.d.ts +2 -0
  16. package/dist/cli/note.js +50 -0
  17. package/dist/cli/relayer.d.ts +2 -0
  18. package/dist/cli/relayer.js +60 -0
  19. package/dist/cli/substream.d.ts +2 -0
  20. package/dist/cli/substream.js +35 -0
  21. package/dist/cli/withdraw.d.ts +2 -0
  22. package/dist/cli/withdraw.js +23 -0
  23. package/dist/cli.d.ts +2 -0
  24. package/dist/cli.js +30 -0
  25. package/dist/context.d.ts +45 -0
  26. package/dist/context.js +77 -0
  27. package/dist/idl/voidify/idl.d.ts +1313 -0
  28. package/dist/idl/voidify/idl.js +1 -0
  29. package/dist/idl/voidify/idl.json +1307 -0
  30. package/dist/idl/voidify-staking/idl.d.ts +93 -0
  31. package/dist/idl/voidify-staking/idl.js +1 -0
  32. package/dist/idl/voidify-staking/idl.json +87 -0
  33. package/dist/index.d.ts +17 -0
  34. package/dist/index.js +10 -0
  35. package/dist/relayer/server/index.d.ts +6 -0
  36. package/dist/relayer/server/index.js +32 -0
  37. package/dist/relayer/server/server.d.ts +24 -0
  38. package/dist/relayer/server/server.js +158 -0
  39. package/dist/relayer/server/switchboard.d.ts +2 -0
  40. package/dist/relayer/server/switchboard.js +42 -0
  41. package/dist/relayer/types.d.ts +21 -0
  42. package/dist/relayer/types.js +1 -0
  43. package/dist/staking/commands.d.ts +3 -0
  44. package/dist/staking/commands.js +13 -0
  45. package/dist/staking/index.d.ts +2 -0
  46. package/dist/staking/index.js +2 -0
  47. package/dist/staking/program.d.ts +18 -0
  48. package/dist/staking/program.js +40 -0
  49. package/dist/substream/chain/events.d.ts +4 -0
  50. package/dist/substream/chain/events.js +50 -0
  51. package/dist/substream/chain/index.d.ts +24 -0
  52. package/dist/substream/chain/index.js +79 -0
  53. package/dist/substream/chain/registry.d.ts +44 -0
  54. package/dist/substream/chain/registry.js +28 -0
  55. package/dist/substream/chain/utils.d.ts +9 -0
  56. package/dist/substream/chain/utils.js +41 -0
  57. package/dist/substream/client.d.ts +27 -0
  58. package/dist/substream/client.js +28 -0
  59. package/dist/substream/database/indexeddb.d.ts +2 -0
  60. package/dist/substream/database/indexeddb.js +242 -0
  61. package/dist/substream/database/sqlite.d.ts +26 -0
  62. package/dist/substream/database/sqlite.js +275 -0
  63. package/dist/substream/modules/deposit.d.ts +14 -0
  64. package/dist/substream/modules/deposit.js +123 -0
  65. package/dist/substream/modules/index.d.ts +11 -0
  66. package/dist/substream/modules/index.js +7 -0
  67. package/dist/substream/modules/relayer.d.ts +10 -0
  68. package/dist/substream/modules/relayer.js +290 -0
  69. package/dist/substream/runtime.d.ts +38 -0
  70. package/dist/substream/runtime.js +163 -0
  71. package/dist/substream/server/event-listener.d.ts +18 -0
  72. package/dist/substream/server/event-listener.js +68 -0
  73. package/dist/substream/server/index.d.ts +3 -0
  74. package/dist/substream/server/index.js +30 -0
  75. package/dist/substream/server/server.d.ts +43 -0
  76. package/dist/substream/server/server.js +216 -0
  77. package/dist/substream/types.d.ts +94 -0
  78. package/dist/substream/types.js +1 -0
  79. package/dist/types/errors.d.ts +1 -0
  80. package/dist/types/errors.js +16 -0
  81. package/dist/types/events.d.ts +13 -0
  82. package/dist/types/events.js +1 -0
  83. package/dist/types/index.d.ts +3 -0
  84. package/dist/types/index.js +1 -0
  85. package/dist/utils/amount.d.ts +4 -0
  86. package/dist/utils/amount.js +41 -0
  87. package/dist/utils/anchor-events.d.ts +13 -0
  88. package/dist/utils/anchor-events.js +28 -0
  89. package/dist/utils/bytes.d.ts +10 -0
  90. package/dist/utils/bytes.js +29 -0
  91. package/dist/utils/idl-seed.d.ts +17 -0
  92. package/dist/utils/idl-seed.js +15 -0
  93. package/dist/utils/index.d.ts +2 -0
  94. package/dist/utils/index.js +2 -0
  95. package/dist/utils/logger.d.ts +3 -0
  96. package/dist/utils/logger.js +19 -0
  97. package/dist/utils/note.d.ts +19 -0
  98. package/dist/utils/note.js +83 -0
  99. package/dist/utils/proof.d.ts +11 -0
  100. package/dist/utils/proof.js +91 -0
  101. package/dist/utils/tx.d.ts +11 -0
  102. package/dist/utils/tx.js +62 -0
  103. package/dist/voidify/deposit.d.ts +10 -0
  104. package/dist/voidify/deposit.js +40 -0
  105. package/dist/voidify/index.d.ts +4 -0
  106. package/dist/voidify/index.js +4 -0
  107. package/dist/voidify/program.d.ts +36 -0
  108. package/dist/voidify/program.js +87 -0
  109. package/dist/voidify/relayer/index.d.ts +1 -0
  110. package/dist/voidify/relayer/index.js +1 -0
  111. package/dist/voidify/relayer/list.d.ts +5 -0
  112. package/dist/voidify/relayer/list.js +16 -0
  113. package/dist/voidify/withdraw.d.ts +16 -0
  114. package/dist/voidify/withdraw.js +188 -0
  115. package/package.json +79 -0
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Program IDL in camelCase format in order to be used in JS/TS.
3
+ *
4
+ * Note that this is only a type helper and is not the actual IDL. The original
5
+ * IDL can be found at `target/idl/voidify_staking.json`.
6
+ */
7
+ export type VoidifyStaking = {
8
+ "address": "";
9
+ "metadata": {
10
+ "name": "voidifyStaking";
11
+ "version": "1.0.1";
12
+ "spec": "0.1.0";
13
+ };
14
+ "instructions": [
15
+ {
16
+ "name": "notifyRewardAmount";
17
+ "discriminator": [
18
+ 228,
19
+ 154,
20
+ 113,
21
+ 244,
22
+ 155,
23
+ 76,
24
+ 153,
25
+ 136
26
+ ];
27
+ "accounts": [
28
+ {
29
+ "name": "caller";
30
+ "signer": true;
31
+ },
32
+ {
33
+ "name": "stakingState";
34
+ "writable": true;
35
+ "pda": {
36
+ "seeds": [
37
+ {
38
+ "kind": "const";
39
+ "value": [
40
+ 115,
41
+ 116,
42
+ 97,
43
+ 107,
44
+ 105,
45
+ 110,
46
+ 103,
47
+ 95,
48
+ 115,
49
+ 116,
50
+ 97,
51
+ 116,
52
+ 101
53
+ ];
54
+ }
55
+ ];
56
+ };
57
+ },
58
+ {
59
+ "name": "rewardVault";
60
+ "pda": {
61
+ "seeds": [
62
+ {
63
+ "kind": "const";
64
+ "value": [
65
+ 114,
66
+ 101,
67
+ 119,
68
+ 97,
69
+ 114,
70
+ 100,
71
+ 95,
72
+ 118,
73
+ 97,
74
+ 117,
75
+ 108,
76
+ 116
77
+ ];
78
+ }
79
+ ];
80
+ };
81
+ },
82
+ {
83
+ "name": "tokenProgram";
84
+ "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA";
85
+ }
86
+ ];
87
+ "args": [];
88
+ }
89
+ ];
90
+ "accounts": [];
91
+ "events": [];
92
+ "types": [];
93
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,87 @@
1
+ {
2
+ "address": "3K12np4CKy8WbQim78trY6Pdii8wHQiWpQ4dMdsCKXYo",
3
+ "metadata": {
4
+ "name": "voidify_staking",
5
+ "version": "1.0.1",
6
+ "spec": "0.1.0"
7
+ },
8
+ "instructions": [
9
+ {
10
+ "name": "",
11
+ "discriminator": [
12
+ 228,
13
+ 154,
14
+ 113,
15
+ 244,
16
+ 155,
17
+ 76,
18
+ 153,
19
+ 136
20
+ ],
21
+ "accounts": [
22
+ {
23
+ "name": "caller",
24
+ "signer": true
25
+ },
26
+ {
27
+ "name": "staking_state",
28
+ "writable": true,
29
+ "pda": {
30
+ "seeds": [
31
+ {
32
+ "kind": "const",
33
+ "value": [
34
+ 115,
35
+ 116,
36
+ 97,
37
+ 107,
38
+ 105,
39
+ 110,
40
+ 103,
41
+ 95,
42
+ 115,
43
+ 116,
44
+ 97,
45
+ 116,
46
+ 101
47
+ ]
48
+ }
49
+ ]
50
+ }
51
+ },
52
+ {
53
+ "name": "reward_vault",
54
+ "pda": {
55
+ "seeds": [
56
+ {
57
+ "kind": "const",
58
+ "value": [
59
+ 114,
60
+ 101,
61
+ 119,
62
+ 97,
63
+ 114,
64
+ 100,
65
+ 95,
66
+ 118,
67
+ 97,
68
+ 117,
69
+ 108,
70
+ 116
71
+ ]
72
+ }
73
+ ]
74
+ }
75
+ },
76
+ {
77
+ "name": "token_program",
78
+ "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
79
+ }
80
+ ],
81
+ "args": []
82
+ }
83
+ ],
84
+ "accounts": [],
85
+ "events": [],
86
+ "types": []
87
+ }
@@ -0,0 +1,17 @@
1
+ export { Context } from "./context.js";
2
+ export type { SubstreamConfig, SubstreamMode } from "./context.js";
3
+ export * as voidify from "./voidify/index.js";
4
+ export * as staking from "./staking/index.js";
5
+ export { VoidifyProgram } from "./voidify/program.js";
6
+ export { VoidifyStakingProgram } from "./staking/program.js";
7
+ export type { WithdrawArtifact } from "./voidify/withdraw.js";
8
+ export { SubstreamCliClient } from "./substream/client.js";
9
+ export type { SubstreamCliConfig, EventsApiResponse, CursorWire, } from "./substream/client.js";
10
+ export { makeIndexedDBStores } from "./substream/database/indexeddb.js";
11
+ export type { DepositModuleApi, RelayerModuleApi, } from "./substream/modules/index.js";
12
+ export type { DepositRecord, RelayerRecord, EventCursor, ApplyOutcome, ChainEventRecord, ChainEventWire, EventScope, EventStore, EventProjection, ProjectionStateRecord, ProjectionStateValue, ProjectionStore, SubstreamRepos, SubstreamStores, } from "./substream/types.js";
13
+ export { Note, TOKEN_DECIMALS } from "./utils/note.js";
14
+ export { parseUnits, formatUnits, toBN } from "./utils/amount.js";
15
+ export type { Voidify } from "./idl/voidify/idl.js";
16
+ export * from "./types/index.js";
17
+ export type { RelayerInfo, WithdrawRequestBody, WithdrawResponse, } from "./relayer/types.js";
package/dist/index.js ADDED
@@ -0,0 +1,10 @@
1
+ export { Context } from "./context.js";
2
+ export * as voidify from "./voidify/index.js";
3
+ export * as staking from "./staking/index.js";
4
+ export { VoidifyProgram } from "./voidify/program.js";
5
+ export { VoidifyStakingProgram } from "./staking/program.js";
6
+ export { SubstreamCliClient } from "./substream/client.js";
7
+ export { makeIndexedDBStores } from "./substream/database/indexeddb.js";
8
+ export { Note, TOKEN_DECIMALS } from "./utils/note.js";
9
+ export { parseUnits, formatUnits, toBN } from "./utils/amount.js";
10
+ export * from "./types/index.js";
@@ -0,0 +1,6 @@
1
+ import { Context } from "../../context.js";
2
+ export declare function startRelayer(ctx: Context, config: {
3
+ port: number;
4
+ host: string;
5
+ feedId: string;
6
+ }): Promise<string>;
@@ -0,0 +1,32 @@
1
+ import { RelayerHttpServer } from "../../relayer/server/server.js";
2
+ import { relayerLogger as logger } from "../../utils/logger.js";
3
+ export async function startRelayer(ctx, config) {
4
+ process.on("unhandledRejection", (reason) => {
5
+ logger.error({ reason }, "unhandledRejection");
6
+ });
7
+ process.on("uncaughtException", (err) => {
8
+ logger.error({ err }, "uncaughtException");
9
+ process.exit(1);
10
+ });
11
+ logger.info({
12
+ relayer: ctx.publicKey.toBase58(),
13
+ host: config.host,
14
+ port: config.port,
15
+ }, "Starting Relayer service");
16
+ const server = new RelayerHttpServer(ctx, config);
17
+ await server.start();
18
+ const shutdown = async (sig) => {
19
+ logger.info({ sig }, "shutting down relayer");
20
+ try {
21
+ await server.stop();
22
+ }
23
+ catch (err) {
24
+ logger.error({ err }, "relayer stop failed");
25
+ }
26
+ process.exit(0);
27
+ };
28
+ process.on("SIGINT", () => void shutdown("SIGINT"));
29
+ process.on("SIGTERM", () => void shutdown("SIGTERM"));
30
+ await new Promise(() => { });
31
+ return `http://${config.host}:${config.port}`;
32
+ }
@@ -0,0 +1,24 @@
1
+ import { Context } from "../../context.js";
2
+ export interface RelayerServerConfig {
3
+ port: number;
4
+ host?: string;
5
+ feedId: string;
6
+ }
7
+ export declare class RelayerHttpServer {
8
+ private ctx;
9
+ private app;
10
+ private server;
11
+ private readonly host;
12
+ private readonly port;
13
+ private readonly feedId;
14
+ constructor(ctx: Context, config: RelayerServerConfig);
15
+ private setupMiddleware;
16
+ private setupRoutes;
17
+ private handleHealth;
18
+ private handleWithdraw;
19
+ private validateWithdrawRequest;
20
+ private getSwitchboardQuote;
21
+ getAddress(): string;
22
+ start(): Promise<void>;
23
+ stop(): Promise<void>;
24
+ }
@@ -0,0 +1,158 @@
1
+ import express from "express";
2
+ import cors from "cors";
3
+ import { updateQuote } from "./switchboard.js";
4
+ import { withdrawIx } from "../../voidify/withdraw.js";
5
+ import { notifyRewardAmountIx } from "../../staking/commands.js";
6
+ import { signAndSend } from "../../utils/tx.js";
7
+ import { relayerLogger as logger } from "../../utils/logger.js";
8
+ export class RelayerHttpServer {
9
+ ctx;
10
+ app;
11
+ server = null;
12
+ host;
13
+ port;
14
+ feedId;
15
+ constructor(ctx, config) {
16
+ this.ctx = ctx;
17
+ this.port = config.port;
18
+ this.host = config.host || "0.0.0.0";
19
+ this.feedId = config.feedId;
20
+ this.app = express();
21
+ this.setupMiddleware();
22
+ this.setupRoutes();
23
+ }
24
+ setupMiddleware() {
25
+ this.app.use(cors());
26
+ this.app.use(express.json());
27
+ this.app.use((req, _res, next) => {
28
+ logger.info({ method: req.method, path: req.path }, "HTTP request");
29
+ next();
30
+ });
31
+ }
32
+ setupRoutes() {
33
+ this.app.get("/health", this.handleHealth.bind(this));
34
+ this.app.post("/api/relay/withdraw", this.handleWithdraw.bind(this));
35
+ this.app.use((req, res) => {
36
+ res.status(404).json({ error: "Not found" });
37
+ });
38
+ this.app.use((err, req, res, _next) => {
39
+ logger.error({ err, method: req.method, path: req.path }, "unhandled express error");
40
+ res.status(500).json({ error: "Internal server error" });
41
+ });
42
+ }
43
+ async handleHealth(req, res) {
44
+ res.json({
45
+ status: "ok",
46
+ timestamp: Date.now(),
47
+ relayer: this.ctx.publicKey.toBase58(),
48
+ });
49
+ }
50
+ async handleWithdraw(req, res) {
51
+ try {
52
+ const body = req.body;
53
+ const validationError = this.validateWithdrawRequest(body);
54
+ if (validationError) {
55
+ res.status(400).json({
56
+ success: false,
57
+ error: validationError,
58
+ });
59
+ return;
60
+ }
61
+ await updateQuote(this.ctx, this.feedId);
62
+ const switchboardQuote = await this.getSwitchboardQuote();
63
+ const ixs = await withdrawIx(this.ctx, new Uint8Array(body.proof), new Uint8Array(body.root), new Uint8Array(body.nullifierHash), body.recipient, this.ctx.publicKey.toBase58(), BigInt(body.fee), BigInt(body.treasury), switchboardQuote, BigInt(body.amount));
64
+ if (this.ctx.hasStakingProgramId()) {
65
+ const notifyIxs = await notifyRewardAmountIx(this.ctx, this.ctx.publicKey);
66
+ ixs.push(...notifyIxs);
67
+ }
68
+ const signature = await signAndSend(this.ctx, ixs);
69
+ logger.info({ signature }, "withdraw submitted");
70
+ res.json({
71
+ success: true,
72
+ signature,
73
+ });
74
+ }
75
+ catch (error) {
76
+ logger.error({ error }, "Failed to withdraw");
77
+ res.status(500).json({
78
+ success: false,
79
+ error: error instanceof Error ? error.message : String(error),
80
+ });
81
+ }
82
+ }
83
+ validateWithdrawRequest(body) {
84
+ if (!body.proof ||
85
+ !Array.isArray(body.proof) ||
86
+ body.proof.length !== 256) {
87
+ return "Invalid proof: must be an array of 256 bytes";
88
+ }
89
+ if (!body.root || !Array.isArray(body.root) || body.root.length !== 32) {
90
+ return "Invalid root: must be an array of 32 bytes";
91
+ }
92
+ if (!body.nullifierHash ||
93
+ !Array.isArray(body.nullifierHash) ||
94
+ body.nullifierHash.length !== 32) {
95
+ return "Invalid nullifierHash: must be an array of 32 bytes";
96
+ }
97
+ if (!body.recipient || typeof body.recipient !== "string") {
98
+ return "Invalid recipient: must be a string";
99
+ }
100
+ for (const field of ["fee", "treasury", "amount"]) {
101
+ const value = body[field];
102
+ if (value === undefined || value === null) {
103
+ return `Missing ${field}`;
104
+ }
105
+ try {
106
+ if (BigInt(value) < 0n) {
107
+ return `Invalid ${field}: must be non-negative`;
108
+ }
109
+ }
110
+ catch {
111
+ return `Invalid ${field}: not a valid integer`;
112
+ }
113
+ }
114
+ return null;
115
+ }
116
+ async getSwitchboardQuote() {
117
+ const sb = await import("@switchboard-xyz/on-demand");
118
+ const queue = await sb.Queue.loadDefault(await sb.AnchorUtils.loadProgramFromConnection(this.ctx.connection));
119
+ const [quotePDA] = sb.OracleQuote.getCanonicalPubkey(queue.pubkey, [
120
+ this.feedId,
121
+ ]);
122
+ return quotePDA;
123
+ }
124
+ getAddress() {
125
+ return `http://${this.host}:${this.port}`;
126
+ }
127
+ async start() {
128
+ return new Promise((resolve, reject) => {
129
+ this.server = this.app.listen(this.port, this.host, (error) => {
130
+ if (error) {
131
+ reject(error);
132
+ }
133
+ else {
134
+ logger.info({ address: this.getAddress() }, "HTTP server listening");
135
+ resolve();
136
+ }
137
+ });
138
+ });
139
+ }
140
+ async stop() {
141
+ return new Promise((resolve, reject) => {
142
+ if (this.server) {
143
+ this.server.close((error) => {
144
+ if (error) {
145
+ reject(error);
146
+ }
147
+ else {
148
+ logger.info("HTTP server stopped");
149
+ resolve();
150
+ }
151
+ });
152
+ }
153
+ else {
154
+ resolve();
155
+ }
156
+ });
157
+ }
158
+ }
@@ -0,0 +1,2 @@
1
+ import { Context } from "../../context.js";
2
+ export declare function updateQuote(ctx: Context, feedID: string): Promise<void>;
@@ -0,0 +1,42 @@
1
+ import * as sb from "@switchboard-xyz/on-demand";
2
+ import { CrossbarClient } from "@switchboard-xyz/common";
3
+ import { signAndSend } from "../../utils/tx.js";
4
+ import { VoidifyProgram } from "../../voidify/program.js";
5
+ async function getQuoteSlot(ctx, quotePDA) {
6
+ try {
7
+ const signatures = await ctx.connection.getSignaturesForAddress(quotePDA, {
8
+ limit: 1,
9
+ });
10
+ return signatures.length ? signatures[0].slot : 0;
11
+ }
12
+ catch (error) {
13
+ throw new Error("Failed to fetch quote slot from chain", {
14
+ cause: error,
15
+ });
16
+ }
17
+ }
18
+ export async function updateQuote(ctx, feedID) {
19
+ const voidifyProgram = new VoidifyProgram(ctx.connection, ctx.programId);
20
+ const oracleConfig = await voidifyProgram.program.account.oracleConfig.fetch(voidifyProgram.oracleConfig());
21
+ const maxPriceAgeSlots = (BigInt(oracleConfig.maxPriceAgeSecs.toString()) * 1000n) / 400n;
22
+ const queue = await sb.Queue.loadDefault(await sb.AnchorUtils.loadProgramFromConnection(ctx.connection));
23
+ const crossbar = CrossbarClient.default();
24
+ const currentSlot = await ctx.connection.getSlot("confirmed");
25
+ const [quotePDA] = sb.OracleQuote.getCanonicalPubkey(queue.pubkey, [feedID]);
26
+ const quoteSlot = await getQuoteSlot(ctx, quotePDA);
27
+ if (BigInt(currentSlot - quoteSlot) >= maxPriceAgeSlots) {
28
+ const ixs = await queue.fetchManagedUpdateIxs(crossbar, [feedID], {
29
+ variableOverrides: {},
30
+ instructionIdx: 0,
31
+ payer: ctx.publicKey,
32
+ });
33
+ const tx = await sb.asV0Tx({
34
+ connection: ctx.connection,
35
+ ixs: ixs,
36
+ payer: ctx.publicKey,
37
+ computeUnitPrice: 20_000,
38
+ computeUnitLimitMultiple: 1.1,
39
+ });
40
+ await signAndSend(ctx, tx);
41
+ }
42
+ }
@@ -0,0 +1,21 @@
1
+ export interface WithdrawRequestBody {
2
+ proof: number[];
3
+ root: number[];
4
+ nullifierHash: number[];
5
+ recipient: string;
6
+ amount: string;
7
+ fee: string;
8
+ treasury: string;
9
+ }
10
+ export interface WithdrawResponse {
11
+ success: boolean;
12
+ signature?: string;
13
+ error?: string;
14
+ }
15
+ export interface RelayerInfo {
16
+ publicKey: string;
17
+ stakeAmount: string;
18
+ feeBps: number;
19
+ url: string;
20
+ isActive: boolean;
21
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,3 @@
1
+ import { PublicKey, TransactionInstruction } from "@solana/web3.js";
2
+ import { Context } from "../context.js";
3
+ export declare function notifyRewardAmountIx(ctx: Context, caller?: PublicKey): Promise<TransactionInstruction[]>;
@@ -0,0 +1,13 @@
1
+ import { VoidifyStakingProgram } from "./program.js";
2
+ export async function notifyRewardAmountIx(ctx, caller) {
3
+ const staking = new VoidifyStakingProgram(ctx.connection, ctx.stakingProgramId);
4
+ const ix = await staking.program.methods
5
+ .notifyRewardAmount()
6
+ .accountsPartial({
7
+ caller: caller ?? ctx.publicKey,
8
+ stakingState: staking.stakingState(),
9
+ rewardVault: staking.rewardVault(),
10
+ })
11
+ .instruction();
12
+ return [ix];
13
+ }
@@ -0,0 +1,2 @@
1
+ export { VoidifyStakingProgram } from "./program.js";
2
+ export * from "./commands.js";
@@ -0,0 +1,2 @@
1
+ export { VoidifyStakingProgram } from "./program.js";
2
+ export * from "./commands.js";
@@ -0,0 +1,18 @@
1
+ import { Program } from "@coral-xyz/anchor";
2
+ import { Connection, PublicKey } from "@solana/web3.js";
3
+ import type { VoidifyStaking } from "../idl/voidify-staking/idl.js";
4
+ export declare class VoidifyStakingProgram {
5
+ private connection;
6
+ private _program;
7
+ private _programId;
8
+ static readonly SEEDS: {
9
+ readonly STAKING_STATE: Buffer<ArrayBufferLike>;
10
+ readonly REWARD_VAULT: Buffer<ArrayBufferLike>;
11
+ };
12
+ constructor(connection: Connection, programId: PublicKey);
13
+ get program(): Program<VoidifyStaking>;
14
+ get programId(): PublicKey;
15
+ get rpcConnection(): Connection;
16
+ stakingState(): PublicKey;
17
+ rewardVault(): PublicKey;
18
+ }
@@ -0,0 +1,40 @@
1
+ import { Program } from "@coral-xyz/anchor";
2
+ import { PublicKey } from "@solana/web3.js";
3
+ import idl from "../idl/voidify-staking/idl.json" with { type: "json" };
4
+ import { getConstSeed } from "../utils/idl-seed.js";
5
+ export class VoidifyStakingProgram {
6
+ connection;
7
+ _program = null;
8
+ _programId;
9
+ static SEEDS = {
10
+ STAKING_STATE: getConstSeed(idl, "staking_state"),
11
+ REWARD_VAULT: getConstSeed(idl, "reward_vault"),
12
+ };
13
+ constructor(connection, programId) {
14
+ this.connection = connection;
15
+ this._programId = programId;
16
+ }
17
+ get program() {
18
+ if (!this._program) {
19
+ idl["address"] = this._programId.toBase58();
20
+ this._program = new Program(idl, {
21
+ connection: this.connection,
22
+ });
23
+ }
24
+ return this._program;
25
+ }
26
+ get programId() {
27
+ return this._programId;
28
+ }
29
+ get rpcConnection() {
30
+ return this.connection;
31
+ }
32
+ stakingState() {
33
+ const [pda] = PublicKey.findProgramAddressSync([VoidifyStakingProgram.SEEDS.STAKING_STATE], this._programId);
34
+ return pda;
35
+ }
36
+ rewardVault() {
37
+ const [pda] = PublicKey.findProgramAddressSync([VoidifyStakingProgram.SEEDS.REWARD_VAULT], this._programId);
38
+ return pda;
39
+ }
40
+ }
@@ -0,0 +1,4 @@
1
+ import type { ChainEventPayload, ChainEventRecord, ChainEventWire } from "../../substream/types.js";
2
+ export declare function chainEventToWire(event: ChainEventRecord): ChainEventWire;
3
+ export declare function chainEventFromWire(wire: ChainEventWire): ChainEventRecord;
4
+ export declare function normalizePayload(value: unknown): ChainEventPayload;
@@ -0,0 +1,50 @@
1
+ export function chainEventToWire(event) {
2
+ return { ...event, eventIndex: event.eventIndex.toString() };
3
+ }
4
+ export function chainEventFromWire(wire) {
5
+ return { ...wire, eventIndex: BigInt(wire.eventIndex) };
6
+ }
7
+ export function normalizePayload(value) {
8
+ if (!value || typeof value !== "object")
9
+ return {};
10
+ const out = {};
11
+ for (const [key, item] of Object.entries(value)) {
12
+ out[key] = normalizeValue(item);
13
+ }
14
+ return out;
15
+ }
16
+ function normalizeValue(value) {
17
+ if (typeof value === "bigint")
18
+ return value.toString();
19
+ if (typeof value === "number" || typeof value === "string")
20
+ return value;
21
+ if (typeof value === "boolean" || value === null || value === undefined) {
22
+ return value ?? null;
23
+ }
24
+ if (Array.isArray(value))
25
+ return value.map((v) => normalizeValue(v));
26
+ if (value instanceof Uint8Array) {
27
+ return Array.from(value)
28
+ .map((item) => item.toString(16).padStart(2, "0"))
29
+ .join("");
30
+ }
31
+ if (typeof value === "object" &&
32
+ "toBase58" in value &&
33
+ typeof value.toBase58 === "function") {
34
+ return value.toBase58();
35
+ }
36
+ if (typeof value === "object" &&
37
+ "toString" in value &&
38
+ typeof value.toString === "function" &&
39
+ value.constructor?.name === "BN") {
40
+ return value.toString();
41
+ }
42
+ if (typeof value === "object") {
43
+ const out = {};
44
+ for (const [key, item] of Object.entries(value)) {
45
+ out[key] = normalizeValue(item);
46
+ }
47
+ return out;
48
+ }
49
+ return String(value);
50
+ }