@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.
- package/README.md +24 -2
- package/package.json +31 -31
- package/types/README.md +24 -2
- package/types/generated/index.d.mts +2481 -0
- package/types/generated/index.d.ts +2481 -0
- package/types/generated/index.js +723 -0
- package/types/generated/index.mjs +614 -0
- package/types/index.ts +11 -8
- package/src/server/api/errors.ts +0 -152
- package/src/server/api/index.ts +0 -40
- package/src/server/api/procedures.ts +0 -144
- package/src/server/api/routers/fiat/router.ts +0 -709
- package/src/server/api/routers/fiat/schemas.ts +0 -169
- package/src/server/api/routers/health/router.ts +0 -41
- package/src/server/api/routers/hotspots/procedures/claimRewards.ts +0 -258
- package/src/server/api/routers/hotspots/procedures/createSplit.ts +0 -253
- package/src/server/api/routers/hotspots/procedures/deleteSplit.ts +0 -156
- package/src/server/api/routers/hotspots/procedures/getHotspots.ts +0 -31
- package/src/server/api/routers/hotspots/procedures/getPendingRewards.ts +0 -44
- package/src/server/api/routers/hotspots/procedures/getSplit.ts +0 -88
- package/src/server/api/routers/hotspots/procedures/transferHotspot.ts +0 -204
- package/src/server/api/routers/hotspots/procedures/updateRewardsDestination.ts +0 -201
- package/src/server/api/routers/hotspots/router.ts +0 -30
- package/src/server/api/routers/hotspots/schemas.ts +0 -182
- package/src/server/api/routers/swap/procedures/getInstructions.ts +0 -152
- package/src/server/api/routers/swap/procedures/getQuote.ts +0 -53
- package/src/server/api/routers/swap/procedures/getTokens.ts +0 -88
- package/src/server/api/routers/swap/router.ts +0 -15
- package/src/server/api/routers/swap/schemas.ts +0 -96
- package/src/server/api/routers/tokens/procedures/createHntAccount.ts +0 -87
- package/src/server/api/routers/tokens/procedures/getBalances.ts +0 -27
- package/src/server/api/routers/tokens/procedures/transfer.ts +0 -159
- package/src/server/api/routers/tokens/router.ts +0 -15
- package/src/server/api/routers/tokens/schemas.ts +0 -80
- package/src/server/api/routers/transactions/procedures/get.ts +0 -46
- package/src/server/api/routers/transactions/procedures/getByPayer.ts +0 -111
- package/src/server/api/routers/transactions/procedures/getByPayerAndTag.ts +0 -119
- package/src/server/api/routers/transactions/procedures/resubmit.ts +0 -68
- package/src/server/api/routers/transactions/procedures/submit.ts +0 -216
- package/src/server/api/routers/transactions/router.ts +0 -21
- package/src/server/api/routers/transactions/schemas.ts +0 -119
- package/src/server/api/routers/webhooks/router.ts +0 -75
- package/src/server/api/routers/welcomePacks/procedures/claim.ts +0 -157
- package/src/server/api/routers/welcomePacks/procedures/create.ts +0 -247
- package/src/server/api/routers/welcomePacks/procedures/deletePack.ts +0 -118
- package/src/server/api/routers/welcomePacks/procedures/get.ts +0 -36
- package/src/server/api/routers/welcomePacks/procedures/getByAddress.ts +0 -26
- package/src/server/api/routers/welcomePacks/procedures/invite.ts +0 -44
- package/src/server/api/routers/welcomePacks/procedures/list.ts +0 -27
- package/src/server/api/routers/welcomePacks/router.ts +0 -27
- package/src/server/api/routers/welcomePacks/schemas.ts +0 -135
- 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
|
-
});
|