@helium/blockchain-api 0.1.2 → 0.1.3

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 (52) hide show
  1. package/README.md +24 -2
  2. package/package.json +31 -31
  3. package/types/README.md +24 -2
  4. package/types/generated/index.d.mts +2481 -0
  5. package/types/generated/index.d.ts +2481 -0
  6. package/types/generated/index.js +723 -0
  7. package/types/generated/index.mjs +614 -0
  8. package/types/index.ts +11 -8
  9. package/src/server/api/errors.ts +0 -152
  10. package/src/server/api/index.ts +0 -40
  11. package/src/server/api/procedures.ts +0 -144
  12. package/src/server/api/routers/fiat/router.ts +0 -709
  13. package/src/server/api/routers/fiat/schemas.ts +0 -169
  14. package/src/server/api/routers/health/router.ts +0 -41
  15. package/src/server/api/routers/hotspots/procedures/claimRewards.ts +0 -258
  16. package/src/server/api/routers/hotspots/procedures/createSplit.ts +0 -253
  17. package/src/server/api/routers/hotspots/procedures/deleteSplit.ts +0 -156
  18. package/src/server/api/routers/hotspots/procedures/getHotspots.ts +0 -31
  19. package/src/server/api/routers/hotspots/procedures/getPendingRewards.ts +0 -44
  20. package/src/server/api/routers/hotspots/procedures/getSplit.ts +0 -88
  21. package/src/server/api/routers/hotspots/procedures/transferHotspot.ts +0 -204
  22. package/src/server/api/routers/hotspots/procedures/updateRewardsDestination.ts +0 -201
  23. package/src/server/api/routers/hotspots/router.ts +0 -30
  24. package/src/server/api/routers/hotspots/schemas.ts +0 -182
  25. package/src/server/api/routers/swap/procedures/getInstructions.ts +0 -152
  26. package/src/server/api/routers/swap/procedures/getQuote.ts +0 -53
  27. package/src/server/api/routers/swap/procedures/getTokens.ts +0 -88
  28. package/src/server/api/routers/swap/router.ts +0 -15
  29. package/src/server/api/routers/swap/schemas.ts +0 -96
  30. package/src/server/api/routers/tokens/procedures/createHntAccount.ts +0 -87
  31. package/src/server/api/routers/tokens/procedures/getBalances.ts +0 -27
  32. package/src/server/api/routers/tokens/procedures/transfer.ts +0 -159
  33. package/src/server/api/routers/tokens/router.ts +0 -15
  34. package/src/server/api/routers/tokens/schemas.ts +0 -80
  35. package/src/server/api/routers/transactions/procedures/get.ts +0 -46
  36. package/src/server/api/routers/transactions/procedures/getByPayer.ts +0 -111
  37. package/src/server/api/routers/transactions/procedures/getByPayerAndTag.ts +0 -119
  38. package/src/server/api/routers/transactions/procedures/resubmit.ts +0 -68
  39. package/src/server/api/routers/transactions/procedures/submit.ts +0 -216
  40. package/src/server/api/routers/transactions/router.ts +0 -21
  41. package/src/server/api/routers/transactions/schemas.ts +0 -119
  42. package/src/server/api/routers/webhooks/router.ts +0 -75
  43. package/src/server/api/routers/welcomePacks/procedures/claim.ts +0 -157
  44. package/src/server/api/routers/welcomePacks/procedures/create.ts +0 -247
  45. package/src/server/api/routers/welcomePacks/procedures/deletePack.ts +0 -118
  46. package/src/server/api/routers/welcomePacks/procedures/get.ts +0 -36
  47. package/src/server/api/routers/welcomePacks/procedures/getByAddress.ts +0 -26
  48. package/src/server/api/routers/welcomePacks/procedures/invite.ts +0 -44
  49. package/src/server/api/routers/welcomePacks/procedures/list.ts +0 -27
  50. package/src/server/api/routers/welcomePacks/router.ts +0 -27
  51. package/src/server/api/routers/welcomePacks/schemas.ts +0 -135
  52. package/src/server/api/schemas.ts +0 -281
@@ -1,169 +0,0 @@
1
- import { z } from "zod";
2
- import { QuoteResponseSchema } from "../swap/schemas";
3
-
4
- // ============================================================================
5
- // Input Schemas
6
- // ============================================================================
7
-
8
- export const InitKycInputSchema = z.object({
9
- type: z.enum(["individual", "business"]).optional(),
10
- });
11
-
12
- export const CreateBankAccountInputSchema = z.object({
13
- currency: z.string(),
14
- account_type: z.string(),
15
- bank_name: z.string(),
16
- account_name: z.string(),
17
- first_name: z.string().optional(),
18
- last_name: z.string().optional(),
19
- account_owner_name: z.string().optional(),
20
- business_name: z.string().optional(),
21
- account: z.object({
22
- account_number: z.string(),
23
- routing_number: z.string(),
24
- checking_or_savings: z.string(),
25
- }),
26
- address: z.object({
27
- street_line_1: z.string(),
28
- line2: z.string().optional(),
29
- city: z.string(),
30
- state: z.string(),
31
- postal_code: z.string(),
32
- country: z.string(),
33
- }),
34
- });
35
-
36
- export const GetBankAccountInputSchema = z.object({
37
- id: z.string(),
38
- });
39
-
40
- export const DeleteBankAccountInputSchema = z.object({
41
- id: z.number(),
42
- });
43
-
44
- export const GetSendQuoteInputSchema = z.object({
45
- id: z.string(),
46
- usdAmount: z.string(),
47
- });
48
-
49
- export const SendFundsInputSchema = z.object({
50
- id: z.string(),
51
- userAddress: z.string(),
52
- quoteResponse: z
53
- .object({
54
- inputMint: z.string(),
55
- inAmount: z.string(),
56
- outputMint: z.string(),
57
- outAmount: z.string(),
58
- otherAmountThreshold: z.string(),
59
- swapMode: z.string(),
60
- slippageBps: z.number(),
61
- platformFee: z.unknown().optional(),
62
- priceImpactPct: z.string(),
63
- routePlan: z.array(z.unknown()),
64
- contextSlot: z.number().optional(),
65
- timeTaken: z.number().optional(),
66
- })
67
- .passthrough(), // Allow additional fields from Jupiter
68
- });
69
-
70
- export const GetTransferInputSchema = z.object({
71
- id: z.string(),
72
- });
73
-
74
- export const UpdateTransferInputSchema = z.object({
75
- id: z.string(),
76
- solanaSignature: z.string(),
77
- });
78
-
79
- // ============================================================================
80
- // Output Schemas
81
- // ============================================================================
82
-
83
- export const KycStatusOutputSchema = z.object({
84
- kycStatus: z.string(),
85
- tosStatus: z.string(),
86
- tosLink: z.string().nullable(),
87
- kycLink: z.string().nullable(),
88
- kycLinkId: z.string().nullable(),
89
- accountType: z.string().optional(),
90
- rejectionReasons: z.array(z.string()).optional(),
91
- });
92
-
93
- export const FeesOutputSchema = z.object({
94
- developer_fee: z.string(),
95
- developer_fee_percent: z.number(),
96
- });
97
-
98
- export const BankAccountSchema = z
99
- .object({
100
- id: z.number().optional(),
101
- bridgeUserId: z.number().optional(),
102
- bridgeExternalAccountId: z.string().optional(),
103
- accountName: z.string().optional(),
104
- bankName: z.string().optional(),
105
- lastFourDigits: z.string().optional(),
106
- routingNumber: z.string().optional(),
107
- accountType: z.string().optional(),
108
- createdAt: z.union([z.string(), z.date()]).optional(),
109
- updatedAt: z.union([z.string(), z.date()]).optional(),
110
- })
111
- .passthrough();
112
-
113
- export const BankAccountListOutputSchema = z.array(BankAccountSchema);
114
-
115
- export const DeleteBankAccountOutputSchema = z.object({
116
- success: z.boolean(),
117
- });
118
-
119
- export const TransactionMetadataSchema = z
120
- .object({
121
- type: z.string(),
122
- description: z.string(),
123
- })
124
- .catchall(z.unknown());
125
-
126
- export const TransactionItemSchema = z.object({
127
- serializedTransaction: z.string(),
128
- metadata: TransactionMetadataSchema.optional(),
129
- });
130
-
131
- export const TransactionDataSchema = z.object({
132
- transactions: z.array(TransactionItemSchema),
133
- parallel: z.boolean(),
134
- tag: z.string().optional(),
135
- });
136
-
137
- export const BridgeTransferSchema = z
138
- .object({
139
- id: z.string(),
140
- state: z.string(),
141
- source_deposit_instructions: z.object({
142
- to_address: z.string(),
143
- }),
144
- })
145
- .passthrough();
146
-
147
- export const SendFundsOutputSchema = z.object({
148
- bridgeTransfer: BridgeTransferSchema,
149
- transactionData: TransactionDataSchema,
150
- });
151
-
152
- export const UpdateTransferOutputSchema = z.object({
153
- success: z.boolean(),
154
- });
155
-
156
- // Quote response is pass-through from Jupiter
157
- export const QuoteOutputSchema = QuoteResponseSchema;
158
-
159
- // ============================================================================
160
- // Type Exports
161
- // ============================================================================
162
-
163
- export type InitKycInput = z.infer<typeof InitKycInputSchema>;
164
- export type CreateBankAccountInput = z.infer<
165
- typeof CreateBankAccountInputSchema
166
- >;
167
- export type KycStatusOutput = z.infer<typeof KycStatusOutputSchema>;
168
- export type FeesOutput = z.infer<typeof FeesOutputSchema>;
169
- export type BridgeTransfer = z.infer<typeof BridgeTransferSchema>;
@@ -1,41 +0,0 @@
1
- import { z } from "zod";
2
- import { publicProcedure } from "../../procedures";
3
- import { connectToDb } from "@/lib/utils/db";
4
-
5
- // ============================================================================
6
- // Schemas
7
- // ============================================================================
8
-
9
- const HealthResponseSchema = z.object({
10
- ok: z.boolean(),
11
- error: z.string().optional(),
12
- });
13
-
14
- // ============================================================================
15
- // Procedures
16
- // ============================================================================
17
-
18
- /**
19
- * Health check procedure.
20
- * Verifies API and database connectivity.
21
- */
22
- const check = publicProcedure
23
- .route({ method: "GET", path: "/health" })
24
- .output(HealthResponseSchema)
25
- .handler(async () => {
26
- try {
27
- await connectToDb();
28
- return { ok: true };
29
- } catch (error) {
30
- console.error("Health check failed:", error);
31
- return { ok: false, error: "Database connection failed" };
32
- }
33
- });
34
-
35
- // ============================================================================
36
- // Router Export
37
- // ============================================================================
38
-
39
- export const healthRouter = {
40
- check,
41
- };
@@ -1,258 +0,0 @@
1
- import { publicProcedure } from "../../../procedures";
2
- import { ClaimRewardsInputSchema, ClaimRewardsOutputSchema } from "../schemas";
3
- import { getSingleton } from "@helium/account-fetch-cache";
4
- import {
5
- getHotspotsByOwner,
6
- getNumRecipientsNeeded,
7
- } from "@/lib/queries/hotspots";
8
- import { env } from "@/lib/env";
9
- import { createSolanaConnection } from "@/lib/solana";
10
- import { init as initLd } from "@helium/lazy-distributor-sdk";
11
- import {
12
- formBulkTransactions,
13
- getBulkRewards,
14
- } from "@/utils/distributorOracle";
15
- import {
16
- LAMPORTS_PER_SOL,
17
- PublicKey,
18
- SystemProgram,
19
- TransactionInstruction,
20
- VersionedTransaction,
21
- } from "@solana/web3.js";
22
- import * as anchor from "@coral-xyz/anchor";
23
- import {
24
- customSignerKey,
25
- init as initTuktuk,
26
- nextAvailableTaskIds,
27
- taskKey,
28
- taskQueueAuthorityKey,
29
- } from "@helium/tuktuk-sdk";
30
- import {
31
- HELIUM_COMMON_LUT,
32
- HELIUM_COMMON_LUT_DEVNET,
33
- HNT_MINT,
34
- batchInstructionsToTxsWithPriorityFee,
35
- toVersionedTx,
36
- } from "@helium/spl-utils";
37
- import { HNT_LAZY_DISTRIBUTOR_ADDRESS } from "@/lib/constants/lazy-distributor";
38
- import { getAssociatedTokenAddressSync } from "@solana/spl-token";
39
-
40
- const MIN_RENT = 0.00089088;
41
- const RECIPIENT_RENT = 0.00242208;
42
- const ATA_RENT = 0.002039 * LAMPORTS_PER_SOL;
43
- const MIN_RENT_LAMPORTS = Math.ceil(MIN_RENT * LAMPORTS_PER_SOL);
44
- const RECIPIENT_RENT_LAMPORTS = Math.ceil(RECIPIENT_RENT * LAMPORTS_PER_SOL);
45
- const ATA_RENT_LAMPORTS = Math.ceil(ATA_RENT);
46
-
47
- const HPL_CRONS_PROGRAM_ID = new PublicKey(
48
- "hcrLPFgFUY6sCUKzqLWxXx5bntDiDCrAZVcrXfx9AHu",
49
- );
50
- const TASK_QUEUE_ID = new PublicKey(
51
- process.env.HPL_CRONS_TASK_QUEUE ||
52
- "H39gEszvsi6AT4rYBiJTuZHJSF5hMHy6CKGTd7wzhsg7",
53
- );
54
-
55
- /**
56
- * Create transactions to claim rewards for all hotspots in a wallet.
57
- * For wallets with 3 or fewer hotspots, returns direct claim transactions.
58
- * For larger wallets, creates a Tuktuk task to process claims.
59
- */
60
- export const claimRewards = publicProcedure
61
- .route({ method: "POST", path: "/hotspots/wallet/{walletAddress}/claim" })
62
- .input(ClaimRewardsInputSchema)
63
- .output(ClaimRewardsOutputSchema)
64
- .errors({
65
- BAD_REQUEST: { message: "Invalid request" },
66
- INSUFFICIENT_FUNDS: {
67
- message: "Insufficient SOL balance to fund claim task",
68
- },
69
- })
70
- .handler(async ({ input, errors }) => {
71
- const { walletAddress } = input;
72
-
73
- // Single query: fetch up to 3 hotspots and total count
74
- const hotspotsData = await getHotspotsByOwner({
75
- owner: walletAddress,
76
- page: 1,
77
- limit: 3,
78
- });
79
- const { total } = hotspotsData;
80
-
81
- // For small wallets, request direct claim transactions
82
- if (total <= 3) {
83
- const assets = hotspotsData.hotspots.map((h) => new PublicKey(h.asset));
84
- const entityKeys = hotspotsData.hotspots.map((h) => h.entityKey);
85
-
86
- // Initialize programs
87
- const { provider } = createSolanaConnection(walletAddress);
88
- const ldProgram = await initLd(provider);
89
-
90
- // Fetch oracle rewards for these entity keys
91
- const rewards = await getBulkRewards(
92
- ldProgram,
93
- new PublicKey(HNT_LAZY_DISTRIBUTOR_ADDRESS),
94
- entityKeys,
95
- );
96
-
97
- // Build and sign transactions via oracle
98
- const vtxs: VersionedTransaction[] = await formBulkTransactions({
99
- program: ldProgram,
100
- rewards,
101
- assets,
102
- lazyDistributor: new PublicKey(HNT_LAZY_DISTRIBUTOR_ADDRESS),
103
- assetEndpoint: env.ASSET_ENDPOINT,
104
- skipOracleSign: false,
105
- });
106
-
107
- const singleton = await getSingleton(provider.connection);
108
- singleton.close();
109
-
110
- const txs = vtxs.map((tx) =>
111
- Buffer.from(tx.serialize()).toString("base64"),
112
- );
113
-
114
- return {
115
- transactionData: {
116
- transactions: txs.map((serialized) => ({
117
- serializedTransaction: serialized,
118
- metadata: {
119
- type: "claim_rewards",
120
- description: "Claim hotspot rewards",
121
- },
122
- })),
123
- parallel: true,
124
- tag: `claim_rewards:${walletAddress}`,
125
- },
126
- };
127
- }
128
-
129
- // For larger wallets, queue a Tuktuk claim task via HPL Crons
130
- const { provider } = createSolanaConnection(walletAddress);
131
- anchor.setProvider(provider);
132
-
133
- const tuktukProgram = await initTuktuk(provider);
134
- const taskQueueAcc =
135
- await tuktukProgram.account.taskQueueV0.fetch(TASK_QUEUE_ID);
136
- const [taskId] = nextAvailableTaskIds(taskQueueAcc.taskBitmap, 1);
137
-
138
- const queueAuthority = PublicKey.findProgramAddressSync(
139
- [Buffer.from("queue_authority")],
140
- HPL_CRONS_PROGRAM_ID,
141
- )[0];
142
-
143
- const idl = await anchor.Program.fetchIdl(HPL_CRONS_PROGRAM_ID, provider);
144
- const hplCronsProgram = new anchor.Program(
145
- idl as anchor.Idl,
146
- provider,
147
- ) as anchor.Program<anchor.Idl>;
148
-
149
- const instructions: TransactionInstruction[] = [];
150
-
151
- const pdaWallet = customSignerKey(TASK_QUEUE_ID, [
152
- Buffer.from("claim_payer"),
153
- new PublicKey(walletAddress).toBuffer(),
154
- ])[0];
155
- const pdaWalletBalanceLamports =
156
- await provider.connection.getBalance(pdaWallet);
157
- const ata = getAssociatedTokenAddressSync(
158
- HNT_MINT,
159
- new PublicKey(walletAddress),
160
- true,
161
- );
162
- const minCrankReward = taskQueueAcc?.minCrankReward?.toNumber() || 10000;
163
- const account = await provider.connection.getAccountInfo(ata);
164
- const pdaWalletFundingNeededLamports =
165
- MIN_RENT_LAMPORTS +
166
- (account ? 0 : ATA_RENT_LAMPORTS) +
167
- // Actual claim txs
168
- 20000 * (total || 1) +
169
- // Requeue transactions (5 queues per tx)
170
- minCrankReward * Math.ceil((total || 1) / 5);
171
- const pdaWalletLamportsShortfall = Math.max(
172
- 0,
173
- pdaWalletFundingNeededLamports - pdaWalletBalanceLamports,
174
- );
175
-
176
- const hotspotsNeedingRecipient =
177
- await getNumRecipientsNeeded(walletAddress);
178
- console.log(
179
- `[PDA WALLET ${pdaWallet.toBase58()}] Hotspots needing recipient: ${hotspotsNeedingRecipient}, shortfall: ${pdaWalletLamportsShortfall}`,
180
- );
181
-
182
- if (pdaWalletLamportsShortfall > 0 || hotspotsNeedingRecipient > 0) {
183
- const requiredLamports =
184
- pdaWalletLamportsShortfall +
185
- hotspotsNeedingRecipient * RECIPIENT_RENT_LAMPORTS;
186
- // Ensure the user's wallet has enough SOL to fund PDA and recipients before returning tx
187
- const senderBalance = await provider.connection.getBalance(
188
- new PublicKey(walletAddress),
189
- );
190
- if (senderBalance < requiredLamports) {
191
- throw errors.INSUFFICIENT_FUNDS({
192
- message: "Insufficient SOL balance to fund claim task",
193
- data: {
194
- balance: senderBalance,
195
- required: requiredLamports,
196
- },
197
- });
198
- }
199
- instructions.push(
200
- SystemProgram.transfer({
201
- fromPubkey: new PublicKey(walletAddress),
202
- toPubkey: pdaWallet,
203
- lamports: requiredLamports,
204
- }),
205
- );
206
- }
207
-
208
- const ix = await hplCronsProgram.methods
209
- .queueWalletClaimV0({ freeTaskId: taskId })
210
- .accountsStrict({
211
- task: taskKey(TASK_QUEUE_ID, taskId)[0],
212
- wallet: new PublicKey(walletAddress),
213
- taskQueue: TASK_QUEUE_ID,
214
- payer: provider.wallet.publicKey,
215
- systemProgram: SystemProgram.programId,
216
- queueAuthority,
217
- tuktukProgram: tuktukProgram.programId,
218
- pdaWallet: customSignerKey(TASK_QUEUE_ID, [
219
- Buffer.from("claim_payer"),
220
- new PublicKey(walletAddress).toBuffer(),
221
- ])[0],
222
- taskQueueAuthority: taskQueueAuthorityKey(
223
- TASK_QUEUE_ID,
224
- queueAuthority,
225
- )[0],
226
- })
227
- .instruction();
228
-
229
- instructions.push(ix);
230
- const vtxs = (
231
- await batchInstructionsToTxsWithPriorityFee(provider, instructions, {
232
- addressLookupTableAddresses: [
233
- process.env.NEXT_PUBLIC_SOLANA_CLUSTER?.trim() === "devnet"
234
- ? HELIUM_COMMON_LUT_DEVNET
235
- : HELIUM_COMMON_LUT,
236
- ],
237
- })
238
- ).map((tx) => toVersionedTx(tx));
239
-
240
- const txs: Array<string> = vtxs.map((tx) =>
241
- Buffer.from(tx.serialize()).toString("base64"),
242
- );
243
-
244
- return {
245
- transactionData: {
246
- transactions: txs.map((serialized) => ({
247
- serializedTransaction: serialized,
248
- metadata: {
249
- type: "queue_wallet_claim",
250
- description: "Queue wallet claim task via Tuktuk",
251
- taskIds: [taskId],
252
- },
253
- })),
254
- parallel: true,
255
- tag: `claim_rewards_tuktuk:${walletAddress}`,
256
- },
257
- };
258
- });