@t402/svm 2.0.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 (58) hide show
  1. package/README.md +200 -0
  2. package/dist/cjs/exact/client/index.d.ts +37 -0
  3. package/dist/cjs/exact/client/index.js +281 -0
  4. package/dist/cjs/exact/client/index.js.map +1 -0
  5. package/dist/cjs/exact/facilitator/index.d.ts +110 -0
  6. package/dist/cjs/exact/facilitator/index.js +720 -0
  7. package/dist/cjs/exact/facilitator/index.js.map +1 -0
  8. package/dist/cjs/exact/server/index.d.ts +87 -0
  9. package/dist/cjs/exact/server/index.js +207 -0
  10. package/dist/cjs/exact/server/index.js.map +1 -0
  11. package/dist/cjs/exact/v1/client/index.d.ts +33 -0
  12. package/dist/cjs/exact/v1/client/index.js +169 -0
  13. package/dist/cjs/exact/v1/client/index.js.map +1 -0
  14. package/dist/cjs/exact/v1/facilitator/index.d.ts +71 -0
  15. package/dist/cjs/exact/v1/facilitator/index.js +388 -0
  16. package/dist/cjs/exact/v1/facilitator/index.js.map +1 -0
  17. package/dist/cjs/index.d.ts +118 -0
  18. package/dist/cjs/index.js +429 -0
  19. package/dist/cjs/index.js.map +1 -0
  20. package/dist/cjs/scheme-ByJE6QYY.d.ts +29 -0
  21. package/dist/cjs/signer-BMkbhFYE.d.ts +123 -0
  22. package/dist/cjs/v1/index.d.ts +12 -0
  23. package/dist/cjs/v1/index.js +180 -0
  24. package/dist/cjs/v1/index.js.map +1 -0
  25. package/dist/esm/chunk-4BFJL7IW.mjs +341 -0
  26. package/dist/esm/chunk-4BFJL7IW.mjs.map +1 -0
  27. package/dist/esm/chunk-7S5RSPMY.mjs +108 -0
  28. package/dist/esm/chunk-7S5RSPMY.mjs.map +1 -0
  29. package/dist/esm/chunk-FPXYRDTG.mjs +111 -0
  30. package/dist/esm/chunk-FPXYRDTG.mjs.map +1 -0
  31. package/dist/esm/chunk-JFN5MEH3.mjs +157 -0
  32. package/dist/esm/chunk-JFN5MEH3.mjs.map +1 -0
  33. package/dist/esm/chunk-WWACQNRQ.mjs +7 -0
  34. package/dist/esm/chunk-WWACQNRQ.mjs.map +1 -0
  35. package/dist/esm/exact/client/index.d.mts +37 -0
  36. package/dist/esm/exact/client/index.mjs +36 -0
  37. package/dist/esm/exact/client/index.mjs.map +1 -0
  38. package/dist/esm/exact/facilitator/index.d.mts +110 -0
  39. package/dist/esm/exact/facilitator/index.mjs +352 -0
  40. package/dist/esm/exact/facilitator/index.mjs.map +1 -0
  41. package/dist/esm/exact/server/index.d.mts +87 -0
  42. package/dist/esm/exact/server/index.mjs +129 -0
  43. package/dist/esm/exact/server/index.mjs.map +1 -0
  44. package/dist/esm/exact/v1/client/index.d.mts +33 -0
  45. package/dist/esm/exact/v1/client/index.mjs +8 -0
  46. package/dist/esm/exact/v1/client/index.mjs.map +1 -0
  47. package/dist/esm/exact/v1/facilitator/index.d.mts +71 -0
  48. package/dist/esm/exact/v1/facilitator/index.mjs +8 -0
  49. package/dist/esm/exact/v1/facilitator/index.mjs.map +1 -0
  50. package/dist/esm/index.d.mts +118 -0
  51. package/dist/esm/index.mjs +194 -0
  52. package/dist/esm/index.mjs.map +1 -0
  53. package/dist/esm/scheme-DRerE5zq.d.mts +29 -0
  54. package/dist/esm/signer-BMkbhFYE.d.mts +123 -0
  55. package/dist/esm/v1/index.d.mts +12 -0
  56. package/dist/esm/v1/index.mjs +13 -0
  57. package/dist/esm/v1/index.mjs.map +1 -0
  58. package/package.json +132 -0
@@ -0,0 +1,720 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/exact/facilitator/index.ts
21
+ var facilitator_exports = {};
22
+ __export(facilitator_exports, {
23
+ ExactSvmScheme: () => ExactSvmScheme,
24
+ registerExactSvmScheme: () => registerExactSvmScheme
25
+ });
26
+ module.exports = __toCommonJS(facilitator_exports);
27
+
28
+ // src/exact/facilitator/scheme.ts
29
+ var import_compute_budget = require("@solana-program/compute-budget");
30
+ var import_token2 = require("@solana-program/token");
31
+ var import_token_20222 = require("@solana-program/token-2022");
32
+ var import_kit2 = require("@solana/kit");
33
+
34
+ // src/constants.ts
35
+ var MAX_COMPUTE_UNIT_PRICE_MICROLAMPORTS = 5e6;
36
+
37
+ // src/utils.ts
38
+ var import_kit = require("@solana/kit");
39
+ var import_token = require("@solana-program/token");
40
+ var import_token_2022 = require("@solana-program/token-2022");
41
+ function decodeTransactionFromPayload(svmPayload) {
42
+ try {
43
+ const base64Encoder = (0, import_kit.getBase64Encoder)();
44
+ const transactionBytes = base64Encoder.encode(svmPayload.transaction);
45
+ const transactionDecoder = (0, import_kit.getTransactionDecoder)();
46
+ return transactionDecoder.decode(transactionBytes);
47
+ } catch (error) {
48
+ console.error("Error decoding transaction:", error);
49
+ throw new Error("invalid_exact_svm_payload_transaction");
50
+ }
51
+ }
52
+ function getTokenPayerFromTransaction(transaction) {
53
+ const compiled = (0, import_kit.getCompiledTransactionMessageDecoder)().decode(
54
+ transaction.messageBytes
55
+ );
56
+ const staticAccounts = compiled.staticAccounts ?? [];
57
+ const instructions = compiled.instructions ?? [];
58
+ for (const ix of instructions) {
59
+ const programIndex = ix.programAddressIndex;
60
+ const programAddress = staticAccounts[programIndex].toString();
61
+ if (programAddress === import_token.TOKEN_PROGRAM_ADDRESS.toString() || programAddress === import_token_2022.TOKEN_2022_PROGRAM_ADDRESS.toString()) {
62
+ const accountIndices = ix.accountIndices ?? [];
63
+ if (accountIndices.length >= 4) {
64
+ const ownerIndex = accountIndices[3];
65
+ const ownerAddress = staticAccounts[ownerIndex].toString();
66
+ if (ownerAddress) return ownerAddress;
67
+ }
68
+ }
69
+ }
70
+ return "";
71
+ }
72
+
73
+ // src/exact/facilitator/scheme.ts
74
+ var ExactSvmScheme = class {
75
+ /**
76
+ * Creates a new ExactSvmFacilitator instance.
77
+ *
78
+ * @param signer - The SVM RPC client for facilitator operations
79
+ * @returns ExactSvmFacilitator instance
80
+ */
81
+ constructor(signer) {
82
+ this.signer = signer;
83
+ this.scheme = "exact";
84
+ this.caipFamily = "solana:*";
85
+ }
86
+ /**
87
+ * Get mechanism-specific extra data for the supported kinds endpoint.
88
+ * For SVM, this includes a randomly selected fee payer address.
89
+ * Random selection distributes load across multiple signers.
90
+ *
91
+ * @param _ - The network identifier (unused for SVM)
92
+ * @returns Extra data with feePayer address
93
+ */
94
+ getExtra(_) {
95
+ const addresses = this.signer.getAddresses();
96
+ const randomIndex = Math.floor(Math.random() * addresses.length);
97
+ return {
98
+ feePayer: addresses[randomIndex]
99
+ };
100
+ }
101
+ /**
102
+ * Get signer addresses used by this facilitator.
103
+ * For SVM, returns all available fee payer addresses.
104
+ *
105
+ * @param _ - The network identifier (unused for SVM)
106
+ * @returns Array of fee payer addresses
107
+ */
108
+ getSigners(_) {
109
+ return [...this.signer.getAddresses()];
110
+ }
111
+ /**
112
+ * Verifies a payment payload.
113
+ *
114
+ * @param payload - The payment payload to verify
115
+ * @param requirements - The payment requirements
116
+ * @returns Promise resolving to verification response
117
+ */
118
+ async verify(payload, requirements) {
119
+ const exactSvmPayload = payload.payload;
120
+ if (payload.accepted.scheme !== "exact" || requirements.scheme !== "exact") {
121
+ return {
122
+ isValid: false,
123
+ invalidReason: "unsupported_scheme",
124
+ payer: ""
125
+ };
126
+ }
127
+ if (payload.accepted.network !== requirements.network) {
128
+ return {
129
+ isValid: false,
130
+ invalidReason: "network_mismatch",
131
+ payer: ""
132
+ };
133
+ }
134
+ if (!requirements.extra?.feePayer || typeof requirements.extra.feePayer !== "string") {
135
+ return {
136
+ isValid: false,
137
+ invalidReason: "invalid_exact_svm_payload_missing_fee_payer",
138
+ payer: ""
139
+ };
140
+ }
141
+ const signerAddresses = this.signer.getAddresses().map((addr) => addr.toString());
142
+ if (!signerAddresses.includes(requirements.extra.feePayer)) {
143
+ return {
144
+ isValid: false,
145
+ invalidReason: "fee_payer_not_managed_by_facilitator",
146
+ payer: ""
147
+ };
148
+ }
149
+ let transaction;
150
+ try {
151
+ transaction = decodeTransactionFromPayload(exactSvmPayload);
152
+ } catch {
153
+ return {
154
+ isValid: false,
155
+ invalidReason: "invalid_exact_svm_payload_transaction_could_not_be_decoded",
156
+ payer: ""
157
+ };
158
+ }
159
+ const compiled = (0, import_kit2.getCompiledTransactionMessageDecoder)().decode(
160
+ transaction.messageBytes
161
+ );
162
+ const decompiled = (0, import_kit2.decompileTransactionMessage)(compiled);
163
+ const instructions = decompiled.instructions ?? [];
164
+ if (instructions.length !== 3) {
165
+ return {
166
+ isValid: false,
167
+ invalidReason: "invalid_exact_svm_payload_transaction_instructions_length",
168
+ payer: ""
169
+ };
170
+ }
171
+ try {
172
+ this.verifyComputeLimitInstruction(instructions[0]);
173
+ this.verifyComputePriceInstruction(instructions[1]);
174
+ } catch (error) {
175
+ const errorMessage = error instanceof Error ? error.message : String(error);
176
+ return {
177
+ isValid: false,
178
+ invalidReason: errorMessage,
179
+ payer: ""
180
+ };
181
+ }
182
+ const payer = getTokenPayerFromTransaction(transaction);
183
+ if (!payer) {
184
+ return {
185
+ isValid: false,
186
+ invalidReason: "invalid_exact_svm_payload_no_transfer_instruction",
187
+ payer: ""
188
+ };
189
+ }
190
+ const transferIx = instructions[2];
191
+ const programAddress = transferIx.programAddress.toString();
192
+ if (programAddress !== import_token2.TOKEN_PROGRAM_ADDRESS.toString() && programAddress !== import_token_20222.TOKEN_2022_PROGRAM_ADDRESS.toString()) {
193
+ return {
194
+ isValid: false,
195
+ invalidReason: "invalid_exact_svm_payload_no_transfer_instruction",
196
+ payer
197
+ };
198
+ }
199
+ let parsedTransfer;
200
+ try {
201
+ if (programAddress === import_token2.TOKEN_PROGRAM_ADDRESS.toString()) {
202
+ parsedTransfer = (0, import_token2.parseTransferCheckedInstruction)(transferIx);
203
+ } else {
204
+ parsedTransfer = (0, import_token_20222.parseTransferCheckedInstruction)(transferIx);
205
+ }
206
+ } catch {
207
+ return {
208
+ isValid: false,
209
+ invalidReason: "invalid_exact_svm_payload_no_transfer_instruction",
210
+ payer
211
+ };
212
+ }
213
+ const authorityAddress = parsedTransfer.accounts.authority.address.toString();
214
+ if (signerAddresses.includes(authorityAddress)) {
215
+ return {
216
+ isValid: false,
217
+ invalidReason: "invalid_exact_svm_payload_transaction_fee_payer_transferring_funds",
218
+ payer
219
+ };
220
+ }
221
+ const mintAddress = parsedTransfer.accounts.mint.address.toString();
222
+ if (mintAddress !== requirements.asset) {
223
+ return {
224
+ isValid: false,
225
+ invalidReason: "invalid_exact_svm_payload_mint_mismatch",
226
+ payer
227
+ };
228
+ }
229
+ const destATA = parsedTransfer.accounts.destination.address.toString();
230
+ try {
231
+ const [expectedDestATA] = await (0, import_token_20222.findAssociatedTokenPda)({
232
+ mint: requirements.asset,
233
+ owner: requirements.payTo,
234
+ tokenProgram: programAddress === import_token2.TOKEN_PROGRAM_ADDRESS.toString() ? import_token2.TOKEN_PROGRAM_ADDRESS : import_token_20222.TOKEN_2022_PROGRAM_ADDRESS
235
+ });
236
+ if (destATA !== expectedDestATA.toString()) {
237
+ return {
238
+ isValid: false,
239
+ invalidReason: "invalid_exact_svm_payload_recipient_mismatch",
240
+ payer
241
+ };
242
+ }
243
+ } catch {
244
+ return {
245
+ isValid: false,
246
+ invalidReason: "invalid_exact_svm_payload_recipient_mismatch",
247
+ payer
248
+ };
249
+ }
250
+ const amount = parsedTransfer.data.amount;
251
+ if (amount < BigInt(requirements.amount)) {
252
+ return {
253
+ isValid: false,
254
+ invalidReason: "invalid_exact_svm_payload_amount_insufficient",
255
+ payer
256
+ };
257
+ }
258
+ try {
259
+ const feePayer = requirements.extra.feePayer;
260
+ const fullySignedTransaction = await this.signer.signTransaction(
261
+ exactSvmPayload.transaction,
262
+ feePayer,
263
+ requirements.network
264
+ );
265
+ await this.signer.simulateTransaction(fullySignedTransaction, requirements.network);
266
+ } catch (error) {
267
+ const errorMessage = error instanceof Error ? error.message : String(error);
268
+ return {
269
+ isValid: false,
270
+ invalidReason: `transaction_simulation_failed: ${errorMessage}`,
271
+ payer
272
+ };
273
+ }
274
+ return {
275
+ isValid: true,
276
+ invalidReason: void 0,
277
+ payer
278
+ };
279
+ }
280
+ /**
281
+ * Settles a payment by submitting the transaction.
282
+ * Ensures the correct signer is used based on the feePayer specified in requirements.
283
+ *
284
+ * @param payload - The payment payload to settle
285
+ * @param requirements - The payment requirements
286
+ * @returns Promise resolving to settlement response
287
+ */
288
+ async settle(payload, requirements) {
289
+ const exactSvmPayload = payload.payload;
290
+ const valid = await this.verify(payload, requirements);
291
+ if (!valid.isValid) {
292
+ return {
293
+ success: false,
294
+ network: payload.accepted.network,
295
+ transaction: "",
296
+ errorReason: valid.invalidReason ?? "verification_failed",
297
+ payer: valid.payer || ""
298
+ };
299
+ }
300
+ try {
301
+ const feePayer = requirements.extra.feePayer;
302
+ const fullySignedTransaction = await this.signer.signTransaction(
303
+ exactSvmPayload.transaction,
304
+ feePayer,
305
+ requirements.network
306
+ );
307
+ const signature = await this.signer.sendTransaction(
308
+ fullySignedTransaction,
309
+ requirements.network
310
+ );
311
+ await this.signer.confirmTransaction(signature, requirements.network);
312
+ return {
313
+ success: true,
314
+ transaction: signature,
315
+ network: payload.accepted.network,
316
+ payer: valid.payer
317
+ };
318
+ } catch (error) {
319
+ console.error("Failed to settle transaction:", error);
320
+ return {
321
+ success: false,
322
+ errorReason: "transaction_failed",
323
+ transaction: "",
324
+ network: payload.accepted.network,
325
+ payer: valid.payer || ""
326
+ };
327
+ }
328
+ }
329
+ /**
330
+ * Verify that the compute limit instruction is valid.
331
+ *
332
+ * @param instruction - The compute limit instruction
333
+ * @param instruction.programAddress - Program address
334
+ * @param instruction.data - Instruction data bytes
335
+ */
336
+ verifyComputeLimitInstruction(instruction) {
337
+ const programAddress = instruction.programAddress.toString();
338
+ if (programAddress !== import_compute_budget.COMPUTE_BUDGET_PROGRAM_ADDRESS.toString() || !instruction.data || instruction.data[0] !== 2) {
339
+ throw new Error(
340
+ "invalid_exact_svm_payload_transaction_instructions_compute_limit_instruction"
341
+ );
342
+ }
343
+ try {
344
+ (0, import_compute_budget.parseSetComputeUnitLimitInstruction)(instruction);
345
+ } catch {
346
+ throw new Error(
347
+ "invalid_exact_svm_payload_transaction_instructions_compute_limit_instruction"
348
+ );
349
+ }
350
+ }
351
+ /**
352
+ * Verify that the compute price instruction is valid.
353
+ *
354
+ * @param instruction - The compute price instruction
355
+ * @param instruction.programAddress - Program address
356
+ * @param instruction.data - Instruction data bytes
357
+ */
358
+ verifyComputePriceInstruction(instruction) {
359
+ const programAddress = instruction.programAddress.toString();
360
+ if (programAddress !== import_compute_budget.COMPUTE_BUDGET_PROGRAM_ADDRESS.toString() || !instruction.data || instruction.data[0] !== 3) {
361
+ throw new Error(
362
+ "invalid_exact_svm_payload_transaction_instructions_compute_price_instruction"
363
+ );
364
+ }
365
+ try {
366
+ const parsedInstruction = (0, import_compute_budget.parseSetComputeUnitPriceInstruction)(instruction);
367
+ if (parsedInstruction.microLamports > BigInt(MAX_COMPUTE_UNIT_PRICE_MICROLAMPORTS)) {
368
+ throw new Error(
369
+ "invalid_exact_svm_payload_transaction_instructions_compute_price_instruction_too_high"
370
+ );
371
+ }
372
+ } catch (error) {
373
+ if (error instanceof Error && error.message.includes("too_high")) {
374
+ throw error;
375
+ }
376
+ throw new Error(
377
+ "invalid_exact_svm_payload_transaction_instructions_compute_price_instruction"
378
+ );
379
+ }
380
+ }
381
+ };
382
+
383
+ // src/exact/v1/facilitator/scheme.ts
384
+ var import_compute_budget2 = require("@solana-program/compute-budget");
385
+ var import_token3 = require("@solana-program/token");
386
+ var import_token_20223 = require("@solana-program/token-2022");
387
+ var import_kit3 = require("@solana/kit");
388
+ var ExactSvmSchemeV1 = class {
389
+ /**
390
+ * Creates a new ExactSvmFacilitatorV1 instance.
391
+ *
392
+ * @param signer - The SVM RPC client for facilitator operations
393
+ * @returns ExactSvmFacilitatorV1 instance
394
+ */
395
+ constructor(signer) {
396
+ this.signer = signer;
397
+ this.scheme = "exact";
398
+ this.caipFamily = "solana:*";
399
+ }
400
+ /**
401
+ * Get mechanism-specific extra data for the supported kinds endpoint.
402
+ * For SVM, this includes a randomly selected fee payer address.
403
+ * Random selection distributes load across multiple signers.
404
+ *
405
+ * @param _ - The network identifier (unused for SVM)
406
+ * @returns Extra data with feePayer address
407
+ */
408
+ getExtra(_) {
409
+ const addresses = this.signer.getAddresses();
410
+ const randomIndex = Math.floor(Math.random() * addresses.length);
411
+ return {
412
+ feePayer: addresses[randomIndex]
413
+ };
414
+ }
415
+ /**
416
+ * Get signer addresses used by this facilitator.
417
+ * For SVM, returns all available fee payer addresses.
418
+ *
419
+ * @param _ - The network identifier (unused for SVM)
420
+ * @returns Array of fee payer addresses
421
+ */
422
+ getSigners(_) {
423
+ return [...this.signer.getAddresses()];
424
+ }
425
+ /**
426
+ * Verifies a payment payload (V1).
427
+ *
428
+ * @param payload - The payment payload to verify
429
+ * @param requirements - The payment requirements
430
+ * @returns Promise resolving to verification response
431
+ */
432
+ async verify(payload, requirements) {
433
+ const requirementsV1 = requirements;
434
+ const payloadV1 = payload;
435
+ const exactSvmPayload = payload.payload;
436
+ if (payloadV1.scheme !== "exact" || requirements.scheme !== "exact") {
437
+ return {
438
+ isValid: false,
439
+ invalidReason: "unsupported_scheme",
440
+ payer: ""
441
+ };
442
+ }
443
+ if (payloadV1.network !== requirements.network) {
444
+ return {
445
+ isValid: false,
446
+ invalidReason: "network_mismatch",
447
+ payer: ""
448
+ };
449
+ }
450
+ if (!requirementsV1.extra?.feePayer || typeof requirementsV1.extra.feePayer !== "string") {
451
+ return {
452
+ isValid: false,
453
+ invalidReason: "invalid_exact_svm_payload_missing_fee_payer",
454
+ payer: ""
455
+ };
456
+ }
457
+ const signerAddresses = this.signer.getAddresses().map((addr) => addr.toString());
458
+ if (!signerAddresses.includes(requirementsV1.extra.feePayer)) {
459
+ return {
460
+ isValid: false,
461
+ invalidReason: "fee_payer_not_managed_by_facilitator",
462
+ payer: ""
463
+ };
464
+ }
465
+ let transaction;
466
+ try {
467
+ transaction = decodeTransactionFromPayload(exactSvmPayload);
468
+ } catch {
469
+ return {
470
+ isValid: false,
471
+ invalidReason: "invalid_exact_svm_payload_transaction_could_not_be_decoded",
472
+ payer: ""
473
+ };
474
+ }
475
+ const compiled = (0, import_kit3.getCompiledTransactionMessageDecoder)().decode(
476
+ transaction.messageBytes
477
+ );
478
+ const decompiled = (0, import_kit3.decompileTransactionMessage)(compiled);
479
+ const instructions = decompiled.instructions ?? [];
480
+ if (instructions.length !== 3) {
481
+ return {
482
+ isValid: false,
483
+ invalidReason: "invalid_exact_svm_payload_transaction_instructions_length",
484
+ payer: ""
485
+ };
486
+ }
487
+ try {
488
+ this.verifyComputeLimitInstruction(instructions[0]);
489
+ this.verifyComputePriceInstruction(instructions[1]);
490
+ } catch (error) {
491
+ const errorMessage = error instanceof Error ? error.message : String(error);
492
+ return {
493
+ isValid: false,
494
+ invalidReason: errorMessage,
495
+ payer: ""
496
+ };
497
+ }
498
+ const payer = getTokenPayerFromTransaction(transaction);
499
+ if (!payer) {
500
+ return {
501
+ isValid: false,
502
+ invalidReason: "invalid_exact_svm_payload_no_transfer_instruction",
503
+ payer: ""
504
+ };
505
+ }
506
+ const transferIx = instructions[2];
507
+ const programAddress = transferIx.programAddress.toString();
508
+ if (programAddress !== import_token3.TOKEN_PROGRAM_ADDRESS.toString() && programAddress !== import_token_20223.TOKEN_2022_PROGRAM_ADDRESS.toString()) {
509
+ return {
510
+ isValid: false,
511
+ invalidReason: "invalid_exact_svm_payload_no_transfer_instruction",
512
+ payer
513
+ };
514
+ }
515
+ let parsedTransfer;
516
+ try {
517
+ if (programAddress === import_token3.TOKEN_PROGRAM_ADDRESS.toString()) {
518
+ parsedTransfer = (0, import_token3.parseTransferCheckedInstruction)(transferIx);
519
+ } else {
520
+ parsedTransfer = (0, import_token_20223.parseTransferCheckedInstruction)(transferIx);
521
+ }
522
+ } catch {
523
+ return {
524
+ isValid: false,
525
+ invalidReason: "invalid_exact_svm_payload_no_transfer_instruction",
526
+ payer
527
+ };
528
+ }
529
+ const authorityAddress = parsedTransfer.accounts.authority.address.toString();
530
+ if (signerAddresses.includes(authorityAddress)) {
531
+ return {
532
+ isValid: false,
533
+ invalidReason: "invalid_exact_svm_payload_transaction_fee_payer_transferring_funds",
534
+ payer
535
+ };
536
+ }
537
+ const mintAddress = parsedTransfer.accounts.mint.address.toString();
538
+ if (mintAddress !== requirements.asset) {
539
+ return {
540
+ isValid: false,
541
+ invalidReason: "invalid_exact_svm_payload_mint_mismatch",
542
+ payer
543
+ };
544
+ }
545
+ const destATA = parsedTransfer.accounts.destination.address.toString();
546
+ try {
547
+ const [expectedDestATA] = await (0, import_token_20223.findAssociatedTokenPda)({
548
+ mint: requirements.asset,
549
+ owner: requirements.payTo,
550
+ tokenProgram: programAddress === import_token3.TOKEN_PROGRAM_ADDRESS.toString() ? import_token3.TOKEN_PROGRAM_ADDRESS : import_token_20223.TOKEN_2022_PROGRAM_ADDRESS
551
+ });
552
+ if (destATA !== expectedDestATA.toString()) {
553
+ return {
554
+ isValid: false,
555
+ invalidReason: "invalid_exact_svm_payload_recipient_mismatch",
556
+ payer
557
+ };
558
+ }
559
+ } catch {
560
+ return {
561
+ isValid: false,
562
+ invalidReason: "invalid_exact_svm_payload_recipient_mismatch",
563
+ payer
564
+ };
565
+ }
566
+ const amount = parsedTransfer.data.amount;
567
+ if (amount < BigInt(requirementsV1.maxAmountRequired)) {
568
+ return {
569
+ isValid: false,
570
+ invalidReason: "invalid_exact_svm_payload_amount_insufficient",
571
+ payer
572
+ };
573
+ }
574
+ try {
575
+ const feePayer = requirementsV1.extra.feePayer;
576
+ const fullySignedTransaction = await this.signer.signTransaction(
577
+ exactSvmPayload.transaction,
578
+ feePayer,
579
+ requirements.network
580
+ );
581
+ await this.signer.simulateTransaction(fullySignedTransaction, requirements.network);
582
+ } catch (error) {
583
+ const errorMessage = error instanceof Error ? error.message : String(error);
584
+ return {
585
+ isValid: false,
586
+ invalidReason: `transaction_simulation_failed: ${errorMessage}`,
587
+ payer
588
+ };
589
+ }
590
+ return {
591
+ isValid: true,
592
+ invalidReason: void 0,
593
+ payer
594
+ };
595
+ }
596
+ /**
597
+ * Settles a payment by submitting the transaction (V1).
598
+ * Ensures the correct signer is used based on the feePayer specified in requirements.
599
+ *
600
+ * @param payload - The payment payload to settle
601
+ * @param requirements - The payment requirements
602
+ * @returns Promise resolving to settlement response
603
+ */
604
+ async settle(payload, requirements) {
605
+ const payloadV1 = payload;
606
+ const exactSvmPayload = payload.payload;
607
+ const valid = await this.verify(payload, requirements);
608
+ if (!valid.isValid) {
609
+ return {
610
+ success: false,
611
+ network: payloadV1.network,
612
+ transaction: "",
613
+ errorReason: valid.invalidReason ?? "verification_failed",
614
+ payer: valid.payer || ""
615
+ };
616
+ }
617
+ try {
618
+ const feePayer = requirements.extra.feePayer;
619
+ const fullySignedTransaction = await this.signer.signTransaction(
620
+ exactSvmPayload.transaction,
621
+ feePayer,
622
+ requirements.network
623
+ );
624
+ const signature = await this.signer.sendTransaction(
625
+ fullySignedTransaction,
626
+ requirements.network
627
+ );
628
+ await this.signer.confirmTransaction(signature, requirements.network);
629
+ return {
630
+ success: true,
631
+ transaction: signature,
632
+ network: payloadV1.network,
633
+ payer: valid.payer
634
+ };
635
+ } catch (error) {
636
+ console.error("Failed to settle transaction:", error);
637
+ return {
638
+ success: false,
639
+ errorReason: "transaction_failed",
640
+ transaction: "",
641
+ network: payloadV1.network,
642
+ payer: valid.payer || ""
643
+ };
644
+ }
645
+ }
646
+ /**
647
+ * Verify compute limit instruction
648
+ *
649
+ * @param instruction - The compute limit instruction
650
+ * @param instruction.programAddress - Program address
651
+ * @param instruction.data - Instruction data bytes
652
+ */
653
+ verifyComputeLimitInstruction(instruction) {
654
+ const programAddress = instruction.programAddress.toString();
655
+ if (programAddress !== import_compute_budget2.COMPUTE_BUDGET_PROGRAM_ADDRESS.toString() || !instruction.data || instruction.data[0] !== 2) {
656
+ throw new Error(
657
+ "invalid_exact_svm_payload_transaction_instructions_compute_limit_instruction"
658
+ );
659
+ }
660
+ try {
661
+ (0, import_compute_budget2.parseSetComputeUnitLimitInstruction)(instruction);
662
+ } catch {
663
+ throw new Error(
664
+ "invalid_exact_svm_payload_transaction_instructions_compute_limit_instruction"
665
+ );
666
+ }
667
+ }
668
+ /**
669
+ * Verify compute price instruction
670
+ *
671
+ * @param instruction - The compute price instruction
672
+ * @param instruction.programAddress - Program address
673
+ * @param instruction.data - Instruction data bytes
674
+ */
675
+ verifyComputePriceInstruction(instruction) {
676
+ const programAddress = instruction.programAddress.toString();
677
+ if (programAddress !== import_compute_budget2.COMPUTE_BUDGET_PROGRAM_ADDRESS.toString() || !instruction.data || instruction.data[0] !== 3) {
678
+ throw new Error(
679
+ "invalid_exact_svm_payload_transaction_instructions_compute_price_instruction"
680
+ );
681
+ }
682
+ try {
683
+ const parsedInstruction = (0, import_compute_budget2.parseSetComputeUnitPriceInstruction)(instruction);
684
+ if (parsedInstruction.microLamports > BigInt(MAX_COMPUTE_UNIT_PRICE_MICROLAMPORTS)) {
685
+ throw new Error(
686
+ "invalid_exact_svm_payload_transaction_instructions_compute_price_instruction_too_high"
687
+ );
688
+ }
689
+ } catch (error) {
690
+ if (error instanceof Error && error.message.includes("too_high")) {
691
+ throw error;
692
+ }
693
+ throw new Error(
694
+ "invalid_exact_svm_payload_transaction_instructions_compute_price_instruction"
695
+ );
696
+ }
697
+ }
698
+ };
699
+
700
+ // src/exact/v1/client/scheme.ts
701
+ var import_compute_budget3 = require("@solana-program/compute-budget");
702
+ var import_token4 = require("@solana-program/token");
703
+ var import_token_20224 = require("@solana-program/token-2022");
704
+ var import_kit4 = require("@solana/kit");
705
+
706
+ // src/v1/index.ts
707
+ var NETWORKS = ["solana", "solana-devnet", "solana-testnet"];
708
+
709
+ // src/exact/facilitator/register.ts
710
+ function registerExactSvmScheme(facilitator, config) {
711
+ facilitator.register(config.networks, new ExactSvmScheme(config.signer));
712
+ facilitator.registerV1(NETWORKS, new ExactSvmSchemeV1(config.signer));
713
+ return facilitator;
714
+ }
715
+ // Annotate the CommonJS export names for ESM import in node:
716
+ 0 && (module.exports = {
717
+ ExactSvmScheme,
718
+ registerExactSvmScheme
719
+ });
720
+ //# sourceMappingURL=index.js.map