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