@helium/blockchain-api 0.1.2 → 0.2.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 (51) hide show
  1. package/README.md +106 -49
  2. package/dist/index.d.ts +2382 -0
  3. package/dist/index.js +852 -0
  4. package/package.json +36 -126
  5. package/src/server/api/errors.ts +0 -152
  6. package/src/server/api/index.ts +0 -40
  7. package/src/server/api/procedures.ts +0 -144
  8. package/src/server/api/routers/fiat/router.ts +0 -709
  9. package/src/server/api/routers/fiat/schemas.ts +0 -169
  10. package/src/server/api/routers/health/router.ts +0 -41
  11. package/src/server/api/routers/hotspots/procedures/claimRewards.ts +0 -258
  12. package/src/server/api/routers/hotspots/procedures/createSplit.ts +0 -253
  13. package/src/server/api/routers/hotspots/procedures/deleteSplit.ts +0 -156
  14. package/src/server/api/routers/hotspots/procedures/getHotspots.ts +0 -31
  15. package/src/server/api/routers/hotspots/procedures/getPendingRewards.ts +0 -44
  16. package/src/server/api/routers/hotspots/procedures/getSplit.ts +0 -88
  17. package/src/server/api/routers/hotspots/procedures/transferHotspot.ts +0 -204
  18. package/src/server/api/routers/hotspots/procedures/updateRewardsDestination.ts +0 -201
  19. package/src/server/api/routers/hotspots/router.ts +0 -30
  20. package/src/server/api/routers/hotspots/schemas.ts +0 -182
  21. package/src/server/api/routers/swap/procedures/getInstructions.ts +0 -152
  22. package/src/server/api/routers/swap/procedures/getQuote.ts +0 -53
  23. package/src/server/api/routers/swap/procedures/getTokens.ts +0 -88
  24. package/src/server/api/routers/swap/router.ts +0 -15
  25. package/src/server/api/routers/swap/schemas.ts +0 -96
  26. package/src/server/api/routers/tokens/procedures/createHntAccount.ts +0 -87
  27. package/src/server/api/routers/tokens/procedures/getBalances.ts +0 -27
  28. package/src/server/api/routers/tokens/procedures/transfer.ts +0 -159
  29. package/src/server/api/routers/tokens/router.ts +0 -15
  30. package/src/server/api/routers/tokens/schemas.ts +0 -80
  31. package/src/server/api/routers/transactions/procedures/get.ts +0 -46
  32. package/src/server/api/routers/transactions/procedures/getByPayer.ts +0 -111
  33. package/src/server/api/routers/transactions/procedures/getByPayerAndTag.ts +0 -119
  34. package/src/server/api/routers/transactions/procedures/resubmit.ts +0 -68
  35. package/src/server/api/routers/transactions/procedures/submit.ts +0 -216
  36. package/src/server/api/routers/transactions/router.ts +0 -21
  37. package/src/server/api/routers/transactions/schemas.ts +0 -119
  38. package/src/server/api/routers/webhooks/router.ts +0 -75
  39. package/src/server/api/routers/welcomePacks/procedures/claim.ts +0 -157
  40. package/src/server/api/routers/welcomePacks/procedures/create.ts +0 -247
  41. package/src/server/api/routers/welcomePacks/procedures/deletePack.ts +0 -118
  42. package/src/server/api/routers/welcomePacks/procedures/get.ts +0 -36
  43. package/src/server/api/routers/welcomePacks/procedures/getByAddress.ts +0 -26
  44. package/src/server/api/routers/welcomePacks/procedures/invite.ts +0 -44
  45. package/src/server/api/routers/welcomePacks/procedures/list.ts +0 -27
  46. package/src/server/api/routers/welcomePacks/router.ts +0 -27
  47. package/src/server/api/routers/welcomePacks/schemas.ts +0 -135
  48. package/src/server/api/schemas.ts +0 -281
  49. package/tsconfig.json +0 -45
  50. package/types/README.md +0 -86
  51. package/types/index.ts +0 -27
@@ -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
- });