@lukasrosario/account
Version:
Base Account SDK
125 lines (108 loc) • 3.82 kB
text/typescript
import type { Hex } from 'viem';
import { createBaseAccountSDK } from '../../../index.js';
import { CHAIN_IDS } from '../constants.js';
import type { PayerInfoResponses } from '../types.js';
/**
* Type for wallet_sendCalls request parameters
*/
type WalletSendCallsRequestParams = {
version: string;
chainId: number;
calls: Array<{
to: Hex;
data: Hex;
value: Hex;
}>;
capabilities: Record<string, unknown>;
};
/**
* Type for wallet_sendCalls response when it returns an object
*/
type WalletSendCallsObjectResponse = {
callsId: string;
capabilities?: {
dataCallback?: PayerInfoResponses;
[key: string]: unknown;
};
};
/**
* Type for payment execution result
*/
export interface PaymentExecutionResult {
transactionHash: Hex;
payerInfoResponses?: PayerInfoResponses;
}
/**
* Creates an ephemeral SDK instance configured for payments
* @param chainId - The chain ID to use
* @returns The configured SDK instance
*/
export function createEphemeralSDK(chainId: number) {
const appName = typeof window !== 'undefined' ? window.location.origin : 'Base Pay SDK';
const sdk = createBaseAccountSDK({
appName: appName,
appChainIds: [chainId],
preference: {
telemetry: true,
},
});
return sdk;
}
/**
* Executes a payment using the SDK
* @param sdk - The SDK instance
* @param requestParams - The wallet_sendCalls request parameters
* @returns The payment execution result with transaction hash and optional info responses
*/
export async function executePayment(
sdk: ReturnType<typeof createBaseAccountSDK>,
requestParams: WalletSendCallsRequestParams
): Promise<PaymentExecutionResult> {
const provider = sdk.getProvider();
const result = await provider.request({
method: 'wallet_sendCalls',
params: [requestParams],
});
let transactionHash: Hex;
let payerInfoResponses: PayerInfoResponses | undefined;
// Handle different response formats
if (typeof result === 'string' && result.length >= 66) {
// Standard response format - just a transaction hash
transactionHash = result.slice(0, 66) as Hex;
} else if (typeof result === 'object' && result !== null) {
// Object response format - contains callsId and capabilities with dataCallback
const resultObj = result as WalletSendCallsObjectResponse;
// Extract transaction hash from callsId
if (typeof resultObj.callsId === 'string' && resultObj.callsId.length >= 66) {
transactionHash = resultObj.callsId.slice(0, 66) as Hex;
// Extract info responses from capabilities.dataCallback
if (resultObj.capabilities?.dataCallback) {
payerInfoResponses = resultObj.capabilities.dataCallback;
}
} else {
throw new Error(`Could not extract transaction hash from object response. Available fields: ${Object.keys(resultObj).join(', ')}`);
}
} else {
throw new Error(`Unexpected response format from wallet_sendCalls: expected string with length > 66 or object with callsId, got ${typeof result}`);
}
return { transactionHash, payerInfoResponses };
}
/**
* Manages the complete payment flow with SDK lifecycle
* @param requestParams - The wallet_sendCalls request parameters
* @param testnet - Whether to use testnet
* @returns The payment execution result
*/
export async function executePaymentWithSDK(requestParams: WalletSendCallsRequestParams, testnet: boolean): Promise<PaymentExecutionResult> {
const network = testnet ? 'baseSepolia' : 'base';
const chainId = CHAIN_IDS[network];
const sdk = createEphemeralSDK(chainId);
const provider = sdk.getProvider();
try {
const result = await executePayment(sdk, requestParams);
return result;
} finally {
// Clean up provider state for subsequent payments
await provider.disconnect();
}
}