sf-x402x 0.6.6-patch.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 +60 -0
- package/dist/cjs/client/index.d.ts +64 -0
- package/dist/cjs/client/index.js +811 -0
- package/dist/cjs/client/index.js.map +1 -0
- package/dist/cjs/config-CFBSAuxW.d.ts +10 -0
- package/dist/cjs/config-Dfuvno71.d.ts +19 -0
- package/dist/cjs/facilitator/index.d.ts +42 -0
- package/dist/cjs/facilitator/index.js +1827 -0
- package/dist/cjs/facilitator/index.js.map +1 -0
- package/dist/cjs/index.d.ts +16 -0
- package/dist/cjs/index.js +2207 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/middleware-BcYD9vqv.d.ts +93 -0
- package/dist/cjs/middleware-DagbDyNz.d.ts +93 -0
- package/dist/cjs/network--RYzQfBg.d.ts +11 -0
- package/dist/cjs/network-BGTUrx-D.d.ts +11 -0
- package/dist/cjs/paywall/index.d.ts +30 -0
- package/dist/cjs/paywall/index.js +141 -0
- package/dist/cjs/paywall/index.js.map +1 -0
- package/dist/cjs/rpc-De2c0oKR.d.ts +35 -0
- package/dist/cjs/rpc-TVntAK7V.d.ts +35 -0
- package/dist/cjs/schemes/index.d.ts +298 -0
- package/dist/cjs/schemes/index.js +2121 -0
- package/dist/cjs/schemes/index.js.map +1 -0
- package/dist/cjs/shared/evm/index.d.ts +55 -0
- package/dist/cjs/shared/evm/index.js +910 -0
- package/dist/cjs/shared/evm/index.js.map +1 -0
- package/dist/cjs/shared/index.d.ts +181 -0
- package/dist/cjs/shared/index.js +667 -0
- package/dist/cjs/shared/index.js.map +1 -0
- package/dist/cjs/types/index.d.ts +1214 -0
- package/dist/cjs/types/index.js +1408 -0
- package/dist/cjs/types/index.js.map +1 -0
- package/dist/cjs/verify/index.d.ts +7 -0
- package/dist/cjs/verify/index.js +427 -0
- package/dist/cjs/verify/index.js.map +1 -0
- package/dist/cjs/wallet-BReyvAJs.d.ts +151 -0
- package/dist/cjs/wallet-BTqCm9Zp.d.ts +27 -0
- package/dist/cjs/wallet-DndoTf1_.d.ts +48 -0
- package/dist/cjs/x402Specs-7OH8g851.d.ts +1306 -0
- package/dist/cjs/x402Specs-CFX8TBKR.d.ts +1306 -0
- package/dist/esm/chunk-5UPAZUO6.mjs +90 -0
- package/dist/esm/chunk-5UPAZUO6.mjs.map +1 -0
- package/dist/esm/chunk-7CWEZNFA.mjs +812 -0
- package/dist/esm/chunk-7CWEZNFA.mjs.map +1 -0
- package/dist/esm/chunk-MWDK4RSB.mjs +620 -0
- package/dist/esm/chunk-MWDK4RSB.mjs.map +1 -0
- package/dist/esm/chunk-R2NI44QI.mjs +327 -0
- package/dist/esm/chunk-R2NI44QI.mjs.map +1 -0
- package/dist/esm/chunk-WS2W5DJT.mjs +58 -0
- package/dist/esm/chunk-WS2W5DJT.mjs.map +1 -0
- package/dist/esm/chunk-XZA3USQF.mjs +784 -0
- package/dist/esm/chunk-XZA3USQF.mjs.map +1 -0
- package/dist/esm/chunk-Z3INM7T4.mjs +106 -0
- package/dist/esm/chunk-Z3INM7T4.mjs.map +1 -0
- package/dist/esm/client/index.d.mts +64 -0
- package/dist/esm/client/index.mjs +17 -0
- package/dist/esm/client/index.mjs.map +1 -0
- package/dist/esm/config-CFBSAuxW.d.mts +10 -0
- package/dist/esm/config-Dfuvno71.d.mts +19 -0
- package/dist/esm/facilitator/index.d.mts +42 -0
- package/dist/esm/facilitator/index.mjs +14 -0
- package/dist/esm/facilitator/index.mjs.map +1 -0
- package/dist/esm/index.d.mts +16 -0
- package/dist/esm/index.mjs +28 -0
- package/dist/esm/index.mjs.map +1 -0
- package/dist/esm/middleware-CAOp-bv4.d.mts +93 -0
- package/dist/esm/network--RYzQfBg.d.mts +11 -0
- package/dist/esm/paywall/index.d.mts +30 -0
- package/dist/esm/paywall/index.mjs +46 -0
- package/dist/esm/paywall/index.mjs.map +1 -0
- package/dist/esm/rpc-22QIQWIu.d.mts +35 -0
- package/dist/esm/schemes/index.d.mts +298 -0
- package/dist/esm/schemes/index.mjs +16 -0
- package/dist/esm/schemes/index.mjs.map +1 -0
- package/dist/esm/shared/evm/index.d.mts +55 -0
- package/dist/esm/shared/evm/index.mjs +18 -0
- package/dist/esm/shared/evm/index.mjs.map +1 -0
- package/dist/esm/shared/index.d.mts +181 -0
- package/dist/esm/shared/index.mjs +31 -0
- package/dist/esm/shared/index.mjs.map +1 -0
- package/dist/esm/types/index.d.mts +1214 -0
- package/dist/esm/types/index.mjs +81 -0
- package/dist/esm/types/index.mjs.map +1 -0
- package/dist/esm/verify/index.d.mts +7 -0
- package/dist/esm/verify/index.mjs +105 -0
- package/dist/esm/verify/index.mjs.map +1 -0
- package/dist/esm/wallet-BReyvAJs.d.mts +151 -0
- package/dist/esm/wallet-BTqCm9Zp.d.mts +27 -0
- package/dist/esm/wallet-C9iHSQbd.d.mts +48 -0
- package/dist/esm/x402Specs-7OH8g851.d.mts +1306 -0
- package/package.json +152 -0
|
@@ -0,0 +1,620 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createAndSignPayment,
|
|
3
|
+
createPayment,
|
|
4
|
+
createPaymentHeader,
|
|
5
|
+
createPaymentHeader2,
|
|
6
|
+
decodePayment,
|
|
7
|
+
encodePayment,
|
|
8
|
+
preparePaymentHeader,
|
|
9
|
+
signPaymentHeader
|
|
10
|
+
} from "./chunk-R2NI44QI.mjs";
|
|
11
|
+
import {
|
|
12
|
+
ErrorReasons,
|
|
13
|
+
SupportedSVMNetworks,
|
|
14
|
+
authorizationTypes,
|
|
15
|
+
decodeTransactionFromPayload,
|
|
16
|
+
getNetworkId,
|
|
17
|
+
getRpcClient,
|
|
18
|
+
getRpcSubscriptions,
|
|
19
|
+
getTokenPayerFromTransaction,
|
|
20
|
+
signAndSimulateTransaction
|
|
21
|
+
} from "./chunk-XZA3USQF.mjs";
|
|
22
|
+
import {
|
|
23
|
+
getERC20Balance,
|
|
24
|
+
getVersion,
|
|
25
|
+
usdcABI
|
|
26
|
+
} from "./chunk-7CWEZNFA.mjs";
|
|
27
|
+
import {
|
|
28
|
+
__export,
|
|
29
|
+
config
|
|
30
|
+
} from "./chunk-5UPAZUO6.mjs";
|
|
31
|
+
|
|
32
|
+
// src/schemes/exact/index.ts
|
|
33
|
+
var exact_exports = {};
|
|
34
|
+
__export(exact_exports, {
|
|
35
|
+
SCHEME: () => SCHEME,
|
|
36
|
+
evm: () => evm_exports,
|
|
37
|
+
svm: () => svm_exports
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// src/schemes/exact/evm/index.ts
|
|
41
|
+
var evm_exports = {};
|
|
42
|
+
__export(evm_exports, {
|
|
43
|
+
createPayment: () => createPayment,
|
|
44
|
+
createPaymentHeader: () => createPaymentHeader,
|
|
45
|
+
decodePayment: () => decodePayment,
|
|
46
|
+
encodePayment: () => encodePayment,
|
|
47
|
+
preparePaymentHeader: () => preparePaymentHeader,
|
|
48
|
+
settle: () => settle,
|
|
49
|
+
signPaymentHeader: () => signPaymentHeader,
|
|
50
|
+
verify: () => verify
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// src/schemes/exact/evm/facilitator.ts
|
|
54
|
+
import { getAddress, parseErc6492Signature } from "viem";
|
|
55
|
+
async function verify(client, payload, paymentRequirements) {
|
|
56
|
+
const exactEvmPayload = payload.payload;
|
|
57
|
+
if (payload.scheme !== SCHEME || paymentRequirements.scheme !== SCHEME) {
|
|
58
|
+
return {
|
|
59
|
+
isValid: false,
|
|
60
|
+
invalidReason: `unsupported_scheme`,
|
|
61
|
+
payer: exactEvmPayload.authorization.from
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
let name;
|
|
65
|
+
let chainId;
|
|
66
|
+
let erc20Address;
|
|
67
|
+
let version;
|
|
68
|
+
try {
|
|
69
|
+
chainId = getNetworkId(payload.network);
|
|
70
|
+
name = paymentRequirements.extra?.name ?? config[chainId.toString()].usdcName;
|
|
71
|
+
erc20Address = paymentRequirements.asset;
|
|
72
|
+
version = paymentRequirements.extra?.version ?? await getVersion(client);
|
|
73
|
+
} catch {
|
|
74
|
+
return {
|
|
75
|
+
isValid: false,
|
|
76
|
+
invalidReason: `invalid_network`,
|
|
77
|
+
payer: payload.payload.authorization.from
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
const permitTypedData = {
|
|
81
|
+
types: authorizationTypes,
|
|
82
|
+
primaryType: "TransferWithAuthorization",
|
|
83
|
+
domain: {
|
|
84
|
+
name,
|
|
85
|
+
version,
|
|
86
|
+
chainId,
|
|
87
|
+
verifyingContract: erc20Address
|
|
88
|
+
},
|
|
89
|
+
message: {
|
|
90
|
+
from: exactEvmPayload.authorization.from,
|
|
91
|
+
to: exactEvmPayload.authorization.to,
|
|
92
|
+
value: exactEvmPayload.authorization.value,
|
|
93
|
+
validAfter: exactEvmPayload.authorization.validAfter,
|
|
94
|
+
validBefore: exactEvmPayload.authorization.validBefore,
|
|
95
|
+
nonce: exactEvmPayload.authorization.nonce
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
const recoveredAddress = await client.verifyTypedData({
|
|
99
|
+
address: exactEvmPayload.authorization.from,
|
|
100
|
+
...permitTypedData,
|
|
101
|
+
signature: exactEvmPayload.signature
|
|
102
|
+
});
|
|
103
|
+
if (!recoveredAddress) {
|
|
104
|
+
return {
|
|
105
|
+
isValid: false,
|
|
106
|
+
invalidReason: "invalid_exact_evm_payload_signature",
|
|
107
|
+
//"Invalid permit signature",
|
|
108
|
+
payer: exactEvmPayload.authorization.from
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
if (getAddress(exactEvmPayload.authorization.to) !== getAddress(paymentRequirements.payTo)) {
|
|
112
|
+
return {
|
|
113
|
+
isValid: false,
|
|
114
|
+
invalidReason: "invalid_exact_evm_payload_recipient_mismatch",
|
|
115
|
+
payer: exactEvmPayload.authorization.from
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
if (BigInt(exactEvmPayload.authorization.validBefore) < BigInt(Math.floor(Date.now() / 1e3) + 6)) {
|
|
119
|
+
return {
|
|
120
|
+
isValid: false,
|
|
121
|
+
invalidReason: "invalid_exact_evm_payload_authorization_valid_before",
|
|
122
|
+
//"Deadline on permit isn't far enough in the future",
|
|
123
|
+
payer: exactEvmPayload.authorization.from
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
if (BigInt(exactEvmPayload.authorization.validAfter) > BigInt(Math.floor(Date.now() / 1e3))) {
|
|
127
|
+
return {
|
|
128
|
+
isValid: false,
|
|
129
|
+
invalidReason: "invalid_exact_evm_payload_authorization_valid_after",
|
|
130
|
+
//"Deadline on permit is in the future",
|
|
131
|
+
payer: exactEvmPayload.authorization.from
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
const balance = await getERC20Balance(
|
|
135
|
+
client,
|
|
136
|
+
erc20Address,
|
|
137
|
+
exactEvmPayload.authorization.from
|
|
138
|
+
);
|
|
139
|
+
if (balance < BigInt(paymentRequirements.maxAmountRequired)) {
|
|
140
|
+
return {
|
|
141
|
+
isValid: false,
|
|
142
|
+
invalidReason: "insufficient_funds",
|
|
143
|
+
//"Client does not have enough funds",
|
|
144
|
+
payer: exactEvmPayload.authorization.from
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
if (BigInt(exactEvmPayload.authorization.value) < BigInt(paymentRequirements.maxAmountRequired)) {
|
|
148
|
+
return {
|
|
149
|
+
isValid: false,
|
|
150
|
+
invalidReason: "invalid_exact_evm_payload_authorization_value",
|
|
151
|
+
//"Value in payload is not enough to cover paymentRequirements.maxAmountRequired",
|
|
152
|
+
payer: exactEvmPayload.authorization.from
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
return {
|
|
156
|
+
isValid: true,
|
|
157
|
+
invalidReason: void 0,
|
|
158
|
+
payer: exactEvmPayload.authorization.from
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
async function settle(wallet, paymentPayload, paymentRequirements) {
|
|
162
|
+
const payload = paymentPayload.payload;
|
|
163
|
+
const valid = await verify(wallet, paymentPayload, paymentRequirements);
|
|
164
|
+
if (!valid.isValid) {
|
|
165
|
+
return {
|
|
166
|
+
success: false,
|
|
167
|
+
network: paymentPayload.network,
|
|
168
|
+
transaction: "",
|
|
169
|
+
errorReason: valid.invalidReason ?? "invalid_scheme",
|
|
170
|
+
//`Payment is no longer valid: ${valid.invalidReason}`,
|
|
171
|
+
payer: payload.authorization.from
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
const { signature } = parseErc6492Signature(payload.signature);
|
|
175
|
+
const tx = await wallet.writeContract({
|
|
176
|
+
address: paymentRequirements.asset,
|
|
177
|
+
abi: usdcABI,
|
|
178
|
+
functionName: "transferWithAuthorization",
|
|
179
|
+
args: [
|
|
180
|
+
payload.authorization.from,
|
|
181
|
+
payload.authorization.to,
|
|
182
|
+
BigInt(payload.authorization.value),
|
|
183
|
+
BigInt(payload.authorization.validAfter),
|
|
184
|
+
BigInt(payload.authorization.validBefore),
|
|
185
|
+
payload.authorization.nonce,
|
|
186
|
+
signature
|
|
187
|
+
],
|
|
188
|
+
chain: wallet.chain
|
|
189
|
+
});
|
|
190
|
+
const receipt = await wallet.waitForTransactionReceipt({ hash: tx });
|
|
191
|
+
if (receipt.status !== "success") {
|
|
192
|
+
return {
|
|
193
|
+
success: false,
|
|
194
|
+
errorReason: "invalid_transaction_state",
|
|
195
|
+
//`Transaction failed`,
|
|
196
|
+
transaction: tx,
|
|
197
|
+
network: paymentPayload.network,
|
|
198
|
+
payer: payload.authorization.from
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
return {
|
|
202
|
+
success: true,
|
|
203
|
+
transaction: tx,
|
|
204
|
+
network: paymentPayload.network,
|
|
205
|
+
payer: payload.authorization.from
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// src/schemes/exact/svm/index.ts
|
|
210
|
+
var svm_exports = {};
|
|
211
|
+
__export(svm_exports, {
|
|
212
|
+
confirmSignedTransaction: () => confirmSignedTransaction,
|
|
213
|
+
createAndSignPayment: () => createAndSignPayment,
|
|
214
|
+
createPaymentHeader: () => createPaymentHeader2,
|
|
215
|
+
getValidatedTransferCheckedInstruction: () => getValidatedTransferCheckedInstruction,
|
|
216
|
+
sendAndConfirmSignedTransaction: () => sendAndConfirmSignedTransaction,
|
|
217
|
+
sendSignedTransaction: () => sendSignedTransaction,
|
|
218
|
+
settle: () => settle2,
|
|
219
|
+
transactionIntrospection: () => transactionIntrospection,
|
|
220
|
+
verify: () => verify2,
|
|
221
|
+
verifyComputeLimitInstruction: () => verifyComputeLimitInstruction,
|
|
222
|
+
verifyComputePriceInstruction: () => verifyComputePriceInstruction,
|
|
223
|
+
verifyCreateATAInstruction: () => verifyCreateATAInstruction,
|
|
224
|
+
verifySchemesAndNetworks: () => verifySchemesAndNetworks,
|
|
225
|
+
verifyTransactionInstructions: () => verifyTransactionInstructions,
|
|
226
|
+
verifyTransferCheckedInstruction: () => verifyTransferCheckedInstruction,
|
|
227
|
+
verifyTransferInstruction: () => verifyTransferInstruction
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
// src/schemes/exact/svm/facilitator/settle.ts
|
|
231
|
+
import {
|
|
232
|
+
assertIsTransactionMessageWithBlockhashLifetime,
|
|
233
|
+
decompileTransactionMessageFetchingLookupTables,
|
|
234
|
+
getBase64EncodedWireTransaction,
|
|
235
|
+
getCompiledTransactionMessageDecoder as getCompiledTransactionMessageDecoder2,
|
|
236
|
+
getSignatureFromTransaction,
|
|
237
|
+
isSolanaError,
|
|
238
|
+
signTransaction,
|
|
239
|
+
SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED
|
|
240
|
+
} from "@solana/kit";
|
|
241
|
+
import {
|
|
242
|
+
createBlockHeightExceedencePromiseFactory,
|
|
243
|
+
waitForRecentTransactionConfirmation,
|
|
244
|
+
createRecentSignatureConfirmationPromiseFactory
|
|
245
|
+
} from "@solana/transaction-confirmation";
|
|
246
|
+
|
|
247
|
+
// src/schemes/exact/svm/facilitator/verify.ts
|
|
248
|
+
import {
|
|
249
|
+
assertIsInstructionWithAccounts,
|
|
250
|
+
assertIsInstructionWithData,
|
|
251
|
+
decompileTransactionMessage,
|
|
252
|
+
fetchEncodedAccounts,
|
|
253
|
+
getCompiledTransactionMessageDecoder
|
|
254
|
+
} from "@solana/kit";
|
|
255
|
+
import {
|
|
256
|
+
parseSetComputeUnitLimitInstruction,
|
|
257
|
+
parseSetComputeUnitPriceInstruction,
|
|
258
|
+
COMPUTE_BUDGET_PROGRAM_ADDRESS
|
|
259
|
+
} from "@solana-program/compute-budget";
|
|
260
|
+
import {
|
|
261
|
+
findAssociatedTokenPda,
|
|
262
|
+
identifyToken2022Instruction,
|
|
263
|
+
parseCreateAssociatedTokenInstruction,
|
|
264
|
+
parseTransferCheckedInstruction as parseTransferCheckedInstruction2022,
|
|
265
|
+
Token2022Instruction,
|
|
266
|
+
TOKEN_2022_PROGRAM_ADDRESS
|
|
267
|
+
} from "@solana-program/token-2022";
|
|
268
|
+
import {
|
|
269
|
+
identifyTokenInstruction,
|
|
270
|
+
parseTransferCheckedInstruction as parseTransferCheckedInstructionToken,
|
|
271
|
+
TOKEN_PROGRAM_ADDRESS,
|
|
272
|
+
TokenInstruction
|
|
273
|
+
} from "@solana-program/token";
|
|
274
|
+
async function verify2(signer, payload, paymentRequirements, config2) {
|
|
275
|
+
try {
|
|
276
|
+
verifySchemesAndNetworks(payload, paymentRequirements);
|
|
277
|
+
const svmPayload = payload.payload;
|
|
278
|
+
const decodedTransaction = decodeTransactionFromPayload(svmPayload);
|
|
279
|
+
const rpc = getRpcClient(paymentRequirements.network, config2?.svmConfig?.rpcUrl);
|
|
280
|
+
await transactionIntrospection(svmPayload, paymentRequirements, config2);
|
|
281
|
+
const simulateResult = await signAndSimulateTransaction(signer, decodedTransaction, rpc);
|
|
282
|
+
if (simulateResult.value?.err) {
|
|
283
|
+
throw new Error(`invalid_exact_svm_payload_transaction_simulation_failed`);
|
|
284
|
+
}
|
|
285
|
+
return {
|
|
286
|
+
isValid: true,
|
|
287
|
+
invalidReason: void 0,
|
|
288
|
+
payer: getTokenPayerFromTransaction(decodedTransaction)
|
|
289
|
+
};
|
|
290
|
+
} catch (error) {
|
|
291
|
+
if (error instanceof Error) {
|
|
292
|
+
if (ErrorReasons.includes(error.message)) {
|
|
293
|
+
return {
|
|
294
|
+
isValid: false,
|
|
295
|
+
invalidReason: error.message,
|
|
296
|
+
payer: (() => {
|
|
297
|
+
try {
|
|
298
|
+
const tx = decodeTransactionFromPayload(payload.payload);
|
|
299
|
+
return getTokenPayerFromTransaction(tx);
|
|
300
|
+
} catch {
|
|
301
|
+
return void 0;
|
|
302
|
+
}
|
|
303
|
+
})()
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
console.error(error);
|
|
308
|
+
return {
|
|
309
|
+
isValid: false,
|
|
310
|
+
invalidReason: "unexpected_verify_error",
|
|
311
|
+
payer: (() => {
|
|
312
|
+
try {
|
|
313
|
+
const tx = decodeTransactionFromPayload(payload.payload);
|
|
314
|
+
return getTokenPayerFromTransaction(tx);
|
|
315
|
+
} catch {
|
|
316
|
+
return void 0;
|
|
317
|
+
}
|
|
318
|
+
})()
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
function verifySchemesAndNetworks(payload, paymentRequirements) {
|
|
323
|
+
if (payload.scheme !== SCHEME || paymentRequirements.scheme !== SCHEME) {
|
|
324
|
+
throw new Error("unsupported_scheme");
|
|
325
|
+
}
|
|
326
|
+
if (payload.network !== paymentRequirements.network || !SupportedSVMNetworks.includes(paymentRequirements.network)) {
|
|
327
|
+
throw new Error("invalid_network");
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
async function transactionIntrospection(svmPayload, paymentRequirements, config2) {
|
|
331
|
+
const rpc = getRpcClient(paymentRequirements.network, config2?.svmConfig?.rpcUrl);
|
|
332
|
+
const decodedTransaction = decodeTransactionFromPayload(svmPayload);
|
|
333
|
+
const compiledTransactionMessage = getCompiledTransactionMessageDecoder().decode(
|
|
334
|
+
decodedTransaction.messageBytes
|
|
335
|
+
);
|
|
336
|
+
const transactionMessage = decompileTransactionMessage(
|
|
337
|
+
compiledTransactionMessage
|
|
338
|
+
);
|
|
339
|
+
await verifyTransactionInstructions(transactionMessage, paymentRequirements, rpc);
|
|
340
|
+
}
|
|
341
|
+
async function verifyTransactionInstructions(transactionMessage, paymentRequirements, rpc) {
|
|
342
|
+
if (transactionMessage.instructions.length !== 3 && transactionMessage.instructions.length !== 4) {
|
|
343
|
+
throw new Error(`invalid_exact_svm_payload_transaction_instructions_length`);
|
|
344
|
+
}
|
|
345
|
+
verifyComputeLimitInstruction(transactionMessage.instructions[0]);
|
|
346
|
+
verifyComputePriceInstruction(transactionMessage.instructions[1]);
|
|
347
|
+
if (transactionMessage.instructions.length === 3) {
|
|
348
|
+
await verifyTransferInstruction(
|
|
349
|
+
transactionMessage.instructions[2],
|
|
350
|
+
paymentRequirements,
|
|
351
|
+
{
|
|
352
|
+
txHasCreateDestATAInstruction: false
|
|
353
|
+
},
|
|
354
|
+
rpc
|
|
355
|
+
);
|
|
356
|
+
} else {
|
|
357
|
+
verifyCreateATAInstruction(transactionMessage.instructions[2], paymentRequirements);
|
|
358
|
+
await verifyTransferInstruction(
|
|
359
|
+
transactionMessage.instructions[3],
|
|
360
|
+
paymentRequirements,
|
|
361
|
+
{
|
|
362
|
+
txHasCreateDestATAInstruction: true
|
|
363
|
+
},
|
|
364
|
+
rpc
|
|
365
|
+
);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
function verifyComputeLimitInstruction(instruction) {
|
|
369
|
+
try {
|
|
370
|
+
if (instruction.programAddress.toString() !== COMPUTE_BUDGET_PROGRAM_ADDRESS.toString() || instruction.data?.[0] !== 2) {
|
|
371
|
+
throw new Error(
|
|
372
|
+
`invalid_exact_svm_payload_transaction_instructions_compute_limit_instruction`
|
|
373
|
+
);
|
|
374
|
+
}
|
|
375
|
+
parseSetComputeUnitLimitInstruction(
|
|
376
|
+
instruction
|
|
377
|
+
);
|
|
378
|
+
} catch (error) {
|
|
379
|
+
console.error(error);
|
|
380
|
+
throw new Error(`invalid_exact_svm_payload_transaction_instructions_compute_limit_instruction`);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
function verifyComputePriceInstruction(instruction) {
|
|
384
|
+
if (instruction.programAddress.toString() !== COMPUTE_BUDGET_PROGRAM_ADDRESS.toString() || instruction.data?.[0] !== 3) {
|
|
385
|
+
throw new Error(`invalid_exact_svm_payload_transaction_instructions_compute_price_instruction`);
|
|
386
|
+
}
|
|
387
|
+
const parsedInstruction = parseSetComputeUnitPriceInstruction(
|
|
388
|
+
instruction
|
|
389
|
+
);
|
|
390
|
+
if (parsedInstruction.data.microLamports > 5 * 1e6) {
|
|
391
|
+
throw new Error(
|
|
392
|
+
`invalid_exact_svm_payload_transaction_instructions_compute_price_instruction_too_high`
|
|
393
|
+
);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
function verifyCreateATAInstruction(instruction, paymentRequirements) {
|
|
397
|
+
let createATAInstruction;
|
|
398
|
+
try {
|
|
399
|
+
assertIsInstructionWithAccounts(instruction);
|
|
400
|
+
assertIsInstructionWithData(instruction);
|
|
401
|
+
createATAInstruction = parseCreateAssociatedTokenInstruction({
|
|
402
|
+
...instruction,
|
|
403
|
+
data: new Uint8Array(instruction.data)
|
|
404
|
+
});
|
|
405
|
+
} catch (error) {
|
|
406
|
+
console.error(error);
|
|
407
|
+
throw new Error(`invalid_exact_svm_payload_transaction_create_ata_instruction`);
|
|
408
|
+
}
|
|
409
|
+
if (createATAInstruction.accounts.owner.address !== paymentRequirements.payTo) {
|
|
410
|
+
throw new Error(`invalid_exact_svm_payload_transaction_create_ata_instruction_incorrect_payee`);
|
|
411
|
+
}
|
|
412
|
+
if (createATAInstruction.accounts.mint.address !== paymentRequirements.asset) {
|
|
413
|
+
throw new Error(`invalid_exact_svm_payload_transaction_create_ata_instruction_incorrect_asset`);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
async function verifyTransferInstruction(instruction, paymentRequirements, { txHasCreateDestATAInstruction }, rpc) {
|
|
417
|
+
const tokenInstruction = getValidatedTransferCheckedInstruction(instruction);
|
|
418
|
+
await verifyTransferCheckedInstruction(
|
|
419
|
+
tokenInstruction,
|
|
420
|
+
paymentRequirements,
|
|
421
|
+
{
|
|
422
|
+
txHasCreateDestATAInstruction
|
|
423
|
+
},
|
|
424
|
+
rpc
|
|
425
|
+
);
|
|
426
|
+
}
|
|
427
|
+
async function verifyTransferCheckedInstruction(parsedInstruction, paymentRequirements, { txHasCreateDestATAInstruction }, rpc) {
|
|
428
|
+
const tokenProgramAddress = parsedInstruction.programAddress.toString() === TOKEN_PROGRAM_ADDRESS.toString() ? TOKEN_PROGRAM_ADDRESS : TOKEN_2022_PROGRAM_ADDRESS;
|
|
429
|
+
const payToATA = await findAssociatedTokenPda({
|
|
430
|
+
mint: paymentRequirements.asset,
|
|
431
|
+
owner: paymentRequirements.payTo,
|
|
432
|
+
tokenProgram: tokenProgramAddress
|
|
433
|
+
});
|
|
434
|
+
if (parsedInstruction.accounts.destination.address !== payToATA[0]) {
|
|
435
|
+
throw new Error(`invalid_exact_svm_payload_transaction_transfer_to_incorrect_ata`);
|
|
436
|
+
}
|
|
437
|
+
const addresses = [parsedInstruction.accounts.source.address, payToATA[0]];
|
|
438
|
+
const maybeAccounts = await fetchEncodedAccounts(rpc, addresses);
|
|
439
|
+
const missingAccounts = maybeAccounts.filter((a) => !a.exists);
|
|
440
|
+
for (const missingAccount of missingAccounts) {
|
|
441
|
+
if (missingAccount.address === parsedInstruction.accounts.source.address) {
|
|
442
|
+
throw new Error(`invalid_exact_svm_payload_transaction_sender_ata_not_found`);
|
|
443
|
+
}
|
|
444
|
+
if (missingAccount.address === payToATA[0] && !txHasCreateDestATAInstruction) {
|
|
445
|
+
throw new Error(`invalid_exact_svm_payload_transaction_receiver_ata_not_found`);
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
const instructionAmount = parsedInstruction.data.amount;
|
|
449
|
+
const paymentRequirementsAmount = BigInt(paymentRequirements.maxAmountRequired);
|
|
450
|
+
if (instructionAmount !== paymentRequirementsAmount) {
|
|
451
|
+
throw new Error(`invalid_exact_svm_payload_transaction_amount_mismatch`);
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
function getValidatedTransferCheckedInstruction(instruction) {
|
|
455
|
+
try {
|
|
456
|
+
assertIsInstructionWithData(instruction);
|
|
457
|
+
assertIsInstructionWithAccounts(instruction);
|
|
458
|
+
} catch (error) {
|
|
459
|
+
console.error(error);
|
|
460
|
+
throw new Error(`invalid_exact_svm_payload_transaction_instructions`);
|
|
461
|
+
}
|
|
462
|
+
let tokenInstruction;
|
|
463
|
+
if (instruction.programAddress.toString() === TOKEN_PROGRAM_ADDRESS.toString()) {
|
|
464
|
+
const identifiedInstruction = identifyTokenInstruction(instruction);
|
|
465
|
+
if (identifiedInstruction !== TokenInstruction.TransferChecked) {
|
|
466
|
+
throw new Error(
|
|
467
|
+
`invalid_exact_svm_payload_transaction_instruction_not_spl_token_transfer_checked`
|
|
468
|
+
);
|
|
469
|
+
}
|
|
470
|
+
tokenInstruction = parseTransferCheckedInstructionToken({
|
|
471
|
+
...instruction,
|
|
472
|
+
data: new Uint8Array(instruction.data)
|
|
473
|
+
});
|
|
474
|
+
} else if (instruction.programAddress.toString() === TOKEN_2022_PROGRAM_ADDRESS.toString()) {
|
|
475
|
+
const identifiedInstruction = identifyToken2022Instruction(instruction);
|
|
476
|
+
if (identifiedInstruction !== Token2022Instruction.TransferChecked) {
|
|
477
|
+
throw new Error(
|
|
478
|
+
`invalid_exact_svm_payload_transaction_instruction_not_token_2022_transfer_checked`
|
|
479
|
+
);
|
|
480
|
+
}
|
|
481
|
+
tokenInstruction = parseTransferCheckedInstruction2022({
|
|
482
|
+
...instruction,
|
|
483
|
+
data: new Uint8Array(instruction.data)
|
|
484
|
+
});
|
|
485
|
+
} else {
|
|
486
|
+
throw new Error(`invalid_exact_svm_payload_transaction_not_a_transfer_instruction`);
|
|
487
|
+
}
|
|
488
|
+
return tokenInstruction;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
// src/schemes/exact/svm/facilitator/settle.ts
|
|
492
|
+
async function settle2(signer, payload, paymentRequirements, config2) {
|
|
493
|
+
const verifyResponse = await verify2(signer, payload, paymentRequirements, config2);
|
|
494
|
+
if (!verifyResponse.isValid) {
|
|
495
|
+
return {
|
|
496
|
+
success: false,
|
|
497
|
+
errorReason: verifyResponse.invalidReason,
|
|
498
|
+
network: payload.network,
|
|
499
|
+
transaction: ""
|
|
500
|
+
};
|
|
501
|
+
}
|
|
502
|
+
const svmPayload = payload.payload;
|
|
503
|
+
const decodedTransaction = decodeTransactionFromPayload(svmPayload);
|
|
504
|
+
const signedTransaction = await signTransaction([signer.keyPair], decodedTransaction);
|
|
505
|
+
const payer = getTokenPayerFromTransaction(decodedTransaction);
|
|
506
|
+
const rpc = getRpcClient(paymentRequirements.network, config2?.svmConfig?.rpcUrl);
|
|
507
|
+
const rpcSubscriptions = getRpcSubscriptions(
|
|
508
|
+
paymentRequirements.network,
|
|
509
|
+
config2?.svmConfig?.rpcUrl
|
|
510
|
+
);
|
|
511
|
+
try {
|
|
512
|
+
const { success, errorReason, signature } = await sendAndConfirmSignedTransaction(
|
|
513
|
+
signedTransaction,
|
|
514
|
+
rpc,
|
|
515
|
+
rpcSubscriptions
|
|
516
|
+
);
|
|
517
|
+
return {
|
|
518
|
+
success,
|
|
519
|
+
errorReason,
|
|
520
|
+
payer,
|
|
521
|
+
transaction: signature,
|
|
522
|
+
network: payload.network
|
|
523
|
+
};
|
|
524
|
+
} catch (error) {
|
|
525
|
+
console.error("Unexpected error during transaction settlement:", error);
|
|
526
|
+
return {
|
|
527
|
+
success: false,
|
|
528
|
+
errorReason: "unexpected_settle_error",
|
|
529
|
+
network: payload.network,
|
|
530
|
+
transaction: getSignatureFromTransaction(signedTransaction),
|
|
531
|
+
payer
|
|
532
|
+
};
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
async function sendSignedTransaction(signedTransaction, rpc, sendTxConfig = {
|
|
536
|
+
skipPreflight: true,
|
|
537
|
+
encoding: "base64"
|
|
538
|
+
}) {
|
|
539
|
+
const base64EncodedTransaction = getBase64EncodedWireTransaction(signedTransaction);
|
|
540
|
+
return await rpc.sendTransaction(base64EncodedTransaction, sendTxConfig).send();
|
|
541
|
+
}
|
|
542
|
+
async function confirmSignedTransaction(signedTransaction, rpc, rpcSubscriptions) {
|
|
543
|
+
const signature = getSignatureFromTransaction(signedTransaction);
|
|
544
|
+
const abortController = new AbortController();
|
|
545
|
+
const timeout = setTimeout(() => {
|
|
546
|
+
abortController.abort("Transaction confirmation timed out after 60 seconds");
|
|
547
|
+
}, 6e4);
|
|
548
|
+
try {
|
|
549
|
+
const compiledTransactionMessage = getCompiledTransactionMessageDecoder2().decode(
|
|
550
|
+
signedTransaction.messageBytes
|
|
551
|
+
);
|
|
552
|
+
const decompiledTransactionMessage = await decompileTransactionMessageFetchingLookupTables(
|
|
553
|
+
compiledTransactionMessage,
|
|
554
|
+
rpc
|
|
555
|
+
);
|
|
556
|
+
assertIsTransactionMessageWithBlockhashLifetime(decompiledTransactionMessage);
|
|
557
|
+
const signedTransactionWithBlockhashLifetime = {
|
|
558
|
+
...signedTransaction,
|
|
559
|
+
lifetimeConstraint: decompiledTransactionMessage.lifetimeConstraint
|
|
560
|
+
};
|
|
561
|
+
const commitment = "confirmed";
|
|
562
|
+
const getRecentSignatureConfirmationPromise = createRecentSignatureConfirmationPromiseFactory({
|
|
563
|
+
rpc,
|
|
564
|
+
rpcSubscriptions
|
|
565
|
+
});
|
|
566
|
+
const getBlockHeightExceedencePromise = createBlockHeightExceedencePromiseFactory({
|
|
567
|
+
rpc,
|
|
568
|
+
rpcSubscriptions
|
|
569
|
+
});
|
|
570
|
+
const config2 = {
|
|
571
|
+
abortSignal: abortController.signal,
|
|
572
|
+
commitment,
|
|
573
|
+
getBlockHeightExceedencePromise,
|
|
574
|
+
getRecentSignatureConfirmationPromise
|
|
575
|
+
};
|
|
576
|
+
await waitForRecentTransactionConfirmation({
|
|
577
|
+
...config2,
|
|
578
|
+
transaction: signedTransactionWithBlockhashLifetime
|
|
579
|
+
});
|
|
580
|
+
return {
|
|
581
|
+
success: true,
|
|
582
|
+
signature
|
|
583
|
+
};
|
|
584
|
+
} catch (error) {
|
|
585
|
+
console.error(error);
|
|
586
|
+
if (isSolanaError(error, SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED)) {
|
|
587
|
+
return {
|
|
588
|
+
success: false,
|
|
589
|
+
errorReason: "settle_exact_svm_block_height_exceeded",
|
|
590
|
+
signature
|
|
591
|
+
};
|
|
592
|
+
} else if (error instanceof DOMException && error.name === "AbortError") {
|
|
593
|
+
return {
|
|
594
|
+
success: false,
|
|
595
|
+
errorReason: "settle_exact_svm_transaction_confirmation_timed_out",
|
|
596
|
+
signature
|
|
597
|
+
};
|
|
598
|
+
} else {
|
|
599
|
+
throw error;
|
|
600
|
+
}
|
|
601
|
+
} finally {
|
|
602
|
+
clearTimeout(timeout);
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
async function sendAndConfirmSignedTransaction(signedTransaction, rpc, rpcSubscriptions) {
|
|
606
|
+
await sendSignedTransaction(signedTransaction, rpc);
|
|
607
|
+
return await confirmSignedTransaction(signedTransaction, rpc, rpcSubscriptions);
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
// src/schemes/exact/index.ts
|
|
611
|
+
var SCHEME = "exact";
|
|
612
|
+
|
|
613
|
+
export {
|
|
614
|
+
verify2 as verify,
|
|
615
|
+
settle2 as settle,
|
|
616
|
+
exact_exports,
|
|
617
|
+
verify as verify2,
|
|
618
|
+
settle as settle2
|
|
619
|
+
};
|
|
620
|
+
//# sourceMappingURL=chunk-MWDK4RSB.mjs.map
|