@helium/blockchain-api 0.1.1 → 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 -157
- 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,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
|
-
});
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { publicProcedure } from "../../../procedures";
|
|
2
|
-
import { GetInputSchema, WelcomePackSchema } from "../schemas";
|
|
3
|
-
import { getWelcomePackByAddress } from "@/lib/queries/welcome-packs";
|
|
4
|
-
import { welcomePackKey } from "@helium/welcome-pack-sdk";
|
|
5
|
-
import { PublicKey } from "@solana/web3.js";
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Get a welcome pack by wallet address and pack ID.
|
|
9
|
-
*/
|
|
10
|
-
export const get = publicProcedure
|
|
11
|
-
.route({
|
|
12
|
-
method: "GET",
|
|
13
|
-
path: "/welcome-packs/wallet/{walletAddress}/{packId}",
|
|
14
|
-
})
|
|
15
|
-
.input(GetInputSchema)
|
|
16
|
-
.output(WelcomePackSchema)
|
|
17
|
-
.errors({
|
|
18
|
-
NOT_FOUND: { message: "Welcome pack not found" },
|
|
19
|
-
})
|
|
20
|
-
.handler(async ({ input, errors }) => {
|
|
21
|
-
const { walletAddress, packId } = input;
|
|
22
|
-
|
|
23
|
-
// Derive the welcome pack address from wallet and packId
|
|
24
|
-
const welcomePackAddress = welcomePackKey(
|
|
25
|
-
new PublicKey(walletAddress),
|
|
26
|
-
Number(packId),
|
|
27
|
-
)[0].toBase58();
|
|
28
|
-
|
|
29
|
-
const pack = await getWelcomePackByAddress(welcomePackAddress);
|
|
30
|
-
|
|
31
|
-
if (!pack) {
|
|
32
|
-
throw errors.NOT_FOUND({ message: "Welcome pack not found" });
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
return pack;
|
|
36
|
-
});
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { publicProcedure } from "../../../procedures";
|
|
2
|
-
import { GetByAddressInputSchema, WelcomePackSchema } from "../schemas";
|
|
3
|
-
import { ORPCError } from "@orpc/server";
|
|
4
|
-
import { getWelcomePackByAddress } from "@/lib/queries/welcome-packs";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Get a welcome pack by its address.
|
|
8
|
-
*/
|
|
9
|
-
export const getByAddress = publicProcedure
|
|
10
|
-
.route({ method: "GET", path: "/welcome-packs/{packAddress}" })
|
|
11
|
-
.input(GetByAddressInputSchema)
|
|
12
|
-
.output(WelcomePackSchema)
|
|
13
|
-
.errors({
|
|
14
|
-
NOT_FOUND: { message: "Welcome pack not found" },
|
|
15
|
-
})
|
|
16
|
-
.handler(async ({ input, errors }) => {
|
|
17
|
-
const { packAddress } = input;
|
|
18
|
-
|
|
19
|
-
const pack = await getWelcomePackByAddress(packAddress);
|
|
20
|
-
|
|
21
|
-
if (!pack) {
|
|
22
|
-
throw errors.NOT_FOUND({ message: "Welcome pack not found" });
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
return pack;
|
|
26
|
-
});
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { publicProcedure } from "../../../procedures";
|
|
2
|
-
import { InviteInputSchema, InviteOutputSchema } from "../schemas";
|
|
3
|
-
import { ORPCError } from "@orpc/server";
|
|
4
|
-
import { createSolanaConnection } from "@/lib/solana";
|
|
5
|
-
import { init as initWelcomePack } from "@helium/welcome-pack-sdk";
|
|
6
|
-
import { PublicKey } from "@solana/web3.js";
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Generate an invite message to be signed for a welcome pack.
|
|
10
|
-
*/
|
|
11
|
-
export const invite = publicProcedure
|
|
12
|
-
.route({
|
|
13
|
-
method: "POST",
|
|
14
|
-
path: "/welcome-packs/{packAddress}/invite/{walletAddress}",
|
|
15
|
-
})
|
|
16
|
-
.input(InviteInputSchema)
|
|
17
|
-
.output(InviteOutputSchema)
|
|
18
|
-
.errors({
|
|
19
|
-
BAD_REQUEST: { message: "Invalid request" },
|
|
20
|
-
})
|
|
21
|
-
.handler(async ({ input, errors }) => {
|
|
22
|
-
const { packAddress, walletAddress, expirationDays } = input;
|
|
23
|
-
|
|
24
|
-
if (!packAddress || !walletAddress) {
|
|
25
|
-
throw errors.BAD_REQUEST({
|
|
26
|
-
message: "Pack address and wallet address are required",
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// Load uniqueId from on-chain welcome pack account
|
|
31
|
-
const { provider } = createSolanaConnection(walletAddress);
|
|
32
|
-
const program = await initWelcomePack(provider);
|
|
33
|
-
const welcomePack = await program.account.welcomePackV0.fetch(
|
|
34
|
-
new PublicKey(packAddress),
|
|
35
|
-
);
|
|
36
|
-
const uniqueId = welcomePack.uniqueId.toString();
|
|
37
|
-
const expirationTs =
|
|
38
|
-
Math.floor(Date.now() / 1000) + expirationDays * 24 * 60 * 60;
|
|
39
|
-
|
|
40
|
-
// Keep the canonical message format aligned with client expectations
|
|
41
|
-
const message = `Approve invite ${uniqueId} expiring ${expirationTs}`;
|
|
42
|
-
|
|
43
|
-
return { message, expirationTs };
|
|
44
|
-
});
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { publicProcedure } from "../../../procedures";
|
|
2
|
-
import { ListInputSchema, ListOutputSchema } from "../schemas";
|
|
3
|
-
import { ORPCError } from "@orpc/server";
|
|
4
|
-
import { getWelcomePacksByOwner } from "@/lib/queries/welcome-packs";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* List all welcome packs for a wallet.
|
|
8
|
-
*/
|
|
9
|
-
export const list = publicProcedure
|
|
10
|
-
.route({ method: "GET", path: "/welcome-packs/wallet/{walletAddress}" })
|
|
11
|
-
.input(ListInputSchema)
|
|
12
|
-
.output(ListOutputSchema)
|
|
13
|
-
.errors({
|
|
14
|
-
BAD_REQUEST: { message: "Wallet address is required" },
|
|
15
|
-
})
|
|
16
|
-
.handler(async ({ input }) => {
|
|
17
|
-
const { walletAddress } = input;
|
|
18
|
-
|
|
19
|
-
if (!walletAddress) {
|
|
20
|
-
throw new ORPCError("BAD_REQUEST", {
|
|
21
|
-
message: "Wallet address is required",
|
|
22
|
-
});
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const packs = await getWelcomePacksByOwner(walletAddress);
|
|
26
|
-
return packs;
|
|
27
|
-
});
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { list } from "./procedures/list";
|
|
2
|
-
import { create } from "./procedures/create";
|
|
3
|
-
import { get } from "./procedures/get";
|
|
4
|
-
import { deletePack } from "./procedures/deletePack";
|
|
5
|
-
import { getByAddress } from "./procedures/getByAddress";
|
|
6
|
-
import { claim } from "./procedures/claim";
|
|
7
|
-
import { invite } from "./procedures/invite";
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Welcome Packs router - handles welcome pack operations.
|
|
11
|
-
*/
|
|
12
|
-
export const welcomePacksRouter = {
|
|
13
|
-
/** List all welcome packs for a wallet */
|
|
14
|
-
list,
|
|
15
|
-
/** Create a new welcome pack */
|
|
16
|
-
create,
|
|
17
|
-
/** Get a welcome pack by wallet and pack ID */
|
|
18
|
-
get,
|
|
19
|
-
/** Delete a welcome pack */
|
|
20
|
-
delete: deletePack,
|
|
21
|
-
/** Get a welcome pack by its address */
|
|
22
|
-
getByAddress,
|
|
23
|
-
/** Claim a welcome pack */
|
|
24
|
-
claim,
|
|
25
|
-
/** Generate an invite message for a welcome pack */
|
|
26
|
-
invite,
|
|
27
|
-
};
|