@zauthx402/sdk 0.1.6 → 0.1.7
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/dist/{index-CylVkunV.d.mts → index-C2FGNEe1.d.mts} +7 -2
- package/dist/{index-CylVkunV.d.ts → index-C2FGNEe1.d.ts} +7 -2
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +158 -21
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +158 -21
- package/dist/index.mjs.map +1 -1
- package/dist/middleware/index.d.mts +1 -1
- package/dist/middleware/index.d.ts +1 -1
- package/dist/middleware/index.js +158 -21
- package/dist/middleware/index.js.map +1 -1
- package/dist/middleware/index.mjs +158 -21
- package/dist/middleware/index.mjs.map +1 -1
- package/package.json +7 -2
|
@@ -542,10 +542,14 @@ interface RefundConfig {
|
|
|
542
542
|
*/
|
|
543
543
|
signer?: RefundSigner;
|
|
544
544
|
/**
|
|
545
|
-
* Private key for refund transactions (
|
|
545
|
+
* Private key for EVM refund transactions (hex format)
|
|
546
546
|
* @deprecated Use signer instead
|
|
547
547
|
*/
|
|
548
548
|
privateKey?: string;
|
|
549
|
+
/**
|
|
550
|
+
* Private key for Solana refund transactions (base58 format)
|
|
551
|
+
*/
|
|
552
|
+
solanaPrivateKey?: string;
|
|
549
553
|
/**
|
|
550
554
|
* Default network for refunds (can be overridden per-endpoint)
|
|
551
555
|
* @default 'base'
|
|
@@ -743,6 +747,7 @@ interface ResolvedRefundConfig {
|
|
|
743
747
|
enabled: boolean;
|
|
744
748
|
signer?: RefundSigner;
|
|
745
749
|
privateKey?: string;
|
|
750
|
+
solanaPrivateKey?: string;
|
|
746
751
|
network: X402Network;
|
|
747
752
|
triggers: Required<RefundTriggers>;
|
|
748
753
|
maxRefundUsd: number;
|
|
@@ -1055,7 +1060,7 @@ declare class RefundExecutor {
|
|
|
1055
1060
|
*/
|
|
1056
1061
|
private executeEvmRefund;
|
|
1057
1062
|
/**
|
|
1058
|
-
* Execute Solana refund
|
|
1063
|
+
* Execute Solana refund using @solana/kit v2 libraries
|
|
1059
1064
|
*/
|
|
1060
1065
|
private executeSolanaRefund;
|
|
1061
1066
|
/**
|
|
@@ -542,10 +542,14 @@ interface RefundConfig {
|
|
|
542
542
|
*/
|
|
543
543
|
signer?: RefundSigner;
|
|
544
544
|
/**
|
|
545
|
-
* Private key for refund transactions (
|
|
545
|
+
* Private key for EVM refund transactions (hex format)
|
|
546
546
|
* @deprecated Use signer instead
|
|
547
547
|
*/
|
|
548
548
|
privateKey?: string;
|
|
549
|
+
/**
|
|
550
|
+
* Private key for Solana refund transactions (base58 format)
|
|
551
|
+
*/
|
|
552
|
+
solanaPrivateKey?: string;
|
|
549
553
|
/**
|
|
550
554
|
* Default network for refunds (can be overridden per-endpoint)
|
|
551
555
|
* @default 'base'
|
|
@@ -743,6 +747,7 @@ interface ResolvedRefundConfig {
|
|
|
743
747
|
enabled: boolean;
|
|
744
748
|
signer?: RefundSigner;
|
|
745
749
|
privateKey?: string;
|
|
750
|
+
solanaPrivateKey?: string;
|
|
746
751
|
network: X402Network;
|
|
747
752
|
triggers: Required<RefundTriggers>;
|
|
748
753
|
maxRefundUsd: number;
|
|
@@ -1055,7 +1060,7 @@ declare class RefundExecutor {
|
|
|
1055
1060
|
*/
|
|
1056
1061
|
private executeEvmRefund;
|
|
1057
1062
|
/**
|
|
1058
|
-
* Execute Solana refund
|
|
1063
|
+
* Execute Solana refund using @solana/kit v2 libraries
|
|
1059
1064
|
*/
|
|
1060
1065
|
private executeSolanaRefund;
|
|
1061
1066
|
/**
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { V as ValidationConfig, a as ValidationResult } from './index-
|
|
2
|
-
export { Q as BatchingConfig, K as ConfirmRefundRequest, L as ConfirmRefundResponse, a6 as DEFAULT_CONFIG, W as EndpointRefundConfig, E as EndpointStatus, B as ErrorEvent, F as EventBatch, G as EventSubmitResponse, _ as ExecutedRefund, H as HealthCheckEvent, P as PaymentEvent, I as PendingRefund, J as PendingRefundsResponse, a2 as ProviderMiddlewareConfig, a0 as RefundCondition, S as RefundConfig, $ as RefundError, y as RefundEvent, R as RefundHandler, Y as RefundPollingConfig, A as RefundReason, f as RefundRequest, g as RefundResult, T as RefundSigner, U as RefundTriggers, M as RejectRefundRequest, N as RejectRefundResponse, w as RequestEvent, a5 as ResolvedConfig, a4 as ResolvedRefundConfig, a3 as ResolvedValidationConfig, x as ResponseEvent, a1 as TelemetryConfig, C as ValidationCheck, X as X402Network, p as X402PaymentInfo, n as X402PaymentPayload, j as X402PaymentRequirement, o as X402PaymentResponse, m as X402Response, k as X402ResponseV1, l as X402ResponseV2, h as X402Scheme, i as X402Version, Z as ZauthClient, O as ZauthConfig, D as ZauthEvent, v as ZauthEventBase, d as ZauthMiddlewareOptions, c as createClient, e as createRefundHandler, b as createZauthMiddleware, t as decodePaymentResponse, u as encodePaymentPayload, r as getPaymentRequirements, s as getPriceUsdc, q as parseX402Response, a7 as resolveConfig, z as zauthProvider } from './index-
|
|
1
|
+
import { V as ValidationConfig, a as ValidationResult } from './index-C2FGNEe1.mjs';
|
|
2
|
+
export { Q as BatchingConfig, K as ConfirmRefundRequest, L as ConfirmRefundResponse, a6 as DEFAULT_CONFIG, W as EndpointRefundConfig, E as EndpointStatus, B as ErrorEvent, F as EventBatch, G as EventSubmitResponse, _ as ExecutedRefund, H as HealthCheckEvent, P as PaymentEvent, I as PendingRefund, J as PendingRefundsResponse, a2 as ProviderMiddlewareConfig, a0 as RefundCondition, S as RefundConfig, $ as RefundError, y as RefundEvent, R as RefundHandler, Y as RefundPollingConfig, A as RefundReason, f as RefundRequest, g as RefundResult, T as RefundSigner, U as RefundTriggers, M as RejectRefundRequest, N as RejectRefundResponse, w as RequestEvent, a5 as ResolvedConfig, a4 as ResolvedRefundConfig, a3 as ResolvedValidationConfig, x as ResponseEvent, a1 as TelemetryConfig, C as ValidationCheck, X as X402Network, p as X402PaymentInfo, n as X402PaymentPayload, j as X402PaymentRequirement, o as X402PaymentResponse, m as X402Response, k as X402ResponseV1, l as X402ResponseV2, h as X402Scheme, i as X402Version, Z as ZauthClient, O as ZauthConfig, D as ZauthEvent, v as ZauthEventBase, d as ZauthMiddlewareOptions, c as createClient, e as createRefundHandler, b as createZauthMiddleware, t as decodePaymentResponse, u as encodePaymentPayload, r as getPaymentRequirements, s as getPriceUsdc, q as parseX402Response, a7 as resolveConfig, z as zauthProvider } from './index-C2FGNEe1.mjs';
|
|
3
3
|
import 'express';
|
|
4
4
|
|
|
5
5
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { V as ValidationConfig, a as ValidationResult } from './index-
|
|
2
|
-
export { Q as BatchingConfig, K as ConfirmRefundRequest, L as ConfirmRefundResponse, a6 as DEFAULT_CONFIG, W as EndpointRefundConfig, E as EndpointStatus, B as ErrorEvent, F as EventBatch, G as EventSubmitResponse, _ as ExecutedRefund, H as HealthCheckEvent, P as PaymentEvent, I as PendingRefund, J as PendingRefundsResponse, a2 as ProviderMiddlewareConfig, a0 as RefundCondition, S as RefundConfig, $ as RefundError, y as RefundEvent, R as RefundHandler, Y as RefundPollingConfig, A as RefundReason, f as RefundRequest, g as RefundResult, T as RefundSigner, U as RefundTriggers, M as RejectRefundRequest, N as RejectRefundResponse, w as RequestEvent, a5 as ResolvedConfig, a4 as ResolvedRefundConfig, a3 as ResolvedValidationConfig, x as ResponseEvent, a1 as TelemetryConfig, C as ValidationCheck, X as X402Network, p as X402PaymentInfo, n as X402PaymentPayload, j as X402PaymentRequirement, o as X402PaymentResponse, m as X402Response, k as X402ResponseV1, l as X402ResponseV2, h as X402Scheme, i as X402Version, Z as ZauthClient, O as ZauthConfig, D as ZauthEvent, v as ZauthEventBase, d as ZauthMiddlewareOptions, c as createClient, e as createRefundHandler, b as createZauthMiddleware, t as decodePaymentResponse, u as encodePaymentPayload, r as getPaymentRequirements, s as getPriceUsdc, q as parseX402Response, a7 as resolveConfig, z as zauthProvider } from './index-
|
|
1
|
+
import { V as ValidationConfig, a as ValidationResult } from './index-C2FGNEe1.js';
|
|
2
|
+
export { Q as BatchingConfig, K as ConfirmRefundRequest, L as ConfirmRefundResponse, a6 as DEFAULT_CONFIG, W as EndpointRefundConfig, E as EndpointStatus, B as ErrorEvent, F as EventBatch, G as EventSubmitResponse, _ as ExecutedRefund, H as HealthCheckEvent, P as PaymentEvent, I as PendingRefund, J as PendingRefundsResponse, a2 as ProviderMiddlewareConfig, a0 as RefundCondition, S as RefundConfig, $ as RefundError, y as RefundEvent, R as RefundHandler, Y as RefundPollingConfig, A as RefundReason, f as RefundRequest, g as RefundResult, T as RefundSigner, U as RefundTriggers, M as RejectRefundRequest, N as RejectRefundResponse, w as RequestEvent, a5 as ResolvedConfig, a4 as ResolvedRefundConfig, a3 as ResolvedValidationConfig, x as ResponseEvent, a1 as TelemetryConfig, C as ValidationCheck, X as X402Network, p as X402PaymentInfo, n as X402PaymentPayload, j as X402PaymentRequirement, o as X402PaymentResponse, m as X402Response, k as X402ResponseV1, l as X402ResponseV2, h as X402Scheme, i as X402Version, Z as ZauthClient, O as ZauthConfig, D as ZauthEvent, v as ZauthEventBase, d as ZauthMiddlewareOptions, c as createClient, e as createRefundHandler, b as createZauthMiddleware, t as decodePaymentResponse, u as encodePaymentPayload, r as getPaymentRequirements, s as getPriceUsdc, q as parseX402Response, a7 as resolveConfig, z as zauthProvider } from './index-C2FGNEe1.js';
|
|
3
3
|
import 'express';
|
|
4
4
|
|
|
5
5
|
/**
|
package/dist/index.js
CHANGED
|
@@ -60,9 +60,9 @@ var require_constants = __commonJS({
|
|
|
60
60
|
}
|
|
61
61
|
});
|
|
62
62
|
|
|
63
|
-
//
|
|
63
|
+
// node_modules/node-gyp-build/node-gyp-build.js
|
|
64
64
|
var require_node_gyp_build = __commonJS({
|
|
65
|
-
"
|
|
65
|
+
"node_modules/node-gyp-build/node-gyp-build.js"(exports$1, module) {
|
|
66
66
|
var fs = __require("fs");
|
|
67
67
|
var path = __require("path");
|
|
68
68
|
var os = __require("os");
|
|
@@ -229,9 +229,9 @@ var require_node_gyp_build = __commonJS({
|
|
|
229
229
|
}
|
|
230
230
|
});
|
|
231
231
|
|
|
232
|
-
//
|
|
232
|
+
// node_modules/node-gyp-build/index.js
|
|
233
233
|
var require_node_gyp_build2 = __commonJS({
|
|
234
|
-
"
|
|
234
|
+
"node_modules/node-gyp-build/index.js"(exports$1, module) {
|
|
235
235
|
var runtimeRequire = typeof __webpack_require__ === "function" ? __non_webpack_require__ : __require;
|
|
236
236
|
if (typeof runtimeRequire.addon === "function") {
|
|
237
237
|
module.exports = runtimeRequire.addon.bind(runtimeRequire);
|
|
@@ -241,9 +241,9 @@ var require_node_gyp_build2 = __commonJS({
|
|
|
241
241
|
}
|
|
242
242
|
});
|
|
243
243
|
|
|
244
|
-
//
|
|
244
|
+
// node_modules/bufferutil/fallback.js
|
|
245
245
|
var require_fallback = __commonJS({
|
|
246
|
-
"
|
|
246
|
+
"node_modules/bufferutil/fallback.js"(exports$1, module) {
|
|
247
247
|
var mask = (source, mask2, output, offset, length) => {
|
|
248
248
|
for (var i = 0; i < length; i++) {
|
|
249
249
|
output[offset + i] = source[i] ^ mask2[i & 3];
|
|
@@ -259,9 +259,9 @@ var require_fallback = __commonJS({
|
|
|
259
259
|
}
|
|
260
260
|
});
|
|
261
261
|
|
|
262
|
-
//
|
|
262
|
+
// node_modules/bufferutil/index.js
|
|
263
263
|
var require_bufferutil = __commonJS({
|
|
264
|
-
"
|
|
264
|
+
"node_modules/bufferutil/index.js"(exports$1, module) {
|
|
265
265
|
try {
|
|
266
266
|
module.exports = require_node_gyp_build2()(__dirname);
|
|
267
267
|
} catch (e) {
|
|
@@ -775,9 +775,9 @@ var require_permessage_deflate = __commonJS({
|
|
|
775
775
|
}
|
|
776
776
|
});
|
|
777
777
|
|
|
778
|
-
//
|
|
778
|
+
// node_modules/utf-8-validate/fallback.js
|
|
779
779
|
var require_fallback2 = __commonJS({
|
|
780
|
-
"
|
|
780
|
+
"node_modules/utf-8-validate/fallback.js"(exports$1, module) {
|
|
781
781
|
function isValidUTF8(buf) {
|
|
782
782
|
const len = buf.length;
|
|
783
783
|
let i = 0;
|
|
@@ -811,9 +811,9 @@ var require_fallback2 = __commonJS({
|
|
|
811
811
|
}
|
|
812
812
|
});
|
|
813
813
|
|
|
814
|
-
//
|
|
814
|
+
// node_modules/utf-8-validate/index.js
|
|
815
815
|
var require_utf_8_validate = __commonJS({
|
|
816
|
-
"
|
|
816
|
+
"node_modules/utf-8-validate/index.js"(exports$1, module) {
|
|
817
817
|
try {
|
|
818
818
|
module.exports = require_node_gyp_build2()(__dirname);
|
|
819
819
|
} catch (e) {
|
|
@@ -3933,6 +3933,7 @@ var DEFAULT_CONFIG = {
|
|
|
3933
3933
|
refund: {
|
|
3934
3934
|
enabled: false,
|
|
3935
3935
|
privateKey: process.env.ZAUTH_REFUND_PRIVATE_KEY,
|
|
3936
|
+
solanaPrivateKey: process.env.ZAUTH_SOLANA_PRIVATE_KEY,
|
|
3936
3937
|
network: "base",
|
|
3937
3938
|
triggers: {
|
|
3938
3939
|
serverError: true,
|
|
@@ -3963,6 +3964,7 @@ function resolveConfig(config) {
|
|
|
3963
3964
|
enabled: config.refund?.enabled ?? DEFAULT_CONFIG.refund.enabled,
|
|
3964
3965
|
signer: config.refund?.signer,
|
|
3965
3966
|
privateKey: config.refund?.privateKey ?? DEFAULT_CONFIG.refund.privateKey,
|
|
3967
|
+
solanaPrivateKey: config.refund?.solanaPrivateKey ?? DEFAULT_CONFIG.refund.solanaPrivateKey,
|
|
3966
3968
|
network: config.refund?.network ?? DEFAULT_CONFIG.refund.network,
|
|
3967
3969
|
triggers: {
|
|
3968
3970
|
...DEFAULT_CONFIG.refund.triggers,
|
|
@@ -4593,17 +4595,68 @@ function decodePaymentHeader(paymentHeader) {
|
|
|
4593
4595
|
decoded = paymentHeader;
|
|
4594
4596
|
}
|
|
4595
4597
|
const parsed = JSON.parse(decoded);
|
|
4596
|
-
|
|
4598
|
+
let payer = parsed.payload?.authorization?.from || // x402 V2 EVM
|
|
4597
4599
|
parsed.payer || parsed.from || parsed.payload?.from || parsed.x?.signature?.address || null;
|
|
4600
|
+
if (!payer && parsed.payload?.transaction) {
|
|
4601
|
+
payer = extractSolanaFeePayer(parsed.payload.transaction);
|
|
4602
|
+
}
|
|
4598
4603
|
const amount = parsed.payload?.authorization?.value || // x402 V2
|
|
4599
4604
|
parsed.amount || parsed.payload?.amount || null;
|
|
4600
|
-
|
|
4605
|
+
let network = parsed.payload?.authorization?.network || // x402 V2 EVM
|
|
4601
4606
|
parsed.network || parsed.payload?.network || null;
|
|
4607
|
+
if (!network && parsed.payload?.transaction && payer) {
|
|
4608
|
+
network = "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp";
|
|
4609
|
+
}
|
|
4602
4610
|
return { payer, amount, network };
|
|
4603
4611
|
} catch {
|
|
4604
4612
|
return null;
|
|
4605
4613
|
}
|
|
4606
4614
|
}
|
|
4615
|
+
function extractSolanaFeePayer(base64Transaction) {
|
|
4616
|
+
try {
|
|
4617
|
+
const txBytes = typeof Buffer !== "undefined" ? Buffer.from(base64Transaction, "base64") : Uint8Array.from(atob(base64Transaction), (c) => c.charCodeAt(0));
|
|
4618
|
+
let offset = 0;
|
|
4619
|
+
const numSignatures = txBytes[offset];
|
|
4620
|
+
offset += 1;
|
|
4621
|
+
offset += numSignatures * 64;
|
|
4622
|
+
const firstByte = txBytes[offset];
|
|
4623
|
+
if ((firstByte & 128) !== 0) {
|
|
4624
|
+
offset += 1;
|
|
4625
|
+
}
|
|
4626
|
+
offset += 3;
|
|
4627
|
+
const numAccounts = txBytes[offset];
|
|
4628
|
+
offset += 1;
|
|
4629
|
+
if (numAccounts > 0 && offset + 32 <= txBytes.length) {
|
|
4630
|
+
const feePayerBytes = txBytes.slice(offset, offset + 32);
|
|
4631
|
+
return base58Encode(feePayerBytes);
|
|
4632
|
+
}
|
|
4633
|
+
return null;
|
|
4634
|
+
} catch {
|
|
4635
|
+
return null;
|
|
4636
|
+
}
|
|
4637
|
+
}
|
|
4638
|
+
function base58Encode(bytes) {
|
|
4639
|
+
const ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
4640
|
+
const BASE = 58;
|
|
4641
|
+
let num = BigInt(0);
|
|
4642
|
+
for (const byte of bytes) {
|
|
4643
|
+
num = num * BigInt(256) + BigInt(byte);
|
|
4644
|
+
}
|
|
4645
|
+
let result = "";
|
|
4646
|
+
while (num > 0) {
|
|
4647
|
+
const remainder = Number(num % BigInt(BASE));
|
|
4648
|
+
num = num / BigInt(BASE);
|
|
4649
|
+
result = ALPHABET[remainder] + result;
|
|
4650
|
+
}
|
|
4651
|
+
for (const byte of bytes) {
|
|
4652
|
+
if (byte === 0) {
|
|
4653
|
+
result = "1" + result;
|
|
4654
|
+
} else {
|
|
4655
|
+
break;
|
|
4656
|
+
}
|
|
4657
|
+
}
|
|
4658
|
+
return result || "1";
|
|
4659
|
+
}
|
|
4607
4660
|
function detectX402Version(body) {
|
|
4608
4661
|
if (!body || typeof body !== "object") {
|
|
4609
4662
|
return null;
|
|
@@ -5345,14 +5398,98 @@ var RefundExecutor = class {
|
|
|
5345
5398
|
}
|
|
5346
5399
|
}
|
|
5347
5400
|
/**
|
|
5348
|
-
* Execute Solana refund
|
|
5401
|
+
* Execute Solana refund using @solana/kit v2 libraries
|
|
5349
5402
|
*/
|
|
5350
|
-
async executeSolanaRefund(
|
|
5351
|
-
|
|
5352
|
-
|
|
5353
|
-
|
|
5354
|
-
|
|
5355
|
-
|
|
5403
|
+
async executeSolanaRefund(refund, amountRaw) {
|
|
5404
|
+
try {
|
|
5405
|
+
const solanaPrivateKey = this.config.solanaPrivateKey;
|
|
5406
|
+
if (!solanaPrivateKey) {
|
|
5407
|
+
return {
|
|
5408
|
+
success: false,
|
|
5409
|
+
error: "No Solana private key configured (set ZAUTH_SOLANA_PRIVATE_KEY)",
|
|
5410
|
+
retryable: false
|
|
5411
|
+
};
|
|
5412
|
+
}
|
|
5413
|
+
const { createKeyPairSignerFromPrivateKeyBytes } = await import('@solana/signers');
|
|
5414
|
+
const {
|
|
5415
|
+
createSolanaRpc,
|
|
5416
|
+
address,
|
|
5417
|
+
pipe,
|
|
5418
|
+
createTransactionMessage,
|
|
5419
|
+
setTransactionMessageFeePayer,
|
|
5420
|
+
setTransactionMessageLifetimeUsingBlockhash,
|
|
5421
|
+
appendTransactionMessageInstructions,
|
|
5422
|
+
signTransactionMessageWithSigners,
|
|
5423
|
+
getBase64EncodedWireTransaction
|
|
5424
|
+
} = await import('@solana/kit');
|
|
5425
|
+
const {
|
|
5426
|
+
findAssociatedTokenPda,
|
|
5427
|
+
getTransferInstruction,
|
|
5428
|
+
TOKEN_PROGRAM_ADDRESS
|
|
5429
|
+
} = await import('@solana-program/token');
|
|
5430
|
+
const bs58 = await import('bs58');
|
|
5431
|
+
const USDC_MINT = address("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");
|
|
5432
|
+
const rpcUrl = process.env.SOLANA_RPC_URL || "https://api.mainnet-beta.solana.com";
|
|
5433
|
+
const rpc = createSolanaRpc(rpcUrl);
|
|
5434
|
+
let signer;
|
|
5435
|
+
try {
|
|
5436
|
+
const secretKey = bs58.default.decode(solanaPrivateKey);
|
|
5437
|
+
const privateKeyBytes = secretKey.slice(0, 32);
|
|
5438
|
+
signer = await createKeyPairSignerFromPrivateKeyBytes(privateKeyBytes);
|
|
5439
|
+
} catch {
|
|
5440
|
+
return {
|
|
5441
|
+
success: false,
|
|
5442
|
+
error: "Invalid Solana private key format (expected base58)",
|
|
5443
|
+
retryable: false
|
|
5444
|
+
};
|
|
5445
|
+
}
|
|
5446
|
+
const recipientAddress = address(refund.recipientAddress);
|
|
5447
|
+
const [senderAta] = await findAssociatedTokenPda({
|
|
5448
|
+
mint: USDC_MINT,
|
|
5449
|
+
owner: signer.address,
|
|
5450
|
+
tokenProgram: TOKEN_PROGRAM_ADDRESS
|
|
5451
|
+
});
|
|
5452
|
+
const [recipientAta] = await findAssociatedTokenPda({
|
|
5453
|
+
mint: USDC_MINT,
|
|
5454
|
+
owner: recipientAddress,
|
|
5455
|
+
tokenProgram: TOKEN_PROGRAM_ADDRESS
|
|
5456
|
+
});
|
|
5457
|
+
const transferIx = getTransferInstruction({
|
|
5458
|
+
source: senderAta,
|
|
5459
|
+
destination: recipientAta,
|
|
5460
|
+
authority: signer,
|
|
5461
|
+
amount: BigInt(amountRaw)
|
|
5462
|
+
});
|
|
5463
|
+
const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();
|
|
5464
|
+
const tx = pipe(
|
|
5465
|
+
createTransactionMessage({ version: 0 }),
|
|
5466
|
+
(tx2) => setTransactionMessageFeePayer(signer.address, tx2),
|
|
5467
|
+
(tx2) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx2),
|
|
5468
|
+
(tx2) => appendTransactionMessageInstructions([transferIx], tx2)
|
|
5469
|
+
);
|
|
5470
|
+
const signedTx = await signTransactionMessageWithSigners(tx);
|
|
5471
|
+
const base64Tx = getBase64EncodedWireTransaction(signedTx);
|
|
5472
|
+
const txSignature = await rpc.sendTransaction(base64Tx, { encoding: "base64" }).send();
|
|
5473
|
+
this.log("Solana refund sent", {
|
|
5474
|
+
txHash: txSignature,
|
|
5475
|
+
to: refund.recipientAddress,
|
|
5476
|
+
amount: amountRaw
|
|
5477
|
+
});
|
|
5478
|
+
return {
|
|
5479
|
+
success: true,
|
|
5480
|
+
txHash: txSignature,
|
|
5481
|
+
amountRaw,
|
|
5482
|
+
gasCostCents: 0
|
|
5483
|
+
// Solana fees are negligible
|
|
5484
|
+
};
|
|
5485
|
+
} catch (error) {
|
|
5486
|
+
this.log("Solana refund failed", { error: error.message });
|
|
5487
|
+
return {
|
|
5488
|
+
success: false,
|
|
5489
|
+
error: error.message,
|
|
5490
|
+
retryable: true
|
|
5491
|
+
};
|
|
5492
|
+
}
|
|
5356
5493
|
}
|
|
5357
5494
|
/**
|
|
5358
5495
|
* Get endpoint-specific config by matching URL patterns
|