@web3auth/no-modal
Version:
Multi chain wallet aggregator for web3Auth
176 lines (172 loc) • 7.02 kB
JavaScript
;
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;