UNPKG

@web3auth/no-modal

Version:
176 lines (172 loc) 7.02 kB
'use strict'; var kit = require('@solana/kit'); var metadataHelpers = require('@toruslabs/metadata-helpers'); var wsEmbed = require('@web3auth/ws-embed'); var evm = require('@x402/evm'); var fetch$1 = require('@x402/fetch'); var svm = require('@x402/svm'); var viem = require('viem'); require('../base/wallet/index.js'); var interfaces = require('./interfaces.js'); var solana = require('../base/wallet/solana.js'); const EVM_CAIP2_WILDCARD = "eip155:*"; const SOLANA_CAIP2_WILDCARD = "solana:*"; /** * For 402 responses that carry v2 payment requirements in the JSON body instead * of the PAYMENT-REQUIRED header, reads the body, promotes the data into the * header, and reconstructs the response so downstream code can consume it normally. * * Returns the original response unchanged when the body is not JSON, is malformed, * or does not carry an x402Version \>= 2 payload. */ async function normalizePaymentRequiredResponse(response) { var _response$headers$get; const contentType = (_response$headers$get = response.headers.get("Content-Type")) !== null && _response$headers$get !== void 0 ? _response$headers$get : ""; let body; if (contentType.includes("application/json")) { body = await response.json(); } else { const data = await response.text(); body = JSON.parse(data); } try { if (body.x402Version && body.x402Version >= 2) { const newHeaders = new Headers(response.headers); const jsonData = JSON.stringify(body); newHeaders.set(interfaces.PAYMENT_REQUIRED_HEADER, metadataHelpers.encodeBase64Url(jsonData)); return new Response(jsonData, { status: response.status, statusText: response.statusText, headers: newHeaders }); } } catch { // Malformed JSON - fall through and return response with the already-consumed body } return new Response(JSON.stringify(body), { status: response.status, statusText: response.statusText, headers: response.headers }); } async function getEvmAddress(provider) { var _accounts$; const accounts = await provider.request({ method: wsEmbed.EVM_METHOD_TYPES.GET_ACCOUNTS }); return (_accounts$ = accounts === null || accounts === void 0 ? void 0 : accounts[0]) !== null && _accounts$ !== void 0 ? _accounts$ : null; } function createProviderBackedEvmSigner(provider, address) { const walletClient = viem.createWalletClient({ account: address, transport: viem.custom(provider) }); return walletClient; } /** * Wraps a fetch function so that 402 responses whose v2 payment requirements * arrive in the response body (instead of the PAYMENT-REQUIRED header) are * normalised: the body JSON is base64-encoded and promoted into the * PAYMENT-REQUIRED header so that the \@x402/fetch client library can process it. * * The \@x402/fetch library's body fallback only accepts x402Version === 1; * this shim bridges the gap for servers that send v2 data in the body. * * @param baseFetch - The underlying fetch implementation to wrap * @returns A fetch-compatible function with the shim applied */ function withX402BodyShim(baseFetch) { return async (input, init) => { const response = await baseFetch(input, init); if (response.status === 402 && !response.headers.get(interfaces.PAYMENT_REQUIRED_HEADER)) { return normalizePaymentRequiredResponse(response); } return response; }; } /** * Builds a `@x402/svm`-compatible `TransactionPartialSigner` from a web3auth * Solana provider. * * The web3auth `signTransaction` call returns the signer's Ed25519 signature * encoded in base58 (64 bytes). We decode it back to bytes and slot it into * the signature dictionary that `@solana/kit`'s partial-signing helpers expect. */ function createSvmSigner(wallet, walletAddress) { const base58Encoder = kit.getBase58Encoder(); const signerAddress = kit.address(walletAddress); const clientSvmSigner = svm.toClientSvmSigner({ address: signerAddress, signTransactions: async transactions => { const signatureDictionaries = await Promise.all(transactions.map(async tx => { const signatureBase58 = await solana.walletSignTransaction(wallet, tx); return { [signerAddress]: base58Encoder.encode(signatureBase58) }; })); return signatureDictionaries; } }); return clientSvmSigner; } /** * Creates a payment-aware fetch function for a connected Solana wallet. * Registers the exact SVM payment scheme and applies the body-shim so that * servers returning v2 payment requirements in the response body are handled * transparently. * * @param wallet - Connected Solana wallet (must have an account) * @param walletAddress - The wallet's public key as a base58 address string * @param rpcUrl - Optional custom Solana RPC URL (defaults to public cluster endpoints) * @returns A fetch-compatible function that handles x402 payment flows */ function createSolanaX402Fetch(wallet, walletAddress, rpcUrl) { if (!walletAddress) throw new Error("Wallet address is unavailable."); const svmSigner = createSvmSigner(wallet, walletAddress); const client = new fetch$1.x402Client().register(SOLANA_CAIP2_WILDCARD, new svm.ExactSvmScheme(svmSigner, rpcUrl ? { rpcUrl } : undefined)); return fetch$1.wrapFetchWithPayment(withX402BodyShim(fetch), client); } /** * Creates a payment-aware fetch function for an EVM typed-data signer. * Registers the exact EVM payment scheme and applies the body-shim so that * servers returning v2 payment requirements in the response body are handled * transparently. * * @param signer - Minimal signer with an address and EIP-712 signTypedData implementation * @returns A fetch-compatible function that handles x402 payment flows */ function createEvmX402Fetch(walletClient) { var _walletClient$account; const address = (_walletClient$account = walletClient.account) === null || _walletClient$account === void 0 ? void 0 : _walletClient$account.address; if (!address) throw new Error("Wallet account is unavailable."); const evmSigner = evm.toClientEvmSigner({ address, signTypedData: async params => { const { domain, types, primaryType, message } = params; return walletClient.signTypedData({ account: address, domain, types, primaryType, message }); } }); const client = new fetch$1.x402Client().register(EVM_CAIP2_WILDCARD, new evm.ExactEvmScheme(evmSigner)); return fetch$1.wrapFetchWithPayment(withX402BodyShim(fetch), client); } exports.PAYMENT_REQUIRED_HEADER = interfaces.PAYMENT_REQUIRED_HEADER; exports.EVM_CAIP2_WILDCARD = EVM_CAIP2_WILDCARD; exports.SOLANA_CAIP2_WILDCARD = SOLANA_CAIP2_WILDCARD; exports.createEvmX402Fetch = createEvmX402Fetch; exports.createProviderBackedEvmSigner = createProviderBackedEvmSigner; exports.createSolanaX402Fetch = createSolanaX402Fetch; exports.getEvmAddress = getEvmAddress; exports.withX402BodyShim = withX402BodyShim;