@atxp/base 0.2.22 → 0.3.0
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/baseAppAccount.js +6 -3
- package/dist/baseAppAccount.js.map +1 -1
- package/dist/baseAppPaymentMaker.js +22 -42
- package/dist/baseAppPaymentMaker.js.map +1 -1
- package/dist/eip1271JwtHelper.js +83 -0
- package/dist/eip1271JwtHelper.js.map +1 -0
- package/dist/index.cjs +630 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +157 -6
- package/dist/index.js +623 -5
- package/dist/index.js.map +1 -1
- package/dist/mainWalletPaymentMaker.js +26 -48
- package/dist/mainWalletPaymentMaker.js.map +1 -1
- package/dist/smartWalletHelpers.js +6 -3
- package/dist/smartWalletHelpers.js.map +1 -1
- package/dist/spendPermissionUtils.js +4 -2
- package/dist/spendPermissionUtils.js.map +1 -1
- package/dist/storage.js +6 -4
- package/dist/storage.js.map +1 -1
- package/package.json +21 -7
- package/dist/baseAppAccount.d.ts +0 -33
- package/dist/baseAppAccount.d.ts.map +0 -1
- package/dist/baseAppAccount.ephemeral.test.d.ts +0 -2
- package/dist/baseAppAccount.ephemeral.test.d.ts.map +0 -1
- package/dist/baseAppAccount.ephemeral.test.js +0 -426
- package/dist/baseAppAccount.ephemeral.test.js.map +0 -1
- package/dist/baseAppAccount.mainWallet.test.d.ts +0 -2
- package/dist/baseAppAccount.mainWallet.test.d.ts.map +0 -1
- package/dist/baseAppAccount.mainWallet.test.js +0 -259
- package/dist/baseAppAccount.mainWallet.test.js.map +0 -1
- package/dist/baseAppPaymentMaker.d.ts +0 -16
- package/dist/baseAppPaymentMaker.d.ts.map +0 -1
- package/dist/baseAppPaymentMaker.test.d.ts +0 -2
- package/dist/baseAppPaymentMaker.test.d.ts.map +0 -1
- package/dist/baseAppPaymentMaker.test.js +0 -113
- package/dist/baseAppPaymentMaker.test.js.map +0 -1
- package/dist/compatibility.test.d.ts +0 -2
- package/dist/compatibility.test.d.ts.map +0 -1
- package/dist/compatibility.test.js +0 -94
- package/dist/compatibility.test.js.map +0 -1
- package/dist/environment.test.d.ts +0 -2
- package/dist/environment.test.d.ts.map +0 -1
- package/dist/environment.test.js +0 -77
- package/dist/environment.test.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/mainWalletPaymentMaker.d.ts +0 -22
- package/dist/mainWalletPaymentMaker.d.ts.map +0 -1
- package/dist/mainWalletPaymentMaker.test.d.ts +0 -2
- package/dist/mainWalletPaymentMaker.test.d.ts.map +0 -1
- package/dist/mainWalletPaymentMaker.test.js +0 -340
- package/dist/mainWalletPaymentMaker.test.js.map +0 -1
- package/dist/smartWalletHelpers.d.ts +0 -13
- package/dist/smartWalletHelpers.d.ts.map +0 -1
- package/dist/spendPermissionUtils.d.ts +0 -9
- package/dist/spendPermissionUtils.d.ts.map +0 -1
- package/dist/storage.d.ts +0 -51
- package/dist/storage.d.ts.map +0 -1
- package/dist/testHelpers.d.ts +0 -88
- package/dist/testHelpers.d.ts.map +0 -1
- package/dist/testHelpers.js +0 -202
- package/dist/testHelpers.js.map +0 -1
- package/dist/types.d.ts +0 -35
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -3
- package/dist/types.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,623 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { USDC_CONTRACT_ADDRESS_BASE } from '@atxp/client';
|
|
2
|
+
import { ConsoleLogger } from '@atxp/common';
|
|
3
|
+
import { encodeFunctionData, parseEther, toHex, createPublicClient, http } from 'viem';
|
|
4
|
+
import { privateKeyToAccount, generatePrivateKey } from 'viem/accounts';
|
|
5
|
+
import { base } from 'viem/chains';
|
|
6
|
+
import { toCoinbaseSmartAccount, createBundlerClient } from 'viem/account-abstraction';
|
|
7
|
+
import { createBaseAccountSDK } from '@base-org/account';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Loads the browser-only spend permission module.
|
|
11
|
+
* Throws an error if called in a server environment.
|
|
12
|
+
*
|
|
13
|
+
* Both BaseAppAccount and BaseAppPaymentMaker should only run in browser environments
|
|
14
|
+
* since they require wallet interaction and browser APIs.
|
|
15
|
+
*/
|
|
16
|
+
async function getSpendPermissionModule() {
|
|
17
|
+
// Check if we're in a browser environment
|
|
18
|
+
if (typeof window === 'undefined') {
|
|
19
|
+
throw new Error('Spend permission operations require browser environment. ' +
|
|
20
|
+
'BaseAppAccount and BaseAppPaymentMaker should only be used client-side in Next.js apps.');
|
|
21
|
+
}
|
|
22
|
+
// Use browser version since both classes require browser environment
|
|
23
|
+
return await import('@base-org/account/spend-permission/browser');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* EIP-1271 JWT helper utilities for creating properly formatted JWTs
|
|
28
|
+
* from EIP-1271 auth data.
|
|
29
|
+
*/
|
|
30
|
+
// Helper function to convert to base64url that works in both Node.js and browsers
|
|
31
|
+
function toBase64Url(data) {
|
|
32
|
+
// Convert string to base64
|
|
33
|
+
const base64 = typeof Buffer !== 'undefined'
|
|
34
|
+
? Buffer.from(data).toString('base64')
|
|
35
|
+
: btoa(data);
|
|
36
|
+
// Convert base64 to base64url
|
|
37
|
+
return base64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Convert EIP-1271 auth data to JWT format
|
|
41
|
+
* @param authData The EIP-1271 auth data (signature will be moved to JWT signature section)
|
|
42
|
+
* @returns JWT string in the format header.payload.signature
|
|
43
|
+
*/
|
|
44
|
+
function createEIP1271JWT(authData) {
|
|
45
|
+
// Create JWT header
|
|
46
|
+
const header = {
|
|
47
|
+
alg: 'EIP1271',
|
|
48
|
+
typ: 'JWT'
|
|
49
|
+
};
|
|
50
|
+
// Create payload without signature (signature goes in JWT signature section)
|
|
51
|
+
const payload = {
|
|
52
|
+
sub: authData.walletAddress,
|
|
53
|
+
iss: 'accounts.atxp.ai',
|
|
54
|
+
aud: 'https://auth.atxp.ai',
|
|
55
|
+
iat: authData.timestamp,
|
|
56
|
+
exp: authData.timestamp + 3600, // 1 hour expiration
|
|
57
|
+
msg: authData.message,
|
|
58
|
+
...(authData.code_challenge && { code_challenge: authData.code_challenge }),
|
|
59
|
+
...(authData.payment_request_id && { payment_request_id: authData.payment_request_id })
|
|
60
|
+
};
|
|
61
|
+
// Encode header and payload
|
|
62
|
+
const encodedHeader = toBase64Url(JSON.stringify(header));
|
|
63
|
+
const encodedPayload = toBase64Url(JSON.stringify(payload));
|
|
64
|
+
// EIP-1271 signature goes in JWT signature section
|
|
65
|
+
const encodedSignature = toBase64Url(authData.signature);
|
|
66
|
+
// Return JWT format: header.payload.signature
|
|
67
|
+
return `${encodedHeader}.${encodedPayload}.${encodedSignature}`;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Create auth data structure from signing parameters
|
|
71
|
+
*/
|
|
72
|
+
function createEIP1271AuthData({ walletAddress, message, signature, timestamp, nonce, codeChallenge, paymentRequestId }) {
|
|
73
|
+
return {
|
|
74
|
+
type: 'EIP1271_AUTH',
|
|
75
|
+
walletAddress,
|
|
76
|
+
message,
|
|
77
|
+
signature,
|
|
78
|
+
timestamp,
|
|
79
|
+
...(nonce && { nonce }),
|
|
80
|
+
...(codeChallenge && { code_challenge: codeChallenge }),
|
|
81
|
+
...(paymentRequestId && { payment_request_id: paymentRequestId })
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Construct the standardized message format for EIP-1271 signing
|
|
86
|
+
*/
|
|
87
|
+
function constructEIP1271Message({ walletAddress, timestamp, nonce, codeChallenge, paymentRequestId }) {
|
|
88
|
+
const messageParts = [
|
|
89
|
+
`PayMCP Authorization Request`,
|
|
90
|
+
``,
|
|
91
|
+
`Wallet: ${walletAddress}`,
|
|
92
|
+
`Timestamp: ${timestamp}`
|
|
93
|
+
];
|
|
94
|
+
if (nonce !== undefined && nonce !== null) {
|
|
95
|
+
messageParts.push(`Nonce: ${nonce}`);
|
|
96
|
+
}
|
|
97
|
+
if (codeChallenge) {
|
|
98
|
+
messageParts.push(`Code Challenge: ${codeChallenge}`);
|
|
99
|
+
}
|
|
100
|
+
if (paymentRequestId) {
|
|
101
|
+
messageParts.push(`Payment Request ID: ${paymentRequestId}`);
|
|
102
|
+
}
|
|
103
|
+
messageParts.push('', '', 'Sign this message to prove you control this wallet.');
|
|
104
|
+
return messageParts.join('\n');
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const USDC_DECIMALS$1 = 6;
|
|
108
|
+
// Minimal ERC20 ABI for transfer function
|
|
109
|
+
const ERC20_ABI = [
|
|
110
|
+
{
|
|
111
|
+
inputs: [
|
|
112
|
+
{ name: 'to', type: 'address' },
|
|
113
|
+
{ name: 'amount', type: 'uint256' }
|
|
114
|
+
],
|
|
115
|
+
name: 'transfer',
|
|
116
|
+
outputs: [{ name: '', type: 'bool' }],
|
|
117
|
+
stateMutability: 'nonpayable',
|
|
118
|
+
type: 'function'
|
|
119
|
+
}
|
|
120
|
+
];
|
|
121
|
+
async function waitForTransactionConfirmations(smartWallet, txHash, confirmations, logger) {
|
|
122
|
+
try {
|
|
123
|
+
const publicClient = smartWallet.client.account?.client;
|
|
124
|
+
if (publicClient && 'waitForTransactionReceipt' in publicClient) {
|
|
125
|
+
logger.info(`Waiting for ${confirmations} confirmations...`);
|
|
126
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
127
|
+
await publicClient.waitForTransactionReceipt({
|
|
128
|
+
hash: txHash,
|
|
129
|
+
confirmations: confirmations
|
|
130
|
+
});
|
|
131
|
+
logger.info(`Transaction confirmed with ${confirmations} confirmations`);
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
logger.warn('Unable to wait for confirmations: client does not support waitForTransactionReceipt');
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
logger.warn(`Could not wait for additional confirmations: ${error}`);
|
|
139
|
+
// Continue anyway - the transaction is already mined
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
class BaseAppPaymentMaker {
|
|
143
|
+
constructor(spendPermission, smartWallet, logger) {
|
|
144
|
+
if (!spendPermission) {
|
|
145
|
+
throw new Error('Spend permission is required');
|
|
146
|
+
}
|
|
147
|
+
if (!smartWallet) {
|
|
148
|
+
throw new Error('Smart wallet is required');
|
|
149
|
+
}
|
|
150
|
+
this.logger = logger ?? new ConsoleLogger();
|
|
151
|
+
this.spendPermission = spendPermission;
|
|
152
|
+
this.smartWallet = smartWallet;
|
|
153
|
+
}
|
|
154
|
+
async generateJWT({ paymentRequestId, codeChallenge }) {
|
|
155
|
+
// Generate EIP-1271 auth data for smart wallet authentication
|
|
156
|
+
const timestamp = Math.floor(Date.now() / 1000);
|
|
157
|
+
const message = constructEIP1271Message({
|
|
158
|
+
walletAddress: this.smartWallet.account.address,
|
|
159
|
+
timestamp,
|
|
160
|
+
codeChallenge,
|
|
161
|
+
paymentRequestId
|
|
162
|
+
});
|
|
163
|
+
// Sign the message - this will return an ABI-encoded signature from the smart wallet
|
|
164
|
+
const signature = await this.smartWallet.account.signMessage({
|
|
165
|
+
message: message
|
|
166
|
+
});
|
|
167
|
+
const authData = createEIP1271AuthData({
|
|
168
|
+
walletAddress: this.smartWallet.account.address,
|
|
169
|
+
message,
|
|
170
|
+
signature,
|
|
171
|
+
timestamp,
|
|
172
|
+
codeChallenge,
|
|
173
|
+
paymentRequestId
|
|
174
|
+
});
|
|
175
|
+
const jwtToken = createEIP1271JWT(authData);
|
|
176
|
+
this.logger.info(`codeChallenge: ${codeChallenge}`);
|
|
177
|
+
this.logger.info(`paymentRequestId: ${paymentRequestId}`);
|
|
178
|
+
this.logger.info(`walletAddress: ${this.smartWallet.account.address}`);
|
|
179
|
+
this.logger.info(`Generated EIP-1271 JWT: ${jwtToken}`);
|
|
180
|
+
return jwtToken;
|
|
181
|
+
}
|
|
182
|
+
async makePayment(amount, currency, receiver, memo) {
|
|
183
|
+
if (currency !== 'USDC') {
|
|
184
|
+
throw new Error('Only usdc currency is supported; received ' + currency);
|
|
185
|
+
}
|
|
186
|
+
this.logger.info(`Making spendPermission payment of ${amount} ${currency} to ${receiver} on Base with memo: ${memo}`);
|
|
187
|
+
// Convert amount to USDC units (6 decimals) as BigInt for spendPermission
|
|
188
|
+
const amountInUSDCUnits = BigInt(amount.multipliedBy(10 ** USDC_DECIMALS$1).toFixed(0));
|
|
189
|
+
// Dynamically import prepareSpendCallData based on environment
|
|
190
|
+
const { prepareSpendCallData } = await getSpendPermissionModule();
|
|
191
|
+
const spendCalls = await prepareSpendCallData(this.spendPermission, amountInUSDCUnits);
|
|
192
|
+
// Add a second call to transfer USDC from the smart wallet to the receiver
|
|
193
|
+
let transferCallData = encodeFunctionData({
|
|
194
|
+
abi: ERC20_ABI,
|
|
195
|
+
functionName: "transfer",
|
|
196
|
+
args: [receiver, amountInUSDCUnits],
|
|
197
|
+
});
|
|
198
|
+
// Append memo to transfer call data if present
|
|
199
|
+
// This works because the EVM ignores extra calldata beyond what a function expects.
|
|
200
|
+
// The ERC20 transfer() function only reads the first 68 bytes (4-byte selector + 32-byte address + 32-byte amount).
|
|
201
|
+
// Any additional data appended after those 68 bytes is safely ignored by the USDC contract
|
|
202
|
+
// but remains accessible in the transaction data for payment verification.
|
|
203
|
+
// This is a well-established pattern used by OpenSea, Uniswap, and other major protocols.
|
|
204
|
+
if (memo && memo.trim()) {
|
|
205
|
+
const memoHex = Buffer.from(memo.trim(), 'utf8').toString('hex');
|
|
206
|
+
transferCallData = (transferCallData + memoHex);
|
|
207
|
+
this.logger.info(`Added memo "${memo.trim()}" to transfer call`);
|
|
208
|
+
}
|
|
209
|
+
const transferCall = {
|
|
210
|
+
to: USDC_CONTRACT_ADDRESS_BASE,
|
|
211
|
+
data: transferCallData,
|
|
212
|
+
value: '0x0'
|
|
213
|
+
};
|
|
214
|
+
// Combine spend permission calls with the transfer call
|
|
215
|
+
const allCalls = [...spendCalls, transferCall];
|
|
216
|
+
this.logger.info(`Executing ${allCalls.length} calls (${spendCalls.length} spend permission + 1 transfer)`);
|
|
217
|
+
const hash = await this.smartWallet.client.sendUserOperation({
|
|
218
|
+
account: this.smartWallet.account,
|
|
219
|
+
calls: allCalls.map(call => {
|
|
220
|
+
return {
|
|
221
|
+
to: call.to,
|
|
222
|
+
data: call.data,
|
|
223
|
+
value: BigInt(call.value || '0x0')
|
|
224
|
+
};
|
|
225
|
+
}),
|
|
226
|
+
maxPriorityFeePerGas: parseEther('0.000000001')
|
|
227
|
+
});
|
|
228
|
+
const receipt = await this.smartWallet.client.waitForUserOperationReceipt({ hash });
|
|
229
|
+
if (!receipt) {
|
|
230
|
+
throw new Error('User operation failed');
|
|
231
|
+
}
|
|
232
|
+
// The receipt contains the actual transaction hash that was mined on chain
|
|
233
|
+
const txHash = receipt.receipt.transactionHash;
|
|
234
|
+
if (!txHash) {
|
|
235
|
+
throw new Error('User operation was executed but no transaction hash was returned. This should not happen.');
|
|
236
|
+
}
|
|
237
|
+
this.logger.info(`Spend permission executed successfully. UserOp: ${receipt.userOpHash}, TxHash: ${txHash}`);
|
|
238
|
+
// Wait for additional confirmations to ensure the transaction is well-propagated
|
|
239
|
+
// This helps avoid the "Transaction receipt could not be found" error
|
|
240
|
+
await waitForTransactionConfirmations(this.smartWallet, txHash, 2, this.logger);
|
|
241
|
+
// Return the actual transaction hash, not the user operation hash
|
|
242
|
+
// The payment verification system needs the on-chain transaction hash
|
|
243
|
+
return txHash;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
const USDC_DECIMALS = 6;
|
|
248
|
+
class MainWalletPaymentMaker {
|
|
249
|
+
constructor(walletAddress, provider, logger) {
|
|
250
|
+
this.walletAddress = walletAddress;
|
|
251
|
+
this.provider = provider;
|
|
252
|
+
this.logger = logger || new ConsoleLogger();
|
|
253
|
+
}
|
|
254
|
+
async generateJWT(payload) {
|
|
255
|
+
this.logger.info(`codeChallenge: ${payload.codeChallenge}`);
|
|
256
|
+
this.logger.info(`paymentRequestId: ${payload.paymentRequestId}`);
|
|
257
|
+
this.logger.info(`walletAddress: ${this.walletAddress}`);
|
|
258
|
+
// Generate EIP-1271 auth data for main wallet authentication
|
|
259
|
+
const timestamp = Math.floor(Date.now() / 1000);
|
|
260
|
+
const message = constructEIP1271Message({
|
|
261
|
+
walletAddress: this.walletAddress,
|
|
262
|
+
timestamp,
|
|
263
|
+
codeChallenge: payload.codeChallenge,
|
|
264
|
+
paymentRequestId: payload.paymentRequestId
|
|
265
|
+
});
|
|
266
|
+
// Sign with the main wallet
|
|
267
|
+
// Coinbase Wallet requires hex-encoded messages, while other wallets may accept plain strings
|
|
268
|
+
let messageToSign;
|
|
269
|
+
// Check if this is Coinbase Wallet by looking for provider properties
|
|
270
|
+
const providerWithCoinbase = this.provider;
|
|
271
|
+
const isCoinbaseWallet = providerWithCoinbase.isCoinbaseWallet ||
|
|
272
|
+
providerWithCoinbase.isCoinbaseBrowser;
|
|
273
|
+
if (isCoinbaseWallet) {
|
|
274
|
+
// Coinbase Wallet requires hex-encoded messages
|
|
275
|
+
messageToSign = toHex(message);
|
|
276
|
+
this.logger.info('Using hex-encoded message for Coinbase Wallet');
|
|
277
|
+
}
|
|
278
|
+
else {
|
|
279
|
+
// Other wallets (MetaMask, etc.) typically accept plain strings
|
|
280
|
+
messageToSign = message;
|
|
281
|
+
this.logger.info('Using plain string message for wallet');
|
|
282
|
+
}
|
|
283
|
+
const signature = await this.provider.request({
|
|
284
|
+
method: 'personal_sign',
|
|
285
|
+
params: [messageToSign, this.walletAddress]
|
|
286
|
+
});
|
|
287
|
+
const authData = createEIP1271AuthData({
|
|
288
|
+
walletAddress: this.walletAddress,
|
|
289
|
+
message,
|
|
290
|
+
signature,
|
|
291
|
+
timestamp,
|
|
292
|
+
codeChallenge: payload.codeChallenge,
|
|
293
|
+
paymentRequestId: payload.paymentRequestId
|
|
294
|
+
});
|
|
295
|
+
const jwtToken = createEIP1271JWT(authData);
|
|
296
|
+
this.logger.info(`Generated EIP-1271 JWT: ${jwtToken}`);
|
|
297
|
+
return jwtToken;
|
|
298
|
+
}
|
|
299
|
+
async makePayment(amount, currency, receiver, _reason) {
|
|
300
|
+
if (currency !== 'USDC') {
|
|
301
|
+
throw new Error('Only usdc currency is supported');
|
|
302
|
+
}
|
|
303
|
+
this.logger.info(`Making direct payment of ${amount} ${currency} to ${receiver} on Base`);
|
|
304
|
+
// Convert amount to USDC units (6 decimals)
|
|
305
|
+
const amountInUSDCUnits = BigInt(amount.multipliedBy(10 ** USDC_DECIMALS).toFixed(0));
|
|
306
|
+
// Encode the transfer function data
|
|
307
|
+
const transferData = encodeFunctionData({
|
|
308
|
+
abi: [{
|
|
309
|
+
name: 'transfer',
|
|
310
|
+
type: 'function',
|
|
311
|
+
inputs: [
|
|
312
|
+
{ name: 'to', type: 'address' },
|
|
313
|
+
{ name: 'amount', type: 'uint256' }
|
|
314
|
+
],
|
|
315
|
+
outputs: [{ name: '', type: 'bool' }]
|
|
316
|
+
}],
|
|
317
|
+
functionName: 'transfer',
|
|
318
|
+
args: [receiver, amountInUSDCUnits]
|
|
319
|
+
});
|
|
320
|
+
// Send the transaction through the user's wallet
|
|
321
|
+
const txHash = await this.provider.request({
|
|
322
|
+
method: 'eth_sendTransaction',
|
|
323
|
+
params: [{
|
|
324
|
+
from: this.walletAddress,
|
|
325
|
+
to: USDC_CONTRACT_ADDRESS_BASE,
|
|
326
|
+
data: transferData,
|
|
327
|
+
value: '0x0'
|
|
328
|
+
}]
|
|
329
|
+
});
|
|
330
|
+
this.logger.info(`Transaction submitted. TxHash: ${txHash}`);
|
|
331
|
+
// Wait for confirmations
|
|
332
|
+
const CONFIRMATIONS = 2;
|
|
333
|
+
await this.waitForTransactionConfirmations(txHash, CONFIRMATIONS);
|
|
334
|
+
return txHash;
|
|
335
|
+
}
|
|
336
|
+
async waitForTransactionConfirmations(txHash, confirmations) {
|
|
337
|
+
this.logger.info(`Waiting for ${confirmations} confirmations...`);
|
|
338
|
+
// Poll for transaction receipt
|
|
339
|
+
let receipt = null;
|
|
340
|
+
while (!receipt) {
|
|
341
|
+
try {
|
|
342
|
+
receipt = await this.provider.request({
|
|
343
|
+
method: 'eth_getTransactionReceipt',
|
|
344
|
+
params: [txHash]
|
|
345
|
+
});
|
|
346
|
+
if (!receipt) {
|
|
347
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
catch (error) {
|
|
351
|
+
this.logger.warn(`Error getting receipt: ${error}`);
|
|
352
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
// Check if transaction was successful
|
|
356
|
+
if (receipt.status === '0x0') {
|
|
357
|
+
throw new Error(`Transaction failed. TxHash: ${txHash}`);
|
|
358
|
+
}
|
|
359
|
+
// Wait for confirmations
|
|
360
|
+
const startBlock = parseInt(receipt.blockNumber, 16);
|
|
361
|
+
let currentBlock = startBlock;
|
|
362
|
+
while (currentBlock - startBlock < confirmations - 1) {
|
|
363
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
364
|
+
const blockNumber = await this.provider.request({
|
|
365
|
+
method: 'eth_blockNumber',
|
|
366
|
+
params: []
|
|
367
|
+
});
|
|
368
|
+
currentBlock = parseInt(blockNumber, 16);
|
|
369
|
+
}
|
|
370
|
+
this.logger.info(`Transaction confirmed with ${confirmations} confirmations`);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* Type-safe storage wrapper for permission data
|
|
376
|
+
*/
|
|
377
|
+
class IntermediaryStorage {
|
|
378
|
+
constructor(storage) {
|
|
379
|
+
this.storage = storage;
|
|
380
|
+
}
|
|
381
|
+
get(key) {
|
|
382
|
+
const data = this.storage.get(key);
|
|
383
|
+
if (!data)
|
|
384
|
+
return null;
|
|
385
|
+
try {
|
|
386
|
+
const parsed = JSON.parse(data);
|
|
387
|
+
return parsed;
|
|
388
|
+
}
|
|
389
|
+
catch {
|
|
390
|
+
return null;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
set(key, data) {
|
|
394
|
+
this.storage.set(key, JSON.stringify(data));
|
|
395
|
+
}
|
|
396
|
+
delete(key) {
|
|
397
|
+
this.storage.delete(key);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* Browser localStorage implementation
|
|
402
|
+
*/
|
|
403
|
+
class BrowserStorage {
|
|
404
|
+
isAvailable() {
|
|
405
|
+
return typeof window !== 'undefined' && typeof window.localStorage !== 'undefined';
|
|
406
|
+
}
|
|
407
|
+
get(key) {
|
|
408
|
+
if (!this.isAvailable())
|
|
409
|
+
return null;
|
|
410
|
+
return localStorage.getItem(key);
|
|
411
|
+
}
|
|
412
|
+
set(key, value) {
|
|
413
|
+
if (!this.isAvailable())
|
|
414
|
+
return;
|
|
415
|
+
localStorage.setItem(key, value);
|
|
416
|
+
}
|
|
417
|
+
delete(key) {
|
|
418
|
+
if (!this.isAvailable())
|
|
419
|
+
return;
|
|
420
|
+
localStorage.removeItem(key);
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
/**
|
|
424
|
+
* In-memory storage implementation for testing
|
|
425
|
+
*/
|
|
426
|
+
class MemoryStorage {
|
|
427
|
+
constructor() {
|
|
428
|
+
this.store = new Map();
|
|
429
|
+
}
|
|
430
|
+
get(key) {
|
|
431
|
+
return this.store.get(key) || null;
|
|
432
|
+
}
|
|
433
|
+
set(key, value) {
|
|
434
|
+
this.store.set(key, value);
|
|
435
|
+
}
|
|
436
|
+
delete(key) {
|
|
437
|
+
this.store.delete(key);
|
|
438
|
+
}
|
|
439
|
+
clear() {
|
|
440
|
+
this.store.clear();
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
// Coinbase CDP Paymaster and Bundler endpoints
|
|
445
|
+
const COINBASE_BUNDLER_URL = 'https://api.developer.coinbase.com/rpc/v1/base';
|
|
446
|
+
const COINBASE_PAYMASTER_URL = 'https://api.developer.coinbase.com/rpc/v1/base';
|
|
447
|
+
/**
|
|
448
|
+
* Creates an ephemeral smart wallet with paymaster support
|
|
449
|
+
*/
|
|
450
|
+
async function toEphemeralSmartWallet(privateKey, apiKey) {
|
|
451
|
+
const signer = privateKeyToAccount(privateKey);
|
|
452
|
+
const publicClient = createPublicClient({
|
|
453
|
+
chain: base,
|
|
454
|
+
transport: http(`${COINBASE_BUNDLER_URL}/${apiKey}`)
|
|
455
|
+
});
|
|
456
|
+
// Create the Coinbase smart wallet
|
|
457
|
+
const account = await toCoinbaseSmartAccount({
|
|
458
|
+
client: publicClient,
|
|
459
|
+
owners: [signer],
|
|
460
|
+
version: '1'
|
|
461
|
+
});
|
|
462
|
+
// Create bundler client with paymaster support
|
|
463
|
+
const bundlerClient = createBundlerClient({
|
|
464
|
+
account,
|
|
465
|
+
client: publicClient,
|
|
466
|
+
transport: http(`${COINBASE_BUNDLER_URL}/${apiKey}`),
|
|
467
|
+
chain: base,
|
|
468
|
+
paymaster: true, // Enable paymaster sponsorship
|
|
469
|
+
paymasterContext: {
|
|
470
|
+
transport: http(`${COINBASE_PAYMASTER_URL}/${apiKey}`)
|
|
471
|
+
}
|
|
472
|
+
});
|
|
473
|
+
return {
|
|
474
|
+
address: account.address,
|
|
475
|
+
client: bundlerClient,
|
|
476
|
+
account,
|
|
477
|
+
signer,
|
|
478
|
+
};
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
const DEFAULT_ALLOWANCE = 10n;
|
|
482
|
+
const DEFAULT_PERIOD_IN_DAYS = 7;
|
|
483
|
+
const PAYMASTER_URL = 'https://api.developer.coinbase.com/rpc/v1/base/snPdXqIzOGhRkGNJvEHM5bl9Hm3yRO3m';
|
|
484
|
+
class BaseAppAccount {
|
|
485
|
+
static toStorageKey(userWalletAddress) {
|
|
486
|
+
return `atxp-base-permission-${userWalletAddress}`;
|
|
487
|
+
}
|
|
488
|
+
static async initialize(config) {
|
|
489
|
+
const logger = config.logger || new ConsoleLogger();
|
|
490
|
+
const useEphemeralWallet = config.useEphemeralWallet ?? true; // Default to true for backward compatibility
|
|
491
|
+
// Initialize Base SDK
|
|
492
|
+
const sdk = createBaseAccountSDK({
|
|
493
|
+
appName: config?.appName,
|
|
494
|
+
appChainIds: [base.id],
|
|
495
|
+
paymasterUrls: {
|
|
496
|
+
[base.id]: PAYMASTER_URL
|
|
497
|
+
}
|
|
498
|
+
});
|
|
499
|
+
const provider = sdk.getProvider();
|
|
500
|
+
// Some wallets don't support wallet_connect, so
|
|
501
|
+
// will just continue if it fails
|
|
502
|
+
try {
|
|
503
|
+
await provider.request({ method: 'wallet_connect' });
|
|
504
|
+
}
|
|
505
|
+
catch (error) {
|
|
506
|
+
// Continue if wallet_connect is not supported
|
|
507
|
+
logger.warn(`wallet_connect not supported, continuing with initialization. ${error}`);
|
|
508
|
+
}
|
|
509
|
+
// If using main wallet mode, return early with main wallet payment maker
|
|
510
|
+
if (!useEphemeralWallet) {
|
|
511
|
+
logger.info(`Using main wallet mode for address: ${config.walletAddress}`);
|
|
512
|
+
return new BaseAppAccount(null, // No spend permission in main wallet mode
|
|
513
|
+
null, // No ephemeral wallet in main wallet mode
|
|
514
|
+
logger, config.walletAddress, provider);
|
|
515
|
+
}
|
|
516
|
+
// Validate smart wallet configuration for ephemeral mode
|
|
517
|
+
if (!config.apiKey) {
|
|
518
|
+
throw new Error('Smart wallet API key is required for ephemeral wallet mode. ' +
|
|
519
|
+
'Get your API key from https://portal.cdp.coinbase.com/');
|
|
520
|
+
}
|
|
521
|
+
// Initialize storage
|
|
522
|
+
const baseStorage = config?.storage || new BrowserStorage();
|
|
523
|
+
const storage = new IntermediaryStorage(baseStorage);
|
|
524
|
+
const storageKey = this.toStorageKey(config.walletAddress);
|
|
525
|
+
// Try to load existing permission
|
|
526
|
+
const existingData = this.loadSavedWalletAndPermission(storage, storageKey);
|
|
527
|
+
if (existingData) {
|
|
528
|
+
const ephemeralSmartWallet = await toEphemeralSmartWallet(existingData.privateKey, config.apiKey);
|
|
529
|
+
return new BaseAppAccount(existingData.permission, ephemeralSmartWallet, logger);
|
|
530
|
+
}
|
|
531
|
+
const privateKey = generatePrivateKey();
|
|
532
|
+
const smartWallet = await toEphemeralSmartWallet(privateKey, config.apiKey);
|
|
533
|
+
logger.info(`Generated ephemeral wallet: ${smartWallet.address}`);
|
|
534
|
+
await this.deploySmartWallet(smartWallet);
|
|
535
|
+
logger.info(`Deployed smart wallet: ${smartWallet.address}`);
|
|
536
|
+
// Dynamically import requestSpendPermission based on environment
|
|
537
|
+
// This function requires browser APIs and wallet interaction
|
|
538
|
+
const { requestSpendPermission } = await getSpendPermissionModule();
|
|
539
|
+
const permission = await requestSpendPermission({
|
|
540
|
+
account: config.walletAddress,
|
|
541
|
+
spender: smartWallet.address,
|
|
542
|
+
token: USDC_CONTRACT_ADDRESS_BASE,
|
|
543
|
+
chainId: base.id,
|
|
544
|
+
allowance: config?.allowance ?? DEFAULT_ALLOWANCE,
|
|
545
|
+
periodInDays: config?.periodInDays ?? DEFAULT_PERIOD_IN_DAYS,
|
|
546
|
+
provider,
|
|
547
|
+
});
|
|
548
|
+
// Save wallet and permission
|
|
549
|
+
storage.set(storageKey, { privateKey, permission });
|
|
550
|
+
return new BaseAppAccount(permission, smartWallet, logger);
|
|
551
|
+
}
|
|
552
|
+
static loadSavedWalletAndPermission(permissionStorage, storageKey) {
|
|
553
|
+
const storedData = permissionStorage.get(storageKey);
|
|
554
|
+
if (!storedData)
|
|
555
|
+
return null;
|
|
556
|
+
// Check if permission is not expired
|
|
557
|
+
const now = Math.floor(Date.now() / 1000);
|
|
558
|
+
const permissionEnd = parseInt(storedData.permission.permission.end.toString());
|
|
559
|
+
if (permissionEnd <= now) {
|
|
560
|
+
permissionStorage.delete(storageKey);
|
|
561
|
+
return null;
|
|
562
|
+
}
|
|
563
|
+
return storedData;
|
|
564
|
+
}
|
|
565
|
+
static async deploySmartWallet(smartWallet) {
|
|
566
|
+
const deployTx = await smartWallet.client.sendUserOperation({
|
|
567
|
+
calls: [{
|
|
568
|
+
to: smartWallet.address,
|
|
569
|
+
value: 0n,
|
|
570
|
+
data: '0x'
|
|
571
|
+
}],
|
|
572
|
+
paymaster: true
|
|
573
|
+
});
|
|
574
|
+
const receipt = await smartWallet.client.waitForUserOperationReceipt({
|
|
575
|
+
hash: deployTx
|
|
576
|
+
});
|
|
577
|
+
if (!receipt.success) {
|
|
578
|
+
throw new Error(`Smart wallet deployment failed. Receipt: ${JSON.stringify(receipt)}`);
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
constructor(spendPermission, ephemeralSmartWallet, logger, mainWalletAddress, provider) {
|
|
582
|
+
if (ephemeralSmartWallet) {
|
|
583
|
+
// Ephemeral wallet mode
|
|
584
|
+
if (!spendPermission) {
|
|
585
|
+
throw new Error('Spend permission is required for ephemeral wallet mode');
|
|
586
|
+
}
|
|
587
|
+
this.accountId = ephemeralSmartWallet.address;
|
|
588
|
+
this.paymentMakers = {
|
|
589
|
+
'base': new BaseAppPaymentMaker(spendPermission, ephemeralSmartWallet, logger),
|
|
590
|
+
};
|
|
591
|
+
}
|
|
592
|
+
else {
|
|
593
|
+
// Main wallet mode
|
|
594
|
+
if (!mainWalletAddress || !provider) {
|
|
595
|
+
throw new Error('Main wallet address and provider are required for main wallet mode');
|
|
596
|
+
}
|
|
597
|
+
this.accountId = mainWalletAddress;
|
|
598
|
+
this.paymentMakers = {
|
|
599
|
+
'base': new MainWalletPaymentMaker(mainWalletAddress, provider, logger),
|
|
600
|
+
};
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
/**
|
|
604
|
+
* Dynamically import the appropriate spend-permission module based on environment.
|
|
605
|
+
* Uses browser version as requestSpendPermission only exists there.
|
|
606
|
+
* Throws error if used in server-side environment.
|
|
607
|
+
*/
|
|
608
|
+
static clearAllStoredData(userWalletAddress, storage) {
|
|
609
|
+
// In non-browser environments, require an explicit storage parameter
|
|
610
|
+
if (!storage) {
|
|
611
|
+
const browserStorage = new BrowserStorage();
|
|
612
|
+
// Check if BrowserStorage would work (i.e., we're in a browser)
|
|
613
|
+
if (typeof window === 'undefined') {
|
|
614
|
+
throw new Error('clearAllStoredData requires a storage to be provided outside of browser environments');
|
|
615
|
+
}
|
|
616
|
+
storage = browserStorage;
|
|
617
|
+
}
|
|
618
|
+
storage.delete(this.toStorageKey(userWalletAddress));
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
export { BaseAppAccount, BaseAppPaymentMaker, BrowserStorage, MainWalletPaymentMaker, MemoryStorage, IntermediaryStorage as PermissionStorage };
|
|
623
|
+
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,sBAAsB,EAA2B,MAAM,6BAA6B,CAAC;AAE9F,OAAO,EAGL,mBAAmB,IAAI,iBAAiB,EACxC,cAAc,EACd,aAAa,EACd,MAAM,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/spendPermissionUtils.ts","../src/eip1271JwtHelper.ts","../src/baseAppPaymentMaker.ts","../src/mainWalletPaymentMaker.ts","../src/storage.ts","../src/smartWalletHelpers.ts","../src/baseAppAccount.ts"],"sourcesContent":[null,null,null,null,null,null,null],"names":["USDC_DECIMALS"],"mappings":"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"}
|