@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,119 +0,0 @@
1
- import { z } from "zod";
2
-
3
- // ============================================================================
4
- // Input Schemas
5
- // ============================================================================
6
-
7
- export const TransactionMetadataSchema = z
8
- .object({
9
- type: z.string(),
10
- description: z.string(),
11
- })
12
- .catchall(z.unknown());
13
-
14
- export const TransactionItemSchema = z.object({
15
- serializedTransaction: z.string(),
16
- metadata: TransactionMetadataSchema.optional(),
17
- });
18
-
19
- export const SubmitInputSchema = z.object({
20
- transactions: z.array(TransactionItemSchema),
21
- parallel: z.boolean(),
22
- tag: z.string().optional(),
23
- });
24
-
25
- export const GetInputSchema = z.object({
26
- id: z.string(),
27
- commitment: z.enum(["confirmed", "finalized"]),
28
- });
29
-
30
- export const ResubmitInputSchema = z.object({
31
- id: z.string(),
32
- });
33
-
34
- export const GetByPayerInputSchema = z.object({
35
- payer: z.string().min(32),
36
- page: z.coerce.number().int().min(1).default(1),
37
- limit: z.coerce.number().int().min(1).max(100).default(20),
38
- status: z.string().optional().default("pending"),
39
- });
40
-
41
- export const GetByPayerAndTagInputSchema = z.object({
42
- payer: z.string().min(32),
43
- tag: z.string(),
44
- page: z.coerce.number().int().min(1).default(1),
45
- limit: z.coerce.number().int().min(1).max(100).default(20),
46
- status: z.string().optional().default("pending"),
47
- });
48
-
49
- // ============================================================================
50
- // Output Schemas
51
- // ============================================================================
52
-
53
- export const SubmitOutputSchema = z.object({
54
- batchId: z.string(),
55
- message: z.string().optional(),
56
- });
57
-
58
- export const TransactionStatusSchema = z.object({
59
- signature: z.string(),
60
- status: z.string(),
61
- transaction: z.unknown().optional(),
62
- });
63
-
64
- export const BatchStatusOutputSchema = z.object({
65
- batchId: z.string(),
66
- status: z.string(),
67
- submissionType: z.string(),
68
- parallel: z.boolean(),
69
- transactions: z.array(TransactionStatusSchema),
70
- jitoBundleId: z.string().optional(),
71
- jitoBundleStatus: z.unknown().optional(),
72
- });
73
-
74
- export const ResubmitOutputSchema = z.object({
75
- success: z.boolean(),
76
- message: z.string(),
77
- error: z.string().optional(),
78
- newSignatures: z.array(z.string()).optional(),
79
- });
80
-
81
- export const PayerBatchSummarySchema = z.object({
82
- batchId: z.string(),
83
- tag: z.string().optional(),
84
- status: z.string(),
85
- submissionType: z.string(),
86
- parallel: z.boolean(),
87
- createdAt: z.string(),
88
- updatedAt: z.string(),
89
- transactions: z.array(
90
- z.object({
91
- metadata: TransactionMetadataSchema.optional(),
92
- }),
93
- ),
94
- });
95
-
96
- export const PayerBatchesOutputSchema = z.object({
97
- payer: z.string(),
98
- batches: z.array(PayerBatchSummarySchema),
99
- pagination: z.object({
100
- page: z.number(),
101
- limit: z.number(),
102
- total: z.number(),
103
- totalPages: z.number(),
104
- }),
105
- });
106
-
107
- // ============================================================================
108
- // Type Exports
109
- // ============================================================================
110
-
111
- export type SubmitInput = z.infer<typeof SubmitInputSchema>;
112
- export type GetInput = z.infer<typeof GetInputSchema>;
113
- export type ResubmitInput = z.infer<typeof ResubmitInputSchema>;
114
- export type GetByPayerInput = z.infer<typeof GetByPayerInputSchema>;
115
- export type GetByPayerAndTagInput = z.infer<typeof GetByPayerAndTagInputSchema>;
116
- export type SubmitOutput = z.infer<typeof SubmitOutputSchema>;
117
- export type BatchStatusOutput = z.infer<typeof BatchStatusOutputSchema>;
118
- export type ResubmitOutput = z.infer<typeof ResubmitOutputSchema>;
119
- export type PayerBatchesOutput = z.infer<typeof PayerBatchesOutputSchema>;
@@ -1,75 +0,0 @@
1
- import { z } from "zod";
2
- import { publicProcedure } from "../../procedures";
3
- import { BridgeUser } from "@/lib/models/bridge-user";
4
- import { ORPCError } from "@orpc/server";
5
-
6
- // ============================================================================
7
- // Schemas
8
- // ============================================================================
9
-
10
- const BridgeWebhookInputSchema = z.object({
11
- type: z.string(),
12
- kyc_link_id: z.string().optional(),
13
- kyc_status: z.string().optional(),
14
- tos_status: z.string().optional(),
15
- customer_id: z.string().optional(),
16
- });
17
-
18
- const BridgeWebhookOutputSchema = z.object({
19
- success: z.boolean(),
20
- error: z.string().optional(),
21
- });
22
-
23
- // ============================================================================
24
- // Procedures
25
- // ============================================================================
26
-
27
- /**
28
- * Bridge webhook handler for KYC/ToS status updates.
29
- */
30
- const bridge = publicProcedure
31
- .route({ method: "POST", path: "/webhooks/bridge" })
32
- .input(BridgeWebhookInputSchema)
33
- .output(BridgeWebhookOutputSchema)
34
- .errors({
35
- NOT_FOUND: { message: "Bridge user not found" },
36
- INVALID_PAYLOAD: { message: "Invalid webhook payload" },
37
- })
38
- .handler(async ({ input, errors }) => {
39
- const data = input;
40
-
41
- // Handle KYC link status updates
42
- if (data.type === "kyc_link.status_updated") {
43
- const bridgeUser = await BridgeUser.findOne({
44
- where: { kycLinkId: data.kyc_link_id },
45
- });
46
-
47
- if (!bridgeUser) {
48
- console.error(
49
- "Bridge user not found for KYC link ID:",
50
- data.kyc_link_id,
51
- );
52
- throw errors.NOT_FOUND({ message: "Bridge user not found" });
53
- }
54
-
55
- // Update statuses
56
- await bridgeUser.update({
57
- kycStatus: data.kyc_status,
58
- tosStatus: data.tos_status,
59
- bridgeCustomerId: data.customer_id,
60
- });
61
-
62
- return { success: true };
63
- }
64
-
65
- // Handle other webhook types here
66
- return { success: true };
67
- });
68
-
69
- // ============================================================================
70
- // Router Export
71
- // ============================================================================
72
-
73
- export const webhooksRouter = {
74
- bridge,
75
- };
@@ -1,157 +0,0 @@
1
- import { publicProcedure } from "../../../procedures";
2
- import { ClaimInputSchema, ClaimOutputSchema } from "../schemas";
3
- import { ORPCError } from "@orpc/server";
4
- import { env } from "@/lib/env";
5
- import { createSolanaConnection, loadKeypair } from "@/lib/solana";
6
- import {
7
- generateTransactionTag,
8
- TRANSACTION_TYPES,
9
- } from "@/lib/utils/transaction-tags";
10
- import {
11
- getAsset,
12
- getAssetProof,
13
- HELIUM_COMMON_LUT,
14
- HELIUM_COMMON_LUT_DEVNET,
15
- populateMissingDraftInfo,
16
- toVersionedTx,
17
- withPriorityFees,
18
- } from "@helium/spl-utils";
19
- import { init as initTuktuk } from "@helium/tuktuk-sdk";
20
- import { claimWelcomePack, init } from "@helium/welcome-pack-sdk";
21
- import {
22
- createAssociatedTokenAccountIdempotentInstruction,
23
- getAssociatedTokenAddressSync,
24
- } from "@solana/spl-token";
25
- import { PublicKey } from "@solana/web3.js";
26
- import BN from "bn.js";
27
-
28
- /**
29
- * Claim a welcome pack.
30
- */
31
- export const claim = publicProcedure
32
- .route({
33
- method: "POST",
34
- path: "/welcome-packs/{packAddress}/claim/{walletAddress}",
35
- })
36
- .input(ClaimInputSchema)
37
- .output(ClaimOutputSchema)
38
- .errors({
39
- BAD_REQUEST: { message: "Invalid request" },
40
- EXPIRED: { message: "Invite has expired" },
41
- })
42
- .handler(async ({ input, errors }) => {
43
- const { packAddress, walletAddress, signature, expirationTs } = input;
44
-
45
- if (!packAddress || !walletAddress) {
46
- throw errors.BAD_REQUEST({
47
- message: "Pack address and wallet address are required",
48
- });
49
- }
50
-
51
- // Verify expiration
52
- const currentTs = Math.floor(Date.now() / 1000);
53
- if (currentTs > parseInt(expirationTs)) {
54
- throw errors.EXPIRED({ message: "Invite has expired" });
55
- }
56
-
57
- const signatureBytes = Buffer.from(signature, "base64");
58
-
59
- const feePayerWallet = loadKeypair(process.env.FEE_PAYER_WALLET_PATH!);
60
-
61
- // Initialize connection and programs
62
- const { provider } = createSolanaConnection(
63
- feePayerWallet.publicKey.toString(),
64
- );
65
- const program = await init(provider);
66
- const tuktukProgram = await initTuktuk(provider);
67
- const welcomePack = await program.account.welcomePackV0.fetch(
68
- new PublicKey(packAddress),
69
- );
70
-
71
- // Prepare claim transaction
72
- const {
73
- instruction: ix,
74
- pubkeys: { rewardsMint },
75
- } = await (
76
- await claimWelcomePack({
77
- program,
78
- claimer: new PublicKey(walletAddress),
79
- tuktukProgram,
80
- taskQueue: new PublicKey(process.env.HPL_CRONS_TASK_QUEUE!),
81
- welcomePack: new PublicKey(packAddress),
82
- claimApproval: {
83
- uniqueId: welcomePack.uniqueId,
84
- expirationTimestamp: new BN(parseInt(expirationTs)),
85
- },
86
- claimApprovalSignature: signatureBytes,
87
- payer: feePayerWallet.publicKey,
88
- getAssetFn: (_, assetId) =>
89
- getAsset(
90
- env.ASSET_ENDPOINT || program.provider.connection.rpcEndpoint,
91
- assetId,
92
- ),
93
- getAssetProofFn: (_, assetId) =>
94
- getAssetProof(
95
- env.ASSET_ENDPOINT || program.provider.connection.rpcEndpoint,
96
- assetId,
97
- ),
98
- })
99
- ).prepare();
100
-
101
- const draft = {
102
- instructions: [
103
- ix,
104
- createAssociatedTokenAccountIdempotentInstruction(
105
- new PublicKey(walletAddress),
106
- getAssociatedTokenAddressSync(
107
- rewardsMint!,
108
- new PublicKey(walletAddress),
109
- true,
110
- ),
111
- new PublicKey(walletAddress),
112
- rewardsMint!,
113
- ),
114
- ],
115
- feePayer: feePayerWallet.publicKey,
116
- addressLookupTableAddresses: [
117
- process.env.NEXT_PUBLIC_SOLANA_CLUSTER!.trim() === "devnet"
118
- ? HELIUM_COMMON_LUT_DEVNET
119
- : HELIUM_COMMON_LUT,
120
- ],
121
- };
122
-
123
- const tx = toVersionedTx(
124
- await populateMissingDraftInfo(provider.connection, {
125
- ...draft,
126
- instructions: await withPriorityFees({
127
- ...draft,
128
- connection: provider.connection,
129
- }),
130
- }),
131
- );
132
- tx.sign([feePayerWallet]);
133
-
134
- const tag = generateTransactionTag({
135
- type: TRANSACTION_TYPES.WELCOME_PACK_CLAIM,
136
- packAddress,
137
- walletAddress,
138
- });
139
-
140
- return {
141
- transactionData: {
142
- transactions: [
143
- {
144
- serializedTransaction: Buffer.from(tx.serialize()).toString(
145
- "base64",
146
- ),
147
- metadata: {
148
- type: "welcome_pack_claim",
149
- description: "Claim welcome pack",
150
- },
151
- },
152
- ],
153
- parallel: true,
154
- tag,
155
- },
156
- };
157
- });
@@ -1,247 +0,0 @@
1
- import { publicProcedure } from "../../../procedures";
2
- import { CreateInputSchema, CreateOutputSchema } from "../schemas";
3
- import { ORPCError } from "@orpc/server";
4
- import { env } from "@/lib/env";
5
- import { WelcomePackWithStatus } from "@/lib/models/welcome-pack";
6
- import { createSolanaConnection } from "@/lib/solana";
7
- import { scheduleToUtcCron } from "@/lib/utils/misc";
8
- import {
9
- generateTransactionTag,
10
- TRANSACTION_TYPES,
11
- } from "@/lib/utils/transaction-tags";
12
- import {
13
- initializeCompressionRecipient,
14
- init as initLd,
15
- recipientKey,
16
- } from "@helium/lazy-distributor-sdk";
17
- import {
18
- getAsset,
19
- getAssetProof,
20
- HELIUM_COMMON_LUT,
21
- populateMissingDraftInfo,
22
- toVersionedTx,
23
- withPriorityFees,
24
- } from "@helium/spl-utils";
25
- import { init, initializeWelcomePack } from "@helium/welcome-pack-sdk";
26
- import {
27
- LAMPORTS_PER_SOL,
28
- PublicKey,
29
- TransactionInstruction,
30
- } from "@solana/web3.js";
31
- import BN from "bn.js";
32
-
33
- function solToLamports(sol: number): BN {
34
- return new BN(sol * LAMPORTS_PER_SOL);
35
- }
36
-
37
- /**
38
- * Create a new welcome pack.
39
- */
40
- export const create = publicProcedure
41
- .route({ method: "POST", path: "/welcome-packs/wallet/{walletAddress}" })
42
- .input(CreateInputSchema)
43
- .output(CreateOutputSchema)
44
- .errors({
45
- BAD_REQUEST: { message: "Invalid request" },
46
- })
47
- .handler(async ({ input, errors }) => {
48
- const {
49
- walletAddress,
50
- assetId,
51
- solAmount,
52
- rentRefund,
53
- assetReturnAddress,
54
- rewardsSplit,
55
- schedule,
56
- lazyDistributor,
57
- } = input;
58
-
59
- if (!assetId) {
60
- throw errors.BAD_REQUEST({ message: "Asset ID is required" });
61
- }
62
-
63
- if (!rewardsSplit?.length) {
64
- throw errors.BAD_REQUEST({
65
- message: "At least one reward split is required",
66
- });
67
- }
68
-
69
- if (!schedule?.frequency || !schedule?.time || !schedule?.timezone) {
70
- throw errors.BAD_REQUEST({
71
- message: "Schedule frequency, time, and timezone are required",
72
- });
73
- }
74
-
75
- if (!rentRefund || !assetReturnAddress) {
76
- throw errors.BAD_REQUEST({ message: "Return addresses are required" });
77
- }
78
-
79
- if (!solAmount || solAmount <= 0) {
80
- throw errors.BAD_REQUEST({
81
- message: "SOL amount must be greater than 0",
82
- });
83
- }
84
-
85
- // Validate reward splits
86
- for (const split of rewardsSplit) {
87
- if (!split.address || !split.amount || !split.type) {
88
- throw errors.BAD_REQUEST({
89
- message: "Each reward split must have an address, amount, and type",
90
- });
91
- }
92
-
93
- if (
94
- split.type === "percentage" &&
95
- (split.amount < 0 || split.amount > 100)
96
- ) {
97
- throw errors.BAD_REQUEST({
98
- message: "Percentage rewards must be between 0 and 100",
99
- });
100
- }
101
-
102
- if (split.type === "fixed" && split.amount <= 0) {
103
- throw errors.BAD_REQUEST({
104
- message: "Fixed rewards must be greater than 0",
105
- });
106
- }
107
- }
108
-
109
- const { connection, provider, wallet } =
110
- createSolanaConnection(walletAddress);
111
- const program = await init(provider);
112
- const ldProgram = await initLd(provider);
113
-
114
- const rewardsSchedule = scheduleToUtcCron(schedule);
115
-
116
- const recipientK = recipientKey(
117
- new PublicKey(lazyDistributor),
118
- new PublicKey(assetId),
119
- )[0];
120
- const recipient =
121
- await ldProgram.account.recipientV0.fetchNullable(recipientK);
122
- const instructions: TransactionInstruction[] = [];
123
-
124
- if (!recipient) {
125
- instructions.push(
126
- await (
127
- await initializeCompressionRecipient({
128
- program: ldProgram,
129
- assetId: new PublicKey(assetId),
130
- payer: wallet.publicKey,
131
- assetEndpoint: env.ASSET_ENDPOINT,
132
- lazyDistributor: new PublicKey(lazyDistributor),
133
- })
134
- ).instruction(),
135
- );
136
- }
137
-
138
- const { instruction: ix, pubkeys } = await (
139
- await initializeWelcomePack({
140
- program,
141
- assetId: new PublicKey(assetId),
142
- owner: new PublicKey(walletAddress),
143
- solAmount: solToLamports(solAmount),
144
- rentRefund: new PublicKey(rentRefund),
145
- assetReturnAddress: new PublicKey(assetReturnAddress),
146
- rewardsSplit: rewardsSplit.map((split) =>
147
- split.type === "percentage"
148
- ? {
149
- share: { share: { amount: split.amount } },
150
- wallet: new PublicKey(split.address),
151
- }
152
- : {
153
- share: { fixed: { amount: new BN(split.amount) } },
154
- wallet: new PublicKey(split.address),
155
- },
156
- ),
157
- rewardsSchedule,
158
- getAssetFn: (_, assetId) =>
159
- getAsset(
160
- env.ASSET_ENDPOINT || program.provider.connection.rpcEndpoint,
161
- assetId,
162
- ),
163
- getAssetProofFn: (_, assetId) =>
164
- getAssetProof(
165
- env.ASSET_ENDPOINT || program.provider.connection.rpcEndpoint,
166
- assetId,
167
- ),
168
- assetEndpoint: env.ASSET_ENDPOINT,
169
- lazyDistributor: new PublicKey(lazyDistributor),
170
- })
171
- ).prepare();
172
- instructions.push(ix);
173
-
174
- const draft = {
175
- instructions,
176
- feePayer: new PublicKey(walletAddress),
177
- addressLookupTableAddresses: [HELIUM_COMMON_LUT],
178
- };
179
-
180
- let instructionsWithFees: TransactionInstruction[];
181
- try {
182
- instructionsWithFees = await withPriorityFees({ ...draft, connection });
183
- } catch {
184
- instructionsWithFees = draft.instructions;
185
- }
186
-
187
- const tx = toVersionedTx(
188
- await populateMissingDraftInfo(connection, {
189
- ...draft,
190
- instructions: instructionsWithFees,
191
- }),
192
- );
193
-
194
- const userWelcomePacksAccount =
195
- await program.account.userWelcomePacksV0.fetchNullable(
196
- new PublicKey(pubkeys.userWelcomePacks!),
197
- );
198
- const lazyDistributorAcc =
199
- await ldProgram.account.lazyDistributorV0.fetch(lazyDistributor);
200
-
201
- const welcomePack: WelcomePackWithStatus = {
202
- address: pubkeys.welcomePack!.toBase58(),
203
- id: userWelcomePacksAccount?.nextId || 0,
204
- uniqueId: `${userWelcomePacksAccount?.nextUniqueId || 0}`,
205
- owner: walletAddress,
206
- rewardsSplit: rewardsSplit.map((split) => ({
207
- address: split.address,
208
- amount: split.amount,
209
- type: split.type,
210
- })),
211
- rewardsSchedule,
212
- solAmount: solAmount.toString(),
213
- assetReturnAddress,
214
- asset: assetId,
215
- lazyDistributor,
216
- loading: true,
217
- rewardsMint: lazyDistributorAcc.rewardsMint.toBase58(),
218
- rentRefund: rentRefund.toString(),
219
- bumpSeed: 0,
220
- hotspot: null,
221
- };
222
-
223
- const tag = generateTransactionTag({
224
- type: TRANSACTION_TYPES.WELCOME_PACK_CREATE,
225
- walletAddress,
226
- assetId,
227
- });
228
-
229
- return {
230
- welcomePack,
231
- transactionData: {
232
- transactions: [
233
- {
234
- serializedTransaction: Buffer.from(tx.serialize()).toString(
235
- "base64",
236
- ),
237
- metadata: {
238
- type: "welcome_pack_create",
239
- description: "Create welcome pack",
240
- },
241
- },
242
- ],
243
- parallel: true,
244
- tag,
245
- },
246
- };
247
- });
@@ -1,118 +0,0 @@
1
- import { publicProcedure } from "../../../procedures";
2
- import { DeleteInputSchema, DeleteOutputSchema } from "../schemas";
3
- import { ORPCError } from "@orpc/server";
4
- import { env } from "@/lib/env";
5
- import { createSolanaConnection } from "@/lib/solana";
6
- import {
7
- generateTransactionTag,
8
- TRANSACTION_TYPES,
9
- } from "@/lib/utils/transaction-tags";
10
- import {
11
- getAsset,
12
- getAssetProof,
13
- HELIUM_COMMON_LUT,
14
- HELIUM_COMMON_LUT_DEVNET,
15
- populateMissingDraftInfo,
16
- toVersionedTx,
17
- withPriorityFees,
18
- } from "@helium/spl-utils";
19
- import {
20
- closeWelcomePack,
21
- init,
22
- welcomePackKey,
23
- } from "@helium/welcome-pack-sdk";
24
- import { PublicKey } from "@solana/web3.js";
25
-
26
- /**
27
- * Delete a welcome pack.
28
- */
29
- export const deletePack = publicProcedure
30
- .route({
31
- method: "DELETE",
32
- path: "/welcome-packs/wallet/{walletAddress}/{packId}",
33
- })
34
- .input(DeleteInputSchema)
35
- .output(DeleteOutputSchema)
36
- .errors({
37
- BAD_REQUEST: { message: "Invalid request" },
38
- })
39
- .handler(async ({ input, errors }) => {
40
- const { walletAddress, packId } = input;
41
-
42
- if (!walletAddress) {
43
- throw errors.BAD_REQUEST({ message: "Wallet address is required" });
44
- }
45
-
46
- if (!packId) {
47
- throw errors.BAD_REQUEST({ message: "Pack ID is required" });
48
- }
49
-
50
- const { provider } = createSolanaConnection(walletAddress);
51
- const program = await init(provider);
52
-
53
- const welcomePackK = welcomePackKey(
54
- new PublicKey(walletAddress),
55
- Number(packId),
56
- )[0];
57
-
58
- const { instruction: ix } = await (
59
- await closeWelcomePack({
60
- program,
61
- welcomePack: welcomePackK,
62
- getAssetFn: (_, assetId) =>
63
- getAsset(
64
- env.ASSET_ENDPOINT || program.provider.connection.rpcEndpoint,
65
- assetId,
66
- ),
67
- getAssetProofFn: (_, assetId) =>
68
- getAssetProof(
69
- env.ASSET_ENDPOINT || program.provider.connection.rpcEndpoint,
70
- assetId,
71
- ),
72
- })
73
- ).prepare();
74
-
75
- const draft = {
76
- instructions: [ix],
77
- feePayer: new PublicKey(walletAddress),
78
- addressLookupTableAddresses: [
79
- process.env.NEXT_PUBLIC_SOLANA_CLUSTER === "devnet"
80
- ? HELIUM_COMMON_LUT_DEVNET
81
- : HELIUM_COMMON_LUT,
82
- ],
83
- };
84
-
85
- const tx = toVersionedTx(
86
- await populateMissingDraftInfo(provider.connection, {
87
- ...draft,
88
- instructions: await withPriorityFees({
89
- ...draft,
90
- connection: provider.connection,
91
- }),
92
- }),
93
- );
94
-
95
- const tag = generateTransactionTag({
96
- type: TRANSACTION_TYPES.WELCOME_PACK_DELETE,
97
- walletAddress,
98
- packId,
99
- });
100
-
101
- return {
102
- transactionData: {
103
- transactions: [
104
- {
105
- serializedTransaction: Buffer.from(tx.serialize()).toString(
106
- "base64",
107
- ),
108
- metadata: {
109
- type: "welcome_pack_delete",
110
- description: "Delete welcome pack",
111
- },
112
- },
113
- ],
114
- parallel: true,
115
- tag,
116
- },
117
- };
118
- });