@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,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
|
-
});
|