facinet 2.4.2 → 2.4.4
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/browser.js +37 -4
- package/dist/browser.js.map +2 -2
- package/dist/commands/pay.d.ts.map +1 -1
- package/dist/commands/pay.js +37 -5
- package/dist/commands/pay.js.map +1 -1
- package/dist/index.js +36 -9
- package/dist/index.js.map +2 -2
- package/dist/sdk/Facinet.d.ts.map +1 -1
- package/dist/sdk/Facinet.js +38 -5
- package/dist/sdk/Facinet.js.map +1 -1
- package/dist/sdk.js +37 -4
- package/dist/sdk.js.map +2 -2
- package/dist/sdk.mjs +37 -4
- package/dist/sdk.mjs.map +2 -2
- package/package.json +1 -1
package/dist/sdk.js
CHANGED
|
@@ -184,6 +184,16 @@ var Facinet = class _Facinet {
|
|
|
184
184
|
payerAddress = payerAddress.toLowerCase();
|
|
185
185
|
const recipientAddress = params.recipient.toLowerCase();
|
|
186
186
|
const facilitator = await this.selectRandomFacilitator();
|
|
187
|
+
if (facilitator.network && facilitator.network !== this.config.network) {
|
|
188
|
+
throw new Error(
|
|
189
|
+
`Facilitator ${facilitator.id} is registered for network ${facilitator.network}, but payment is for ${this.config.network}. Please ensure facilitators are registered for the correct network.`
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
if (facilitator.chainId !== void 0 && facilitator.chainId !== this.chain.chainId) {
|
|
193
|
+
throw new Error(
|
|
194
|
+
`Facilitator ${facilitator.id} is registered for chain ID ${facilitator.chainId}, but payment is for chain ID ${this.chain.chainId}. Please ensure facilitators are registered for the correct chain.`
|
|
195
|
+
);
|
|
196
|
+
}
|
|
187
197
|
const amount = BigInt(parseFloat(params.amount) * 1e6);
|
|
188
198
|
const validAfter = Math.floor(Date.now() / 1e3) - 60;
|
|
189
199
|
const validBefore = validAfter + 3600;
|
|
@@ -258,15 +268,38 @@ var Facinet = class _Facinet {
|
|
|
258
268
|
validAfter: validAfter.toString(),
|
|
259
269
|
validBefore: validBefore.toString(),
|
|
260
270
|
nonce
|
|
271
|
+
},
|
|
272
|
+
// Include domain info so backend can verify signature
|
|
273
|
+
domain: {
|
|
274
|
+
name: this.chain.erc3009DomainName,
|
|
275
|
+
version: this.chain.erc3009DomainVersion,
|
|
276
|
+
chainId: this.chain.chainId,
|
|
277
|
+
verifyingContract: this.chain.usdcAddress
|
|
261
278
|
}
|
|
262
279
|
};
|
|
263
280
|
try {
|
|
281
|
+
const payload = {
|
|
282
|
+
facilitatorId: facilitator.id,
|
|
283
|
+
paymentPayload,
|
|
284
|
+
network: this.config.network,
|
|
285
|
+
chainId: this.chain.chainId,
|
|
286
|
+
usdcAddress: this.chain.usdcAddress,
|
|
287
|
+
// Explicitly include domain info at top level for backend
|
|
288
|
+
domainName: this.chain.erc3009DomainName,
|
|
289
|
+
domainVersion: this.chain.erc3009DomainVersion
|
|
290
|
+
};
|
|
291
|
+
if (process.env.NODE_ENV === "development" || process.env.DEBUG) {
|
|
292
|
+
console.log("[Facinet SDK] Payment payload:", {
|
|
293
|
+
network: payload.network,
|
|
294
|
+
chainId: payload.chainId,
|
|
295
|
+
usdcAddress: payload.usdcAddress,
|
|
296
|
+
domainName: payload.domainName,
|
|
297
|
+
facilitatorId: payload.facilitatorId
|
|
298
|
+
});
|
|
299
|
+
}
|
|
264
300
|
const response = await import_axios.default.post(
|
|
265
301
|
`${this.config.apiUrl}/api/x402/settle-custom`,
|
|
266
|
-
|
|
267
|
-
facilitatorId: facilitator.id,
|
|
268
|
-
paymentPayload
|
|
269
|
-
}
|
|
302
|
+
payload
|
|
270
303
|
);
|
|
271
304
|
if (!response.data.success) {
|
|
272
305
|
throw new Error(
|
package/dist/sdk.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/sdk.ts", "../src/sdk/Facinet.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Facinet SDK - Main Export\n *\n * Use this when installing as a library:\n * npm install facinet\n *\n * @example\n * ```typescript\n * import { Facinet } from 'facinet';\n *\n * const facinet = new Facinet({ network: 'base-sepolia' });\n * await facinet.pay({\n * amount: '1',\n * recipient: '0xYourAddress'\n * });\n * ```\n */\n\nexport { Facinet } from './sdk/Facinet';\nexport type {\n FacinetConfig,\n PaymentParams,\n PaymentResult,\n Facilitator,\n ChainConfig,\n} from './sdk/types';\nexport { Facinet as default } from './sdk/Facinet';\n", "/**\n * Facinet SDK - Main Class\n *\n * JavaScript/TypeScript SDK for integrating x402 payments\n * Supports multichain: Avalanche Fuji, Ethereum Sepolia, Base Sepolia, Polygon Amoy\n */\n\nimport axios from 'axios';\nimport { Wallet, JsonRpcProvider } from 'ethers';\nimport type { FacinetConfig, PaymentParams, PaymentResult, Facilitator, ChainConfig } from './types';\n\n// All 4 supported chains\nconst CHAINS: Record<string, ChainConfig> = {\n 'avalanche-fuji': {\n name: 'avalanche-fuji',\n displayName: 'Avalanche Fuji',\n chainId: 43113,\n rpcUrl: 'https://api.avax-test.network/ext/bc/C/rpc',\n usdcAddress: '0x5425890298aed601595a70AB815c96711a31Bc65',\n usdcDecimals: 6,\n gasToken: 'AVAX',\n blockExplorer: 'https://testnet.snowtrace.io',\n erc3009DomainName: 'USD Coin',\n erc3009DomainVersion: '2',\n },\n 'ethereum-sepolia': {\n name: 'ethereum-sepolia',\n displayName: 'Ethereum Sepolia',\n chainId: 11155111,\n rpcUrl: 'https://ethereum-sepolia-rpc.publicnode.com',\n usdcAddress: '0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238',\n usdcDecimals: 6,\n gasToken: 'ETH',\n blockExplorer: 'https://sepolia.etherscan.io',\n erc3009DomainName: 'USDC',\n erc3009DomainVersion: '2',\n },\n 'base-sepolia': {\n name: 'base-sepolia',\n displayName: 'Base Sepolia',\n chainId: 84532,\n rpcUrl: 'https://sepolia.base.org',\n usdcAddress: '0x036CbD53842c5426634e7929541eC2318f3dCF7e',\n usdcDecimals: 6,\n gasToken: 'ETH',\n blockExplorer: 'https://sepolia.basescan.org',\n erc3009DomainName: 'USDC',\n erc3009DomainVersion: '2',\n },\n 'polygon-amoy': {\n name: 'polygon-amoy',\n displayName: 'Polygon Amoy',\n chainId: 80002,\n rpcUrl: 'https://rpc-amoy.polygon.technology',\n usdcAddress: '0x41E94Eb019C0762f9Bfcf9Fb1E58725BfB0e7582',\n usdcDecimals: 6,\n gasToken: 'MATIC',\n blockExplorer: 'https://amoy.polygonscan.com',\n erc3009DomainName: 'USDC',\n erc3009DomainVersion: '2',\n },\n};\n\n// Legacy aliases for backwards compatibility\nconst NETWORK_ALIASES: Record<string, string> = {\n 'avalanche': 'avalanche-fuji',\n 'ethereum': 'ethereum-sepolia',\n 'polygon': 'polygon-amoy',\n 'base': 'base-sepolia',\n};\n\n// Unified API URL for all networks\nconst DEFAULT_API_URL = 'https://facinet.vercel.app';\n\n/**\n * Resolve network name (handles legacy aliases)\n */\nfunction resolveNetwork(network: string): string {\n return NETWORK_ALIASES[network] || network;\n}\n\n/**\n * Get API URL for a network\n */\nfunction getApiUrlForNetwork(network: string, customApiUrl?: string): string {\n if (customApiUrl) {\n return customApiUrl.replace(/\\/$/, '');\n }\n return DEFAULT_API_URL;\n}\n\nexport class Facinet {\n private config: Required<Pick<FacinetConfig, 'apiUrl' | 'privateKey' | 'network' | 'rpcUrl'>>;\n private chain: ChainConfig;\n private wallet?: InstanceType<typeof Wallet>;\n\n constructor(config: FacinetConfig = {}) {\n const resolvedNetwork = resolveNetwork(config.network || 'avalanche-fuji');\n const apiUrl = getApiUrlForNetwork(resolvedNetwork, config.apiUrl);\n\n this.config = {\n apiUrl,\n privateKey: config.privateKey || '',\n network: resolvedNetwork as any,\n rpcUrl: config.rpcUrl || '',\n };\n\n this.chain = CHAINS[resolvedNetwork];\n if (!this.chain) {\n throw new Error(\n `Unsupported network: ${config.network}. Supported networks: ${Object.keys(CHAINS).join(', ')}`\n );\n }\n\n if (this.config.privateKey) {\n const provider = new JsonRpcProvider(\n this.config.rpcUrl || this.chain.rpcUrl\n );\n this.wallet = new Wallet(this.config.privateKey, provider);\n }\n }\n\n /**\n * Get the current chain configuration\n */\n getChain(): ChainConfig {\n return { ...this.chain };\n }\n\n /**\n * Get all supported chains\n */\n static getSupportedChains(): ChainConfig[] {\n return Object.values(CHAINS);\n }\n\n /**\n * Get supported network names\n */\n static getSupportedNetworks(): string[] {\n return Object.keys(CHAINS);\n }\n\n /**\n * Make a payment via x402 facilitator network\n *\n * @example\n * ```typescript\n * const facinet = new Facinet({ network: 'base-sepolia' });\n * const result = await facinet.pay({\n * amount: '1',\n * recipient: '0xMerchantAddress',\n * payerAddress: '0xCustomerAddress'\n * });\n * console.log('Payment successful!', result.txHash);\n * ```\n */\n async pay(params: PaymentParams): Promise<PaymentResult> {\n if (!params.amount || parseFloat(params.amount) <= 0) {\n throw new Error('Invalid amount');\n }\n\n if (!params.recipient.match(/^0x[a-fA-F0-9]{40}$/)) {\n throw new Error('Invalid recipient address');\n }\n\n // Resolve payer address\n let payerAddress = params.payerAddress || '';\n if (!payerAddress) {\n if (this.wallet) {\n payerAddress = this.wallet.address as `0x${string}`;\n } else if (typeof window !== 'undefined' && (window as any).ethereum) {\n const accounts = await (window as any).ethereum.request({\n method: 'eth_requestAccounts',\n });\n payerAddress = accounts[0];\n } else {\n throw new Error(\n 'No payer address provided and no wallet available. Provide payerAddress or privateKey in config.'\n );\n }\n }\n\n payerAddress = payerAddress.toLowerCase() as `0x${string}`;\n const recipientAddress = params.recipient.toLowerCase();\n\n // Select random facilitator\n const facilitator = await this.selectRandomFacilitator();\n\n // Create ERC-3009 authorization\n const amount = BigInt(parseFloat(params.amount) * 1e6); // 6 decimals for USDC\n const validAfter = Math.floor(Date.now() / 1000) - 60;\n const validBefore = validAfter + 3600; // 1 hour validity\n const nonce =\n '0x' +\n Array.from({ length: 64 }, () =>\n Math.floor(Math.random() * 16).toString(16)\n ).join('');\n\n // EIP-712 Domain - uses chain-specific domain name\n const domain = {\n name: this.chain.erc3009DomainName,\n version: this.chain.erc3009DomainVersion,\n chainId: this.chain.chainId,\n verifyingContract: this.chain.usdcAddress,\n };\n\n const types = {\n TransferWithAuthorization: [\n { name: 'from', type: 'address' },\n { name: 'to', type: 'address' },\n { name: 'value', type: 'uint256' },\n { name: 'validAfter', type: 'uint256' },\n { name: 'validBefore', type: 'uint256' },\n { name: 'nonce', type: 'bytes32' },\n ],\n };\n\n const value = {\n from: payerAddress,\n to: recipientAddress,\n value: amount,\n validAfter,\n validBefore,\n nonce,\n };\n\n // Sign the authorization\n let signature: string;\n\n if (this.wallet) {\n signature = await this.wallet.signTypedData(domain, types, value);\n } else if (typeof window !== 'undefined' && (window as any).ethereum) {\n const { TypedDataEncoder } = await import('ethers');\n\n const messageForSigning = {\n from: payerAddress,\n to: recipientAddress,\n value: amount.toString(),\n validAfter: validAfter.toString(),\n validBefore: validBefore.toString(),\n nonce,\n };\n\n const typedDataPayload = JSON.stringify({\n types: {\n EIP712Domain: [\n { name: 'name', type: 'string' },\n { name: 'version', type: 'string' },\n { name: 'chainId', type: 'uint256' },\n { name: 'verifyingContract', type: 'address' },\n ],\n TransferWithAuthorization: types.TransferWithAuthorization,\n },\n domain,\n primaryType: 'TransferWithAuthorization',\n message: messageForSigning,\n });\n\n signature = await (window as any).ethereum.request({\n method: 'eth_signTypedData_v4',\n params: [payerAddress, typedDataPayload],\n });\n } else {\n throw new Error('No signing method available');\n }\n\n // Build payment payload\n const paymentPayload = {\n signature,\n authorization: {\n from: payerAddress,\n to: recipientAddress,\n value: amount.toString(),\n validAfter: validAfter.toString(),\n validBefore: validBefore.toString(),\n nonce,\n },\n };\n\n // Submit to facilitator\n try {\n const response = await axios.post(\n `${this.config.apiUrl}/api/x402/settle-custom`,\n {\n facilitatorId: facilitator.id,\n paymentPayload,\n }\n );\n\n if (!response.data.success) {\n throw new Error(\n response.data.error || response.data.message || 'Payment failed'\n );\n }\n\n return {\n success: true,\n txHash: response.data.txHash,\n facilitator: {\n id: facilitator.id,\n name: facilitator.name || `Facilitator ${facilitator.id.slice(0, 8)}`,\n wallet: facilitator.facilitatorWallet,\n },\n payment: {\n from: payerAddress,\n to: recipientAddress,\n amount: params.amount,\n network: this.config.network,\n },\n };\n } catch (error: any) {\n if (error.response?.data) {\n const backendError =\n error.response.data.message || error.response.data.error;\n throw new Error(`Payment failed: ${backendError}`);\n }\n throw error;\n }\n }\n\n /**\n * Get all active facilitators for the current network\n */\n async getFacilitators(): Promise<Facilitator[]> {\n try {\n const response = await axios.get(\n `${this.config.apiUrl}/api/facilitator/list`,\n {\n timeout: 10000,\n headers: {\n 'User-Agent': 'Facinet-SDK/2.3.0',\n },\n }\n );\n\n if (response.data.success && Array.isArray(response.data.facilitators)) {\n // Filter by status and network/chainId\n return response.data.facilitators.filter((f: Facilitator) => {\n // Must be active\n if (f.status !== 'active') {\n return false;\n }\n \n // If facilitator has network or chainId, match it with current chain\n if (f.network) {\n return f.network === this.config.network;\n }\n \n if (f.chainId !== undefined) {\n return f.chainId === this.chain.chainId;\n }\n \n // If no network/chainId specified, include it (backwards compatibility)\n return true;\n });\n }\n\n return [];\n } catch (error: any) {\n throw new Error(\n `Failed to fetch facilitators for ${this.chain.displayName} (${this.config.network}): ${error.message || 'Unknown error'}`\n );\n }\n }\n\n /**\n * Select a random active facilitator for the current network\n */\n async selectRandomFacilitator(): Promise<Facilitator> {\n const facilitators = await this.getFacilitators();\n\n if (facilitators.length === 0) {\n throw new Error(\n `No active facilitators available for ${this.chain.displayName} (${this.config.network}, Chain ID: ${this.chain.chainId}). ` +\n `Please check that facilitators are registered for this network. API URL: ${this.config.apiUrl}`\n );\n }\n\n const randomIndex = Math.floor(Math.random() * facilitators.length);\n const selectedFacilitator = facilitators[randomIndex];\n \n // Ensure facilitator has a name\n if (!selectedFacilitator.name) {\n selectedFacilitator.name = `Facilitator ${selectedFacilitator.id.slice(0, 8)}`;\n }\n \n return selectedFacilitator;\n }\n\n /**\n * Quick payment helper (static method)\n *\n * @example\n * ```typescript\n * // Pay on Base Sepolia\n * await Facinet.quickPay({\n * amount: '1',\n * recipient: '0xMerchantAddress',\n * privateKey: process.env.PRIVATE_KEY,\n * network: 'base-sepolia'\n * });\n * ```\n */\n static async quickPay(\n params: PaymentParams & { privateKey?: string; network?: FacinetConfig['network'] }\n ): Promise<PaymentResult> {\n const facinet = new Facinet({\n privateKey: params.privateKey,\n network: params.network,\n });\n\n return facinet.pay({\n amount: params.amount,\n recipient: params.recipient,\n payerAddress: params.payerAddress,\n });\n }\n}\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["/**\n * Facinet SDK - Main Export\n *\n * Use this when installing as a library:\n * npm install facinet\n *\n * @example\n * ```typescript\n * import { Facinet } from 'facinet';\n *\n * const facinet = new Facinet({ network: 'base-sepolia' });\n * await facinet.pay({\n * amount: '1',\n * recipient: '0xYourAddress'\n * });\n * ```\n */\n\nexport { Facinet } from './sdk/Facinet';\nexport type {\n FacinetConfig,\n PaymentParams,\n PaymentResult,\n Facilitator,\n ChainConfig,\n} from './sdk/types';\nexport { Facinet as default } from './sdk/Facinet';\n", "/**\n * Facinet SDK - Main Class\n *\n * JavaScript/TypeScript SDK for integrating x402 payments\n * Supports multichain: Avalanche Fuji, Ethereum Sepolia, Base Sepolia, Polygon Amoy\n */\n\nimport axios from 'axios';\nimport { Wallet, JsonRpcProvider } from 'ethers';\nimport type { FacinetConfig, PaymentParams, PaymentResult, Facilitator, ChainConfig } from './types';\n\n// All 4 supported chains\nconst CHAINS: Record<string, ChainConfig> = {\n 'avalanche-fuji': {\n name: 'avalanche-fuji',\n displayName: 'Avalanche Fuji',\n chainId: 43113,\n rpcUrl: 'https://api.avax-test.network/ext/bc/C/rpc',\n usdcAddress: '0x5425890298aed601595a70AB815c96711a31Bc65',\n usdcDecimals: 6,\n gasToken: 'AVAX',\n blockExplorer: 'https://testnet.snowtrace.io',\n erc3009DomainName: 'USD Coin',\n erc3009DomainVersion: '2',\n },\n 'ethereum-sepolia': {\n name: 'ethereum-sepolia',\n displayName: 'Ethereum Sepolia',\n chainId: 11155111,\n rpcUrl: 'https://ethereum-sepolia-rpc.publicnode.com',\n usdcAddress: '0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238',\n usdcDecimals: 6,\n gasToken: 'ETH',\n blockExplorer: 'https://sepolia.etherscan.io',\n erc3009DomainName: 'USDC',\n erc3009DomainVersion: '2',\n },\n 'base-sepolia': {\n name: 'base-sepolia',\n displayName: 'Base Sepolia',\n chainId: 84532,\n rpcUrl: 'https://sepolia.base.org',\n usdcAddress: '0x036CbD53842c5426634e7929541eC2318f3dCF7e',\n usdcDecimals: 6,\n gasToken: 'ETH',\n blockExplorer: 'https://sepolia.basescan.org',\n erc3009DomainName: 'USDC',\n erc3009DomainVersion: '2',\n },\n 'polygon-amoy': {\n name: 'polygon-amoy',\n displayName: 'Polygon Amoy',\n chainId: 80002,\n rpcUrl: 'https://rpc-amoy.polygon.technology',\n usdcAddress: '0x41E94Eb019C0762f9Bfcf9Fb1E58725BfB0e7582',\n usdcDecimals: 6,\n gasToken: 'MATIC',\n blockExplorer: 'https://amoy.polygonscan.com',\n erc3009DomainName: 'USDC',\n erc3009DomainVersion: '2',\n },\n};\n\n// Legacy aliases for backwards compatibility\nconst NETWORK_ALIASES: Record<string, string> = {\n 'avalanche': 'avalanche-fuji',\n 'ethereum': 'ethereum-sepolia',\n 'polygon': 'polygon-amoy',\n 'base': 'base-sepolia',\n};\n\n// Unified API URL for all networks\nconst DEFAULT_API_URL = 'https://facinet.vercel.app';\n\n/**\n * Resolve network name (handles legacy aliases)\n */\nfunction resolveNetwork(network: string): string {\n return NETWORK_ALIASES[network] || network;\n}\n\n/**\n * Get API URL for a network\n */\nfunction getApiUrlForNetwork(network: string, customApiUrl?: string): string {\n if (customApiUrl) {\n return customApiUrl.replace(/\\/$/, '');\n }\n return DEFAULT_API_URL;\n}\n\nexport class Facinet {\n private config: Required<Pick<FacinetConfig, 'apiUrl' | 'privateKey' | 'network' | 'rpcUrl'>>;\n private chain: ChainConfig;\n private wallet?: InstanceType<typeof Wallet>;\n\n constructor(config: FacinetConfig = {}) {\n const resolvedNetwork = resolveNetwork(config.network || 'avalanche-fuji');\n const apiUrl = getApiUrlForNetwork(resolvedNetwork, config.apiUrl);\n\n this.config = {\n apiUrl,\n privateKey: config.privateKey || '',\n network: resolvedNetwork as any,\n rpcUrl: config.rpcUrl || '',\n };\n\n this.chain = CHAINS[resolvedNetwork];\n if (!this.chain) {\n throw new Error(\n `Unsupported network: ${config.network}. Supported networks: ${Object.keys(CHAINS).join(', ')}`\n );\n }\n\n if (this.config.privateKey) {\n const provider = new JsonRpcProvider(\n this.config.rpcUrl || this.chain.rpcUrl\n );\n this.wallet = new Wallet(this.config.privateKey, provider);\n }\n }\n\n /**\n * Get the current chain configuration\n */\n getChain(): ChainConfig {\n return { ...this.chain };\n }\n\n /**\n * Get all supported chains\n */\n static getSupportedChains(): ChainConfig[] {\n return Object.values(CHAINS);\n }\n\n /**\n * Get supported network names\n */\n static getSupportedNetworks(): string[] {\n return Object.keys(CHAINS);\n }\n\n /**\n * Make a payment via x402 facilitator network\n *\n * @example\n * ```typescript\n * const facinet = new Facinet({ network: 'base-sepolia' });\n * const result = await facinet.pay({\n * amount: '1',\n * recipient: '0xMerchantAddress',\n * payerAddress: '0xCustomerAddress'\n * });\n * console.log('Payment successful!', result.txHash);\n * ```\n */\n async pay(params: PaymentParams): Promise<PaymentResult> {\n if (!params.amount || parseFloat(params.amount) <= 0) {\n throw new Error('Invalid amount');\n }\n\n if (!params.recipient.match(/^0x[a-fA-F0-9]{40}$/)) {\n throw new Error('Invalid recipient address');\n }\n\n // Resolve payer address\n let payerAddress = params.payerAddress || '';\n if (!payerAddress) {\n if (this.wallet) {\n payerAddress = this.wallet.address as `0x${string}`;\n } else if (typeof window !== 'undefined' && (window as any).ethereum) {\n const accounts = await (window as any).ethereum.request({\n method: 'eth_requestAccounts',\n });\n payerAddress = accounts[0];\n } else {\n throw new Error(\n 'No payer address provided and no wallet available. Provide payerAddress or privateKey in config.'\n );\n }\n }\n\n payerAddress = payerAddress.toLowerCase() as `0x${string}`;\n const recipientAddress = params.recipient.toLowerCase();\n\n // Select random facilitator for this network\n const facilitator = await this.selectRandomFacilitator();\n \n // Validate facilitator matches our network (if facilitator has network/chainId info)\n if (facilitator.network && facilitator.network !== this.config.network) {\n throw new Error(\n `Facilitator ${facilitator.id} is registered for network ${facilitator.network}, but payment is for ${this.config.network}. ` +\n `Please ensure facilitators are registered for the correct network.`\n );\n }\n if (facilitator.chainId !== undefined && facilitator.chainId !== this.chain.chainId) {\n throw new Error(\n `Facilitator ${facilitator.id} is registered for chain ID ${facilitator.chainId}, but payment is for chain ID ${this.chain.chainId}. ` +\n `Please ensure facilitators are registered for the correct chain.`\n );\n }\n\n // Create ERC-3009 authorization\n const amount = BigInt(parseFloat(params.amount) * 1e6); // 6 decimals for USDC\n const validAfter = Math.floor(Date.now() / 1000) - 60;\n const validBefore = validAfter + 3600; // 1 hour validity\n const nonce =\n '0x' +\n Array.from({ length: 64 }, () =>\n Math.floor(Math.random() * 16).toString(16)\n ).join('');\n\n // EIP-712 Domain - uses chain-specific domain name\n const domain = {\n name: this.chain.erc3009DomainName,\n version: this.chain.erc3009DomainVersion,\n chainId: this.chain.chainId,\n verifyingContract: this.chain.usdcAddress,\n };\n\n const types = {\n TransferWithAuthorization: [\n { name: 'from', type: 'address' },\n { name: 'to', type: 'address' },\n { name: 'value', type: 'uint256' },\n { name: 'validAfter', type: 'uint256' },\n { name: 'validBefore', type: 'uint256' },\n { name: 'nonce', type: 'bytes32' },\n ],\n };\n\n const value = {\n from: payerAddress,\n to: recipientAddress,\n value: amount,\n validAfter,\n validBefore,\n nonce,\n };\n\n // Sign the authorization\n let signature: string;\n\n if (this.wallet) {\n signature = await this.wallet.signTypedData(domain, types, value);\n } else if (typeof window !== 'undefined' && (window as any).ethereum) {\n const { TypedDataEncoder } = await import('ethers');\n\n const messageForSigning = {\n from: payerAddress,\n to: recipientAddress,\n value: amount.toString(),\n validAfter: validAfter.toString(),\n validBefore: validBefore.toString(),\n nonce,\n };\n\n const typedDataPayload = JSON.stringify({\n types: {\n EIP712Domain: [\n { name: 'name', type: 'string' },\n { name: 'version', type: 'string' },\n { name: 'chainId', type: 'uint256' },\n { name: 'verifyingContract', type: 'address' },\n ],\n TransferWithAuthorization: types.TransferWithAuthorization,\n },\n domain,\n primaryType: 'TransferWithAuthorization',\n message: messageForSigning,\n });\n\n signature = await (window as any).ethereum.request({\n method: 'eth_signTypedData_v4',\n params: [payerAddress, typedDataPayload],\n });\n } else {\n throw new Error('No signing method available');\n }\n\n // Build payment payload with complete authorization info\n const paymentPayload = {\n signature,\n authorization: {\n from: payerAddress,\n to: recipientAddress,\n value: amount.toString(),\n validAfter: validAfter.toString(),\n validBefore: validBefore.toString(),\n nonce,\n },\n // Include domain info so backend can verify signature\n domain: {\n name: this.chain.erc3009DomainName,\n version: this.chain.erc3009DomainVersion,\n chainId: this.chain.chainId,\n verifyingContract: this.chain.usdcAddress,\n },\n };\n\n // Submit to facilitator with explicit network/chain info\n try {\n const payload = {\n facilitatorId: facilitator.id,\n paymentPayload,\n network: this.config.network,\n chainId: this.chain.chainId,\n usdcAddress: this.chain.usdcAddress,\n // Explicitly include domain info at top level for backend\n domainName: this.chain.erc3009DomainName,\n domainVersion: this.chain.erc3009DomainVersion,\n };\n\n // Debug: Log what we're sending (remove in production if needed)\n if (process.env.NODE_ENV === 'development' || process.env.DEBUG) {\n console.log('[Facinet SDK] Payment payload:', {\n network: payload.network,\n chainId: payload.chainId,\n usdcAddress: payload.usdcAddress,\n domainName: payload.domainName,\n facilitatorId: payload.facilitatorId,\n });\n }\n\n const response = await axios.post(\n `${this.config.apiUrl}/api/x402/settle-custom`,\n payload\n );\n\n if (!response.data.success) {\n throw new Error(\n response.data.error || response.data.message || 'Payment failed'\n );\n }\n\n return {\n success: true,\n txHash: response.data.txHash,\n facilitator: {\n id: facilitator.id,\n name: facilitator.name || `Facilitator ${facilitator.id.slice(0, 8)}`,\n wallet: facilitator.facilitatorWallet,\n },\n payment: {\n from: payerAddress,\n to: recipientAddress,\n amount: params.amount,\n network: this.config.network,\n },\n };\n } catch (error: any) {\n if (error.response?.data) {\n const backendError =\n error.response.data.message || error.response.data.error;\n throw new Error(`Payment failed: ${backendError}`);\n }\n throw error;\n }\n }\n\n /**\n * Get all active facilitators for the current network\n */\n async getFacilitators(): Promise<Facilitator[]> {\n try {\n const response = await axios.get(\n `${this.config.apiUrl}/api/facilitator/list`,\n {\n timeout: 10000,\n headers: {\n 'User-Agent': 'Facinet-SDK/2.3.0',\n },\n }\n );\n\n if (response.data.success && Array.isArray(response.data.facilitators)) {\n // Filter by status and network/chainId\n return response.data.facilitators.filter((f: Facilitator) => {\n // Must be active\n if (f.status !== 'active') {\n return false;\n }\n \n // If facilitator has network or chainId, match it with current chain\n if (f.network) {\n return f.network === this.config.network;\n }\n \n if (f.chainId !== undefined) {\n return f.chainId === this.chain.chainId;\n }\n \n // If no network/chainId specified, include it (backwards compatibility)\n return true;\n });\n }\n\n return [];\n } catch (error: any) {\n throw new Error(\n `Failed to fetch facilitators for ${this.chain.displayName} (${this.config.network}): ${error.message || 'Unknown error'}`\n );\n }\n }\n\n /**\n * Select a random active facilitator for the current network\n */\n async selectRandomFacilitator(): Promise<Facilitator> {\n const facilitators = await this.getFacilitators();\n\n if (facilitators.length === 0) {\n throw new Error(\n `No active facilitators available for ${this.chain.displayName} (${this.config.network}, Chain ID: ${this.chain.chainId}). ` +\n `Please check that facilitators are registered for this network. API URL: ${this.config.apiUrl}`\n );\n }\n\n const randomIndex = Math.floor(Math.random() * facilitators.length);\n const selectedFacilitator = facilitators[randomIndex];\n \n // Ensure facilitator has a name\n if (!selectedFacilitator.name) {\n selectedFacilitator.name = `Facilitator ${selectedFacilitator.id.slice(0, 8)}`;\n }\n \n return selectedFacilitator;\n }\n\n /**\n * Quick payment helper (static method)\n *\n * @example\n * ```typescript\n * // Pay on Base Sepolia\n * await Facinet.quickPay({\n * amount: '1',\n * recipient: '0xMerchantAddress',\n * privateKey: process.env.PRIVATE_KEY,\n * network: 'base-sepolia'\n * });\n * ```\n */\n static async quickPay(\n params: PaymentParams & { privateKey?: string; network?: FacinetConfig['network'] }\n ): Promise<PaymentResult> {\n const facinet = new Facinet({\n privateKey: params.privateKey,\n network: params.network,\n });\n\n return facinet.pay({\n amount: params.amount,\n recipient: params.recipient,\n payerAddress: params.payerAddress,\n });\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["axios"]
|
|
7
7
|
}
|
package/dist/sdk.mjs
CHANGED
|
@@ -147,6 +147,16 @@ var Facinet = class _Facinet {
|
|
|
147
147
|
payerAddress = payerAddress.toLowerCase();
|
|
148
148
|
const recipientAddress = params.recipient.toLowerCase();
|
|
149
149
|
const facilitator = await this.selectRandomFacilitator();
|
|
150
|
+
if (facilitator.network && facilitator.network !== this.config.network) {
|
|
151
|
+
throw new Error(
|
|
152
|
+
`Facilitator ${facilitator.id} is registered for network ${facilitator.network}, but payment is for ${this.config.network}. Please ensure facilitators are registered for the correct network.`
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
if (facilitator.chainId !== void 0 && facilitator.chainId !== this.chain.chainId) {
|
|
156
|
+
throw new Error(
|
|
157
|
+
`Facilitator ${facilitator.id} is registered for chain ID ${facilitator.chainId}, but payment is for chain ID ${this.chain.chainId}. Please ensure facilitators are registered for the correct chain.`
|
|
158
|
+
);
|
|
159
|
+
}
|
|
150
160
|
const amount = BigInt(parseFloat(params.amount) * 1e6);
|
|
151
161
|
const validAfter = Math.floor(Date.now() / 1e3) - 60;
|
|
152
162
|
const validBefore = validAfter + 3600;
|
|
@@ -221,15 +231,38 @@ var Facinet = class _Facinet {
|
|
|
221
231
|
validAfter: validAfter.toString(),
|
|
222
232
|
validBefore: validBefore.toString(),
|
|
223
233
|
nonce
|
|
234
|
+
},
|
|
235
|
+
// Include domain info so backend can verify signature
|
|
236
|
+
domain: {
|
|
237
|
+
name: this.chain.erc3009DomainName,
|
|
238
|
+
version: this.chain.erc3009DomainVersion,
|
|
239
|
+
chainId: this.chain.chainId,
|
|
240
|
+
verifyingContract: this.chain.usdcAddress
|
|
224
241
|
}
|
|
225
242
|
};
|
|
226
243
|
try {
|
|
244
|
+
const payload = {
|
|
245
|
+
facilitatorId: facilitator.id,
|
|
246
|
+
paymentPayload,
|
|
247
|
+
network: this.config.network,
|
|
248
|
+
chainId: this.chain.chainId,
|
|
249
|
+
usdcAddress: this.chain.usdcAddress,
|
|
250
|
+
// Explicitly include domain info at top level for backend
|
|
251
|
+
domainName: this.chain.erc3009DomainName,
|
|
252
|
+
domainVersion: this.chain.erc3009DomainVersion
|
|
253
|
+
};
|
|
254
|
+
if (process.env.NODE_ENV === "development" || process.env.DEBUG) {
|
|
255
|
+
console.log("[Facinet SDK] Payment payload:", {
|
|
256
|
+
network: payload.network,
|
|
257
|
+
chainId: payload.chainId,
|
|
258
|
+
usdcAddress: payload.usdcAddress,
|
|
259
|
+
domainName: payload.domainName,
|
|
260
|
+
facilitatorId: payload.facilitatorId
|
|
261
|
+
});
|
|
262
|
+
}
|
|
227
263
|
const response = await axios.post(
|
|
228
264
|
`${this.config.apiUrl}/api/x402/settle-custom`,
|
|
229
|
-
|
|
230
|
-
facilitatorId: facilitator.id,
|
|
231
|
-
paymentPayload
|
|
232
|
-
}
|
|
265
|
+
payload
|
|
233
266
|
);
|
|
234
267
|
if (!response.data.success) {
|
|
235
268
|
throw new Error(
|
package/dist/sdk.mjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/sdk/Facinet.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Facinet SDK - Main Class\n *\n * JavaScript/TypeScript SDK for integrating x402 payments\n * Supports multichain: Avalanche Fuji, Ethereum Sepolia, Base Sepolia, Polygon Amoy\n */\n\nimport axios from 'axios';\nimport { Wallet, JsonRpcProvider } from 'ethers';\nimport type { FacinetConfig, PaymentParams, PaymentResult, Facilitator, ChainConfig } from './types';\n\n// All 4 supported chains\nconst CHAINS: Record<string, ChainConfig> = {\n 'avalanche-fuji': {\n name: 'avalanche-fuji',\n displayName: 'Avalanche Fuji',\n chainId: 43113,\n rpcUrl: 'https://api.avax-test.network/ext/bc/C/rpc',\n usdcAddress: '0x5425890298aed601595a70AB815c96711a31Bc65',\n usdcDecimals: 6,\n gasToken: 'AVAX',\n blockExplorer: 'https://testnet.snowtrace.io',\n erc3009DomainName: 'USD Coin',\n erc3009DomainVersion: '2',\n },\n 'ethereum-sepolia': {\n name: 'ethereum-sepolia',\n displayName: 'Ethereum Sepolia',\n chainId: 11155111,\n rpcUrl: 'https://ethereum-sepolia-rpc.publicnode.com',\n usdcAddress: '0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238',\n usdcDecimals: 6,\n gasToken: 'ETH',\n blockExplorer: 'https://sepolia.etherscan.io',\n erc3009DomainName: 'USDC',\n erc3009DomainVersion: '2',\n },\n 'base-sepolia': {\n name: 'base-sepolia',\n displayName: 'Base Sepolia',\n chainId: 84532,\n rpcUrl: 'https://sepolia.base.org',\n usdcAddress: '0x036CbD53842c5426634e7929541eC2318f3dCF7e',\n usdcDecimals: 6,\n gasToken: 'ETH',\n blockExplorer: 'https://sepolia.basescan.org',\n erc3009DomainName: 'USDC',\n erc3009DomainVersion: '2',\n },\n 'polygon-amoy': {\n name: 'polygon-amoy',\n displayName: 'Polygon Amoy',\n chainId: 80002,\n rpcUrl: 'https://rpc-amoy.polygon.technology',\n usdcAddress: '0x41E94Eb019C0762f9Bfcf9Fb1E58725BfB0e7582',\n usdcDecimals: 6,\n gasToken: 'MATIC',\n blockExplorer: 'https://amoy.polygonscan.com',\n erc3009DomainName: 'USDC',\n erc3009DomainVersion: '2',\n },\n};\n\n// Legacy aliases for backwards compatibility\nconst NETWORK_ALIASES: Record<string, string> = {\n 'avalanche': 'avalanche-fuji',\n 'ethereum': 'ethereum-sepolia',\n 'polygon': 'polygon-amoy',\n 'base': 'base-sepolia',\n};\n\n// Unified API URL for all networks\nconst DEFAULT_API_URL = 'https://facinet.vercel.app';\n\n/**\n * Resolve network name (handles legacy aliases)\n */\nfunction resolveNetwork(network: string): string {\n return NETWORK_ALIASES[network] || network;\n}\n\n/**\n * Get API URL for a network\n */\nfunction getApiUrlForNetwork(network: string, customApiUrl?: string): string {\n if (customApiUrl) {\n return customApiUrl.replace(/\\/$/, '');\n }\n return DEFAULT_API_URL;\n}\n\nexport class Facinet {\n private config: Required<Pick<FacinetConfig, 'apiUrl' | 'privateKey' | 'network' | 'rpcUrl'>>;\n private chain: ChainConfig;\n private wallet?: InstanceType<typeof Wallet>;\n\n constructor(config: FacinetConfig = {}) {\n const resolvedNetwork = resolveNetwork(config.network || 'avalanche-fuji');\n const apiUrl = getApiUrlForNetwork(resolvedNetwork, config.apiUrl);\n\n this.config = {\n apiUrl,\n privateKey: config.privateKey || '',\n network: resolvedNetwork as any,\n rpcUrl: config.rpcUrl || '',\n };\n\n this.chain = CHAINS[resolvedNetwork];\n if (!this.chain) {\n throw new Error(\n `Unsupported network: ${config.network}. Supported networks: ${Object.keys(CHAINS).join(', ')}`\n );\n }\n\n if (this.config.privateKey) {\n const provider = new JsonRpcProvider(\n this.config.rpcUrl || this.chain.rpcUrl\n );\n this.wallet = new Wallet(this.config.privateKey, provider);\n }\n }\n\n /**\n * Get the current chain configuration\n */\n getChain(): ChainConfig {\n return { ...this.chain };\n }\n\n /**\n * Get all supported chains\n */\n static getSupportedChains(): ChainConfig[] {\n return Object.values(CHAINS);\n }\n\n /**\n * Get supported network names\n */\n static getSupportedNetworks(): string[] {\n return Object.keys(CHAINS);\n }\n\n /**\n * Make a payment via x402 facilitator network\n *\n * @example\n * ```typescript\n * const facinet = new Facinet({ network: 'base-sepolia' });\n * const result = await facinet.pay({\n * amount: '1',\n * recipient: '0xMerchantAddress',\n * payerAddress: '0xCustomerAddress'\n * });\n * console.log('Payment successful!', result.txHash);\n * ```\n */\n async pay(params: PaymentParams): Promise<PaymentResult> {\n if (!params.amount || parseFloat(params.amount) <= 0) {\n throw new Error('Invalid amount');\n }\n\n if (!params.recipient.match(/^0x[a-fA-F0-9]{40}$/)) {\n throw new Error('Invalid recipient address');\n }\n\n // Resolve payer address\n let payerAddress = params.payerAddress || '';\n if (!payerAddress) {\n if (this.wallet) {\n payerAddress = this.wallet.address as `0x${string}`;\n } else if (typeof window !== 'undefined' && (window as any).ethereum) {\n const accounts = await (window as any).ethereum.request({\n method: 'eth_requestAccounts',\n });\n payerAddress = accounts[0];\n } else {\n throw new Error(\n 'No payer address provided and no wallet available. Provide payerAddress or privateKey in config.'\n );\n }\n }\n\n payerAddress = payerAddress.toLowerCase() as `0x${string}`;\n const recipientAddress = params.recipient.toLowerCase();\n\n // Select random facilitator\n const facilitator = await this.selectRandomFacilitator();\n\n // Create ERC-3009 authorization\n const amount = BigInt(parseFloat(params.amount) * 1e6); // 6 decimals for USDC\n const validAfter = Math.floor(Date.now() / 1000) - 60;\n const validBefore = validAfter + 3600; // 1 hour validity\n const nonce =\n '0x' +\n Array.from({ length: 64 }, () =>\n Math.floor(Math.random() * 16).toString(16)\n ).join('');\n\n // EIP-712 Domain - uses chain-specific domain name\n const domain = {\n name: this.chain.erc3009DomainName,\n version: this.chain.erc3009DomainVersion,\n chainId: this.chain.chainId,\n verifyingContract: this.chain.usdcAddress,\n };\n\n const types = {\n TransferWithAuthorization: [\n { name: 'from', type: 'address' },\n { name: 'to', type: 'address' },\n { name: 'value', type: 'uint256' },\n { name: 'validAfter', type: 'uint256' },\n { name: 'validBefore', type: 'uint256' },\n { name: 'nonce', type: 'bytes32' },\n ],\n };\n\n const value = {\n from: payerAddress,\n to: recipientAddress,\n value: amount,\n validAfter,\n validBefore,\n nonce,\n };\n\n // Sign the authorization\n let signature: string;\n\n if (this.wallet) {\n signature = await this.wallet.signTypedData(domain, types, value);\n } else if (typeof window !== 'undefined' && (window as any).ethereum) {\n const { TypedDataEncoder } = await import('ethers');\n\n const messageForSigning = {\n from: payerAddress,\n to: recipientAddress,\n value: amount.toString(),\n validAfter: validAfter.toString(),\n validBefore: validBefore.toString(),\n nonce,\n };\n\n const typedDataPayload = JSON.stringify({\n types: {\n EIP712Domain: [\n { name: 'name', type: 'string' },\n { name: 'version', type: 'string' },\n { name: 'chainId', type: 'uint256' },\n { name: 'verifyingContract', type: 'address' },\n ],\n TransferWithAuthorization: types.TransferWithAuthorization,\n },\n domain,\n primaryType: 'TransferWithAuthorization',\n message: messageForSigning,\n });\n\n signature = await (window as any).ethereum.request({\n method: 'eth_signTypedData_v4',\n params: [payerAddress, typedDataPayload],\n });\n } else {\n throw new Error('No signing method available');\n }\n\n // Build payment payload\n const paymentPayload = {\n signature,\n authorization: {\n from: payerAddress,\n to: recipientAddress,\n value: amount.toString(),\n validAfter: validAfter.toString(),\n validBefore: validBefore.toString(),\n nonce,\n },\n };\n\n // Submit to facilitator\n try {\n const response = await axios.post(\n `${this.config.apiUrl}/api/x402/settle-custom`,\n {\n facilitatorId: facilitator.id,\n paymentPayload,\n }\n );\n\n if (!response.data.success) {\n throw new Error(\n response.data.error || response.data.message || 'Payment failed'\n );\n }\n\n return {\n success: true,\n txHash: response.data.txHash,\n facilitator: {\n id: facilitator.id,\n name: facilitator.name || `Facilitator ${facilitator.id.slice(0, 8)}`,\n wallet: facilitator.facilitatorWallet,\n },\n payment: {\n from: payerAddress,\n to: recipientAddress,\n amount: params.amount,\n network: this.config.network,\n },\n };\n } catch (error: any) {\n if (error.response?.data) {\n const backendError =\n error.response.data.message || error.response.data.error;\n throw new Error(`Payment failed: ${backendError}`);\n }\n throw error;\n }\n }\n\n /**\n * Get all active facilitators for the current network\n */\n async getFacilitators(): Promise<Facilitator[]> {\n try {\n const response = await axios.get(\n `${this.config.apiUrl}/api/facilitator/list`,\n {\n timeout: 10000,\n headers: {\n 'User-Agent': 'Facinet-SDK/2.3.0',\n },\n }\n );\n\n if (response.data.success && Array.isArray(response.data.facilitators)) {\n // Filter by status and network/chainId\n return response.data.facilitators.filter((f: Facilitator) => {\n // Must be active\n if (f.status !== 'active') {\n return false;\n }\n \n // If facilitator has network or chainId, match it with current chain\n if (f.network) {\n return f.network === this.config.network;\n }\n \n if (f.chainId !== undefined) {\n return f.chainId === this.chain.chainId;\n }\n \n // If no network/chainId specified, include it (backwards compatibility)\n return true;\n });\n }\n\n return [];\n } catch (error: any) {\n throw new Error(\n `Failed to fetch facilitators for ${this.chain.displayName} (${this.config.network}): ${error.message || 'Unknown error'}`\n );\n }\n }\n\n /**\n * Select a random active facilitator for the current network\n */\n async selectRandomFacilitator(): Promise<Facilitator> {\n const facilitators = await this.getFacilitators();\n\n if (facilitators.length === 0) {\n throw new Error(\n `No active facilitators available for ${this.chain.displayName} (${this.config.network}, Chain ID: ${this.chain.chainId}). ` +\n `Please check that facilitators are registered for this network. API URL: ${this.config.apiUrl}`\n );\n }\n\n const randomIndex = Math.floor(Math.random() * facilitators.length);\n const selectedFacilitator = facilitators[randomIndex];\n \n // Ensure facilitator has a name\n if (!selectedFacilitator.name) {\n selectedFacilitator.name = `Facilitator ${selectedFacilitator.id.slice(0, 8)}`;\n }\n \n return selectedFacilitator;\n }\n\n /**\n * Quick payment helper (static method)\n *\n * @example\n * ```typescript\n * // Pay on Base Sepolia\n * await Facinet.quickPay({\n * amount: '1',\n * recipient: '0xMerchantAddress',\n * privateKey: process.env.PRIVATE_KEY,\n * network: 'base-sepolia'\n * });\n * ```\n */\n static async quickPay(\n params: PaymentParams & { privateKey?: string; network?: FacinetConfig['network'] }\n ): Promise<PaymentResult> {\n const facinet = new Facinet({\n privateKey: params.privateKey,\n network: params.network,\n });\n\n return facinet.pay({\n amount: params.amount,\n recipient: params.recipient,\n payerAddress: params.payerAddress,\n });\n }\n}\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["/**\n * Facinet SDK - Main Class\n *\n * JavaScript/TypeScript SDK for integrating x402 payments\n * Supports multichain: Avalanche Fuji, Ethereum Sepolia, Base Sepolia, Polygon Amoy\n */\n\nimport axios from 'axios';\nimport { Wallet, JsonRpcProvider } from 'ethers';\nimport type { FacinetConfig, PaymentParams, PaymentResult, Facilitator, ChainConfig } from './types';\n\n// All 4 supported chains\nconst CHAINS: Record<string, ChainConfig> = {\n 'avalanche-fuji': {\n name: 'avalanche-fuji',\n displayName: 'Avalanche Fuji',\n chainId: 43113,\n rpcUrl: 'https://api.avax-test.network/ext/bc/C/rpc',\n usdcAddress: '0x5425890298aed601595a70AB815c96711a31Bc65',\n usdcDecimals: 6,\n gasToken: 'AVAX',\n blockExplorer: 'https://testnet.snowtrace.io',\n erc3009DomainName: 'USD Coin',\n erc3009DomainVersion: '2',\n },\n 'ethereum-sepolia': {\n name: 'ethereum-sepolia',\n displayName: 'Ethereum Sepolia',\n chainId: 11155111,\n rpcUrl: 'https://ethereum-sepolia-rpc.publicnode.com',\n usdcAddress: '0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238',\n usdcDecimals: 6,\n gasToken: 'ETH',\n blockExplorer: 'https://sepolia.etherscan.io',\n erc3009DomainName: 'USDC',\n erc3009DomainVersion: '2',\n },\n 'base-sepolia': {\n name: 'base-sepolia',\n displayName: 'Base Sepolia',\n chainId: 84532,\n rpcUrl: 'https://sepolia.base.org',\n usdcAddress: '0x036CbD53842c5426634e7929541eC2318f3dCF7e',\n usdcDecimals: 6,\n gasToken: 'ETH',\n blockExplorer: 'https://sepolia.basescan.org',\n erc3009DomainName: 'USDC',\n erc3009DomainVersion: '2',\n },\n 'polygon-amoy': {\n name: 'polygon-amoy',\n displayName: 'Polygon Amoy',\n chainId: 80002,\n rpcUrl: 'https://rpc-amoy.polygon.technology',\n usdcAddress: '0x41E94Eb019C0762f9Bfcf9Fb1E58725BfB0e7582',\n usdcDecimals: 6,\n gasToken: 'MATIC',\n blockExplorer: 'https://amoy.polygonscan.com',\n erc3009DomainName: 'USDC',\n erc3009DomainVersion: '2',\n },\n};\n\n// Legacy aliases for backwards compatibility\nconst NETWORK_ALIASES: Record<string, string> = {\n 'avalanche': 'avalanche-fuji',\n 'ethereum': 'ethereum-sepolia',\n 'polygon': 'polygon-amoy',\n 'base': 'base-sepolia',\n};\n\n// Unified API URL for all networks\nconst DEFAULT_API_URL = 'https://facinet.vercel.app';\n\n/**\n * Resolve network name (handles legacy aliases)\n */\nfunction resolveNetwork(network: string): string {\n return NETWORK_ALIASES[network] || network;\n}\n\n/**\n * Get API URL for a network\n */\nfunction getApiUrlForNetwork(network: string, customApiUrl?: string): string {\n if (customApiUrl) {\n return customApiUrl.replace(/\\/$/, '');\n }\n return DEFAULT_API_URL;\n}\n\nexport class Facinet {\n private config: Required<Pick<FacinetConfig, 'apiUrl' | 'privateKey' | 'network' | 'rpcUrl'>>;\n private chain: ChainConfig;\n private wallet?: InstanceType<typeof Wallet>;\n\n constructor(config: FacinetConfig = {}) {\n const resolvedNetwork = resolveNetwork(config.network || 'avalanche-fuji');\n const apiUrl = getApiUrlForNetwork(resolvedNetwork, config.apiUrl);\n\n this.config = {\n apiUrl,\n privateKey: config.privateKey || '',\n network: resolvedNetwork as any,\n rpcUrl: config.rpcUrl || '',\n };\n\n this.chain = CHAINS[resolvedNetwork];\n if (!this.chain) {\n throw new Error(\n `Unsupported network: ${config.network}. Supported networks: ${Object.keys(CHAINS).join(', ')}`\n );\n }\n\n if (this.config.privateKey) {\n const provider = new JsonRpcProvider(\n this.config.rpcUrl || this.chain.rpcUrl\n );\n this.wallet = new Wallet(this.config.privateKey, provider);\n }\n }\n\n /**\n * Get the current chain configuration\n */\n getChain(): ChainConfig {\n return { ...this.chain };\n }\n\n /**\n * Get all supported chains\n */\n static getSupportedChains(): ChainConfig[] {\n return Object.values(CHAINS);\n }\n\n /**\n * Get supported network names\n */\n static getSupportedNetworks(): string[] {\n return Object.keys(CHAINS);\n }\n\n /**\n * Make a payment via x402 facilitator network\n *\n * @example\n * ```typescript\n * const facinet = new Facinet({ network: 'base-sepolia' });\n * const result = await facinet.pay({\n * amount: '1',\n * recipient: '0xMerchantAddress',\n * payerAddress: '0xCustomerAddress'\n * });\n * console.log('Payment successful!', result.txHash);\n * ```\n */\n async pay(params: PaymentParams): Promise<PaymentResult> {\n if (!params.amount || parseFloat(params.amount) <= 0) {\n throw new Error('Invalid amount');\n }\n\n if (!params.recipient.match(/^0x[a-fA-F0-9]{40}$/)) {\n throw new Error('Invalid recipient address');\n }\n\n // Resolve payer address\n let payerAddress = params.payerAddress || '';\n if (!payerAddress) {\n if (this.wallet) {\n payerAddress = this.wallet.address as `0x${string}`;\n } else if (typeof window !== 'undefined' && (window as any).ethereum) {\n const accounts = await (window as any).ethereum.request({\n method: 'eth_requestAccounts',\n });\n payerAddress = accounts[0];\n } else {\n throw new Error(\n 'No payer address provided and no wallet available. Provide payerAddress or privateKey in config.'\n );\n }\n }\n\n payerAddress = payerAddress.toLowerCase() as `0x${string}`;\n const recipientAddress = params.recipient.toLowerCase();\n\n // Select random facilitator for this network\n const facilitator = await this.selectRandomFacilitator();\n \n // Validate facilitator matches our network (if facilitator has network/chainId info)\n if (facilitator.network && facilitator.network !== this.config.network) {\n throw new Error(\n `Facilitator ${facilitator.id} is registered for network ${facilitator.network}, but payment is for ${this.config.network}. ` +\n `Please ensure facilitators are registered for the correct network.`\n );\n }\n if (facilitator.chainId !== undefined && facilitator.chainId !== this.chain.chainId) {\n throw new Error(\n `Facilitator ${facilitator.id} is registered for chain ID ${facilitator.chainId}, but payment is for chain ID ${this.chain.chainId}. ` +\n `Please ensure facilitators are registered for the correct chain.`\n );\n }\n\n // Create ERC-3009 authorization\n const amount = BigInt(parseFloat(params.amount) * 1e6); // 6 decimals for USDC\n const validAfter = Math.floor(Date.now() / 1000) - 60;\n const validBefore = validAfter + 3600; // 1 hour validity\n const nonce =\n '0x' +\n Array.from({ length: 64 }, () =>\n Math.floor(Math.random() * 16).toString(16)\n ).join('');\n\n // EIP-712 Domain - uses chain-specific domain name\n const domain = {\n name: this.chain.erc3009DomainName,\n version: this.chain.erc3009DomainVersion,\n chainId: this.chain.chainId,\n verifyingContract: this.chain.usdcAddress,\n };\n\n const types = {\n TransferWithAuthorization: [\n { name: 'from', type: 'address' },\n { name: 'to', type: 'address' },\n { name: 'value', type: 'uint256' },\n { name: 'validAfter', type: 'uint256' },\n { name: 'validBefore', type: 'uint256' },\n { name: 'nonce', type: 'bytes32' },\n ],\n };\n\n const value = {\n from: payerAddress,\n to: recipientAddress,\n value: amount,\n validAfter,\n validBefore,\n nonce,\n };\n\n // Sign the authorization\n let signature: string;\n\n if (this.wallet) {\n signature = await this.wallet.signTypedData(domain, types, value);\n } else if (typeof window !== 'undefined' && (window as any).ethereum) {\n const { TypedDataEncoder } = await import('ethers');\n\n const messageForSigning = {\n from: payerAddress,\n to: recipientAddress,\n value: amount.toString(),\n validAfter: validAfter.toString(),\n validBefore: validBefore.toString(),\n nonce,\n };\n\n const typedDataPayload = JSON.stringify({\n types: {\n EIP712Domain: [\n { name: 'name', type: 'string' },\n { name: 'version', type: 'string' },\n { name: 'chainId', type: 'uint256' },\n { name: 'verifyingContract', type: 'address' },\n ],\n TransferWithAuthorization: types.TransferWithAuthorization,\n },\n domain,\n primaryType: 'TransferWithAuthorization',\n message: messageForSigning,\n });\n\n signature = await (window as any).ethereum.request({\n method: 'eth_signTypedData_v4',\n params: [payerAddress, typedDataPayload],\n });\n } else {\n throw new Error('No signing method available');\n }\n\n // Build payment payload with complete authorization info\n const paymentPayload = {\n signature,\n authorization: {\n from: payerAddress,\n to: recipientAddress,\n value: amount.toString(),\n validAfter: validAfter.toString(),\n validBefore: validBefore.toString(),\n nonce,\n },\n // Include domain info so backend can verify signature\n domain: {\n name: this.chain.erc3009DomainName,\n version: this.chain.erc3009DomainVersion,\n chainId: this.chain.chainId,\n verifyingContract: this.chain.usdcAddress,\n },\n };\n\n // Submit to facilitator with explicit network/chain info\n try {\n const payload = {\n facilitatorId: facilitator.id,\n paymentPayload,\n network: this.config.network,\n chainId: this.chain.chainId,\n usdcAddress: this.chain.usdcAddress,\n // Explicitly include domain info at top level for backend\n domainName: this.chain.erc3009DomainName,\n domainVersion: this.chain.erc3009DomainVersion,\n };\n\n // Debug: Log what we're sending (remove in production if needed)\n if (process.env.NODE_ENV === 'development' || process.env.DEBUG) {\n console.log('[Facinet SDK] Payment payload:', {\n network: payload.network,\n chainId: payload.chainId,\n usdcAddress: payload.usdcAddress,\n domainName: payload.domainName,\n facilitatorId: payload.facilitatorId,\n });\n }\n\n const response = await axios.post(\n `${this.config.apiUrl}/api/x402/settle-custom`,\n payload\n );\n\n if (!response.data.success) {\n throw new Error(\n response.data.error || response.data.message || 'Payment failed'\n );\n }\n\n return {\n success: true,\n txHash: response.data.txHash,\n facilitator: {\n id: facilitator.id,\n name: facilitator.name || `Facilitator ${facilitator.id.slice(0, 8)}`,\n wallet: facilitator.facilitatorWallet,\n },\n payment: {\n from: payerAddress,\n to: recipientAddress,\n amount: params.amount,\n network: this.config.network,\n },\n };\n } catch (error: any) {\n if (error.response?.data) {\n const backendError =\n error.response.data.message || error.response.data.error;\n throw new Error(`Payment failed: ${backendError}`);\n }\n throw error;\n }\n }\n\n /**\n * Get all active facilitators for the current network\n */\n async getFacilitators(): Promise<Facilitator[]> {\n try {\n const response = await axios.get(\n `${this.config.apiUrl}/api/facilitator/list`,\n {\n timeout: 10000,\n headers: {\n 'User-Agent': 'Facinet-SDK/2.3.0',\n },\n }\n );\n\n if (response.data.success && Array.isArray(response.data.facilitators)) {\n // Filter by status and network/chainId\n return response.data.facilitators.filter((f: Facilitator) => {\n // Must be active\n if (f.status !== 'active') {\n return false;\n }\n \n // If facilitator has network or chainId, match it with current chain\n if (f.network) {\n return f.network === this.config.network;\n }\n \n if (f.chainId !== undefined) {\n return f.chainId === this.chain.chainId;\n }\n \n // If no network/chainId specified, include it (backwards compatibility)\n return true;\n });\n }\n\n return [];\n } catch (error: any) {\n throw new Error(\n `Failed to fetch facilitators for ${this.chain.displayName} (${this.config.network}): ${error.message || 'Unknown error'}`\n );\n }\n }\n\n /**\n * Select a random active facilitator for the current network\n */\n async selectRandomFacilitator(): Promise<Facilitator> {\n const facilitators = await this.getFacilitators();\n\n if (facilitators.length === 0) {\n throw new Error(\n `No active facilitators available for ${this.chain.displayName} (${this.config.network}, Chain ID: ${this.chain.chainId}). ` +\n `Please check that facilitators are registered for this network. API URL: ${this.config.apiUrl}`\n );\n }\n\n const randomIndex = Math.floor(Math.random() * facilitators.length);\n const selectedFacilitator = facilitators[randomIndex];\n \n // Ensure facilitator has a name\n if (!selectedFacilitator.name) {\n selectedFacilitator.name = `Facilitator ${selectedFacilitator.id.slice(0, 8)}`;\n }\n \n return selectedFacilitator;\n }\n\n /**\n * Quick payment helper (static method)\n *\n * @example\n * ```typescript\n * // Pay on Base Sepolia\n * await Facinet.quickPay({\n * amount: '1',\n * recipient: '0xMerchantAddress',\n * privateKey: process.env.PRIVATE_KEY,\n * network: 'base-sepolia'\n * });\n * ```\n */\n static async quickPay(\n params: PaymentParams & { privateKey?: string; network?: FacinetConfig['network'] }\n ): Promise<PaymentResult> {\n const facinet = new Facinet({\n privateKey: params.privateKey,\n network: params.network,\n });\n\n return facinet.pay({\n amount: params.amount,\n recipient: params.recipient,\n payerAddress: params.payerAddress,\n });\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED