@crossmint/client-sdk-smart-wallet 0.1.8 → 0.1.10

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/index.d.cts CHANGED
@@ -3,7 +3,7 @@ export { EVMBlockchainIncludingTestnet as Chain, blockchainToChainId } from '@cr
3
3
  import * as _crossmint_client_sdk_base from '@crossmint/client-sdk-base';
4
4
  import { BaseCrossmintService, APIErrorService, CrossmintSDKError, SmartWalletErrorCode } from '@crossmint/client-sdk-base';
5
5
  export { CrossmintSDKError, CrossmintServiceError, JWTDecryptionError, JWTExpiredError, JWTIdentifierError, JWTInvalidError, NotAuthorizedError, SmartWalletErrorCode, TransferError } from '@crossmint/client-sdk-base';
6
- import { LocalAccount, EIP1193Provider, HttpTransport, Chain, PublicClient } from 'viem';
6
+ import { LocalAccount, EIP1193Provider, HttpTransport, Chain, PublicClient, Abi, ContractFunctionName, ContractFunctionArgs, WriteContractParameters, Hex } from 'viem';
7
7
  import { SmartAccountClient, UserOperation } from 'permissionless';
8
8
  import { EntryPoint, GetEntryPointVersion } from 'permissionless/types/entrypoint';
9
9
  import { z } from 'zod';
@@ -225,7 +225,7 @@ declare const SmartWalletConfigSchema: z.ZodObject<{
225
225
  }>, "many">;
226
226
  smartContractWalletAddress: z.ZodOptional<z.ZodType<`0x${string}`, z.ZodTypeDef, `0x${string}`>>;
227
227
  }, "strip", z.ZodTypeAny, {
228
- kernelVersion: "0.3.1" | "0.3.0" | "0.2.4";
228
+ kernelVersion: "0.2.4" | "0.3.0" | "0.3.1";
229
229
  entryPointVersion: "v0.6" | "v0.7";
230
230
  userId: string;
231
231
  signers: {
@@ -247,7 +247,7 @@ declare const SmartWalletConfigSchema: z.ZodObject<{
247
247
  }[];
248
248
  smartContractWalletAddress?: `0x${string}` | undefined;
249
249
  }, {
250
- kernelVersion: "0.3.1" | "0.3.0" | "0.2.4";
250
+ kernelVersion: "0.2.4" | "0.3.0" | "0.3.1";
251
251
  entryPointVersion: "v0.6" | "v0.7";
252
252
  userId: string;
253
253
  signers: {
@@ -329,6 +329,17 @@ type NFTTransferType = {
329
329
  };
330
330
  type TransferType = ERC20TransferType | SFTTransferType | NFTTransferType;
331
331
 
332
+ interface SendTransactionOptions {
333
+ /**
334
+ * The number of confirmations to wait for before yielding the transaction hash.
335
+ */
336
+ confirmations: number;
337
+ /**
338
+ * The timeout in milliseconds to wait for a transaction to confirm before throwing an error.
339
+ */
340
+ transactionConfirmationTimeout: number;
341
+ }
342
+
332
343
  /**
333
344
  * Smart wallet interface for EVM chains enhanced with Crossmint capabilities.
334
345
  * Core functionality is exposed via [viem](https://viem.sh/) clients within the `client` property of the class.
@@ -351,6 +362,7 @@ declare class EVMSmartWallet {
351
362
  */
352
363
  public: PublicClient;
353
364
  };
365
+ private readonly sendTransactionService;
354
366
  constructor(crossmintService: CrossmintWalletService, accountClient: SmartWalletClient, publicClient: PublicClient<HttpTransport>, chain: SmartWalletChain, logger?: _crossmint_client_sdk_base.SDKLogger);
355
367
  /**
356
368
  * The address of the smart wallet.
@@ -364,6 +376,42 @@ declare class EVMSmartWallet {
364
376
  * @returns A list of NFTs owned by the wallet.
365
377
  */
366
378
  nfts(): Promise<any>;
379
+ /**
380
+ * Sends a contract call transaction and returns the hash of a confirmed transaction.
381
+ * @param address the address of the contract to be called
382
+ * @param abi the ABI of the contract - ***should be defined as a typed variable*** to enable type checking of the contract arguments, see https://viem.sh/docs/typescript#type-inference for guidance
383
+ * @param functionName the name of the smart contract function to be called
384
+ * @param args the arguments to be passed to the function
385
+ * @returns The transaction hash.
386
+ * @throws `SendTransactionError` if the transaction fails to send. Contains the error thrown by the viem client.
387
+ * @throws `SendTransactionExecutionRevertedError`, a subclass of `SendTransactionError` if the transaction fails due to a contract execution error.
388
+ *
389
+ * **Passing a typed ABI:**
390
+ * @example
391
+ * const abi = [{
392
+ * "inputs": [
393
+ * {
394
+ * "internalType": "address",
395
+ * "name": "recipient",
396
+ * "type": "address"
397
+ * },
398
+ * ],
399
+ * "name": "mintNFT",
400
+ * "outputs": [],
401
+ * "stateMutability": "nonpayable",
402
+ * "type": "function"
403
+ * }] as const;
404
+ *
405
+ * await wallet.executeContract({
406
+ * address: contractAddress,
407
+ * abi,
408
+ * functionName: "mintNFT",
409
+ * args: [recipientAddress],
410
+ * });
411
+ */
412
+ executeContract<const TAbi extends Abi | readonly unknown[], TFunctionName extends ContractFunctionName<TAbi, "nonpayable" | "payable"> = ContractFunctionName<TAbi, "nonpayable" | "payable">, TArgs extends ContractFunctionArgs<TAbi, "nonpayable" | "payable", TFunctionName> = ContractFunctionArgs<TAbi, "nonpayable" | "payable", TFunctionName>>({ address, abi, functionName, args, value, config, }: Omit<WriteContractParameters<TAbi, TFunctionName, TArgs>, "chain" | "account"> & {
413
+ config?: Partial<SendTransactionOptions>;
414
+ }): Promise<Hex>;
367
415
  }
368
416
 
369
417
  declare class SmartWalletError extends CrossmintSDKError {
package/dist/index.d.ts CHANGED
@@ -3,7 +3,7 @@ export { EVMBlockchainIncludingTestnet as Chain, blockchainToChainId } from '@cr
3
3
  import * as _crossmint_client_sdk_base from '@crossmint/client-sdk-base';
4
4
  import { BaseCrossmintService, APIErrorService, CrossmintSDKError, SmartWalletErrorCode } from '@crossmint/client-sdk-base';
5
5
  export { CrossmintSDKError, CrossmintServiceError, JWTDecryptionError, JWTExpiredError, JWTIdentifierError, JWTInvalidError, NotAuthorizedError, SmartWalletErrorCode, TransferError } from '@crossmint/client-sdk-base';
6
- import { LocalAccount, EIP1193Provider, HttpTransport, Chain, PublicClient } from 'viem';
6
+ import { LocalAccount, EIP1193Provider, HttpTransport, Chain, PublicClient, Abi, ContractFunctionName, ContractFunctionArgs, WriteContractParameters, Hex } from 'viem';
7
7
  import { SmartAccountClient, UserOperation } from 'permissionless';
8
8
  import { EntryPoint, GetEntryPointVersion } from 'permissionless/types/entrypoint';
9
9
  import { z } from 'zod';
@@ -225,7 +225,7 @@ declare const SmartWalletConfigSchema: z.ZodObject<{
225
225
  }>, "many">;
226
226
  smartContractWalletAddress: z.ZodOptional<z.ZodType<`0x${string}`, z.ZodTypeDef, `0x${string}`>>;
227
227
  }, "strip", z.ZodTypeAny, {
228
- kernelVersion: "0.3.1" | "0.3.0" | "0.2.4";
228
+ kernelVersion: "0.2.4" | "0.3.0" | "0.3.1";
229
229
  entryPointVersion: "v0.6" | "v0.7";
230
230
  userId: string;
231
231
  signers: {
@@ -247,7 +247,7 @@ declare const SmartWalletConfigSchema: z.ZodObject<{
247
247
  }[];
248
248
  smartContractWalletAddress?: `0x${string}` | undefined;
249
249
  }, {
250
- kernelVersion: "0.3.1" | "0.3.0" | "0.2.4";
250
+ kernelVersion: "0.2.4" | "0.3.0" | "0.3.1";
251
251
  entryPointVersion: "v0.6" | "v0.7";
252
252
  userId: string;
253
253
  signers: {
@@ -329,6 +329,17 @@ type NFTTransferType = {
329
329
  };
330
330
  type TransferType = ERC20TransferType | SFTTransferType | NFTTransferType;
331
331
 
332
+ interface SendTransactionOptions {
333
+ /**
334
+ * The number of confirmations to wait for before yielding the transaction hash.
335
+ */
336
+ confirmations: number;
337
+ /**
338
+ * The timeout in milliseconds to wait for a transaction to confirm before throwing an error.
339
+ */
340
+ transactionConfirmationTimeout: number;
341
+ }
342
+
332
343
  /**
333
344
  * Smart wallet interface for EVM chains enhanced with Crossmint capabilities.
334
345
  * Core functionality is exposed via [viem](https://viem.sh/) clients within the `client` property of the class.
@@ -351,6 +362,7 @@ declare class EVMSmartWallet {
351
362
  */
352
363
  public: PublicClient;
353
364
  };
365
+ private readonly sendTransactionService;
354
366
  constructor(crossmintService: CrossmintWalletService, accountClient: SmartWalletClient, publicClient: PublicClient<HttpTransport>, chain: SmartWalletChain, logger?: _crossmint_client_sdk_base.SDKLogger);
355
367
  /**
356
368
  * The address of the smart wallet.
@@ -364,6 +376,42 @@ declare class EVMSmartWallet {
364
376
  * @returns A list of NFTs owned by the wallet.
365
377
  */
366
378
  nfts(): Promise<any>;
379
+ /**
380
+ * Sends a contract call transaction and returns the hash of a confirmed transaction.
381
+ * @param address the address of the contract to be called
382
+ * @param abi the ABI of the contract - ***should be defined as a typed variable*** to enable type checking of the contract arguments, see https://viem.sh/docs/typescript#type-inference for guidance
383
+ * @param functionName the name of the smart contract function to be called
384
+ * @param args the arguments to be passed to the function
385
+ * @returns The transaction hash.
386
+ * @throws `SendTransactionError` if the transaction fails to send. Contains the error thrown by the viem client.
387
+ * @throws `SendTransactionExecutionRevertedError`, a subclass of `SendTransactionError` if the transaction fails due to a contract execution error.
388
+ *
389
+ * **Passing a typed ABI:**
390
+ * @example
391
+ * const abi = [{
392
+ * "inputs": [
393
+ * {
394
+ * "internalType": "address",
395
+ * "name": "recipient",
396
+ * "type": "address"
397
+ * },
398
+ * ],
399
+ * "name": "mintNFT",
400
+ * "outputs": [],
401
+ * "stateMutability": "nonpayable",
402
+ * "type": "function"
403
+ * }] as const;
404
+ *
405
+ * await wallet.executeContract({
406
+ * address: contractAddress,
407
+ * abi,
408
+ * functionName: "mintNFT",
409
+ * args: [recipientAddress],
410
+ * });
411
+ */
412
+ executeContract<const TAbi extends Abi | readonly unknown[], TFunctionName extends ContractFunctionName<TAbi, "nonpayable" | "payable"> = ContractFunctionName<TAbi, "nonpayable" | "payable">, TArgs extends ContractFunctionArgs<TAbi, "nonpayable" | "payable", TFunctionName> = ContractFunctionArgs<TAbi, "nonpayable" | "payable", TFunctionName>>({ address, abi, functionName, args, value, config, }: Omit<WriteContractParameters<TAbi, TFunctionName, TArgs>, "chain" | "account"> & {
413
+ config?: Partial<SendTransactionOptions>;
414
+ }): Promise<Hex>;
367
415
  }
368
416
 
369
417
  declare class SmartWalletError extends CrossmintSDKError {
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import{blockchainToChainId as Nn,EVMBlockchainIncludingTestnet as Un}from"@crossmint/common-sdk-base";import{isAddress as ae,publicActions as we}from"viem";import{TransferError as We}from"@crossmint/client-sdk-base";import{SDKLogger as ee,getBrowserLogger as Ae}from"@crossmint/client-sdk-base";var Z="ZeroDev";var k="SCW_SDK",I="0.1.0",R="2024-06-09",Q="https://rpc.zerodev.app/api/v2/bundler/";var F=["0.3.1","0.3.0","0.2.4"],H=["v0.6","v0.7"];var y=new ee(k),te=new ee(k,Ae(k,{onlyDatadog:!0}));import{erc20Abi as be,erc721Abi as xe}from"viem";var re=[{inputs:[{internalType:"string",name:"uri_",type:"string"}],stateMutability:"nonpayable",type:"constructor"},{anonymous:!1,inputs:[{indexed:!0,internalType:"address",name:"account",type:"address"},{indexed:!0,internalType:"address",name:"operator",type:"address"},{indexed:!1,internalType:"bool",name:"approved",type:"bool"}],name:"ApprovalForAll",type:"event"},{anonymous:!1,inputs:[{indexed:!0,internalType:"address",name:"operator",type:"address"},{indexed:!0,internalType:"address",name:"from",type:"address"},{indexed:!0,internalType:"address",name:"to",type:"address"},{indexed:!1,internalType:"uint256[]",name:"ids",type:"uint256[]"},{indexed:!1,internalType:"uint256[]",name:"values",type:"uint256[]"}],name:"TransferBatch",type:"event"},{anonymous:!1,inputs:[{indexed:!0,internalType:"address",name:"operator",type:"address"},{indexed:!0,internalType:"address",name:"from",type:"address"},{indexed:!0,internalType:"address",name:"to",type:"address"},{indexed:!1,internalType:"uint256",name:"id",type:"uint256"},{indexed:!1,internalType:"uint256",name:"value",type:"uint256"}],name:"TransferSingle",type:"event"},{anonymous:!1,inputs:[{indexed:!1,internalType:"string",name:"value",type:"string"},{indexed:!0,internalType:"uint256",name:"id",type:"uint256"}],name:"URI",type:"event"},{inputs:[{internalType:"address",name:"account",type:"address"},{internalType:"uint256",name:"id",type:"uint256"}],name:"balanceOf",outputs:[{internalType:"uint256",name:"",type:"uint256"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"address[]",name:"accounts",type:"address[]"},{internalType:"uint256[]",name:"ids",type:"uint256[]"}],name:"balanceOfBatch",outputs:[{internalType:"uint256[]",name:"",type:"uint256[]"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"address",name:"account",type:"address"},{internalType:"address",name:"operator",type:"address"}],name:"isApprovedForAll",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"address",name:"from",type:"address"},{internalType:"address",name:"to",type:"address"},{internalType:"uint256[]",name:"ids",type:"uint256[]"},{internalType:"uint256[]",name:"amounts",type:"uint256[]"},{internalType:"bytes",name:"data",type:"bytes"}],name:"safeBatchTransferFrom",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"address",name:"from",type:"address"},{internalType:"address",name:"to",type:"address"},{internalType:"uint256",name:"id",type:"uint256"},{internalType:"uint256",name:"amount",type:"uint256"},{internalType:"bytes",name:"data",type:"bytes"}],name:"safeTransferFrom",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"address",name:"operator",type:"address"},{internalType:"bool",name:"approved",type:"bool"}],name:"setApprovalForAll",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"bytes4",name:"interfaceId",type:"bytes4"}],name:"supportsInterface",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"uint256",name:"",type:"uint256"}],name:"uri",outputs:[{internalType:"string",name:"",type:"string"}],stateMutability:"view",type:"function"}];function ne({contract:r,config:e,from:t,to:n}){switch(e.token.type){case"ft":return{account:t,address:r,abi:be,functionName:"transfer",args:[n,e.amount]};case"sft":return{account:t,address:r,abi:re,functionName:"safeTransferFrom",args:[t.address,n,e.token.tokenId,e.quantity,"0x00"],tokenId:e.token.tokenId};case"nft":return{account:t,address:r,abi:xe,functionName:"safeTransferFrom",args:[t.address,n,e.token.tokenId],tokenId:e.token.tokenId}}}var E=class{constructor(e,t,n,a,o=y){this.crossmintService=e;this.accountClient=t;this.logger=o;this.chain=a,this.client={wallet:t,public:n}}get address(){return this.accountClient.account.address}async transferToken(e,t){return this.logger.logPerformance("TRANSFER",async()=>{if(this.chain!==t.token.chain)throw new Error(`Chain mismatch: Expected ${t.token.chain}, but got ${this.chain}. Ensure you are interacting with the correct blockchain.`);if(!ae(e))throw new Error(`Invalid recipient address: '${e}' is not a valid EVM address.`);if(!ae(t.token.contractAddress))throw new Error(`Invalid contract address: '${t.token.contractAddress}' is not a valid EVM address.`);let n=ne({contract:t.token.contractAddress,to:e,from:this.accountClient.account,config:t});try{let a=this.accountClient.extend(we),{request:o}=await a.simulateContract(n),s=await a.writeContract(o);return this.logger.log(`[TRANSFER] - Transaction hash from transfer: ${s}`),s}catch(a){this.logger.error("[TRANSFER] - ERROR_TRANSFERRING_TOKEN",{error:a instanceof Error?a.message:JSON.stringify(a),tokenId:n.tokenId,contractAddress:t.token.contractAddress,chain:t.token.chain});let o=n.tokenId==null?"":`:${n.tokenId}}`;throw new We(`Error transferring token ${t.token.contractAddress}${o}`)}},{toAddress:e,config:t})}async nfts(){return this.crossmintService.fetchNFTs(this.address,this.chain)}};import{CrossmintSDKError as ve,SmartWalletErrorCode as m}from"@crossmint/client-sdk-base";var l=class extends ve{constructor(e,t,n=m.UNCATEGORIZED){super(e,n,t)}},f=class extends l{constructor(e,t,n){super(e,m.ADMIN_MISMATCH),this.required=t,this.used=n}},A=class extends l{constructor(e,t,n){super(e,m.PASSKEY_MISMATCH),this.required=t,this.used=n}},T=class extends l{constructor(t){super(`The user with userId ${t.toString()} already has a wallet created for this project`);this.code=m.USER_WALLET_ALREADY_CREATED}},b=class extends l{constructor(e){super(`Prompt was either cancelled or timed out for passkey ${e}`,void 0,m.PASSKEY_PROMPT),this.passkeyName=e}},x=class extends l{constructor(e){super(`Registration for passkey ${e} failed, either the registration took too long, or passkey signature vaildation failed.`,void 0,m.PASSKEY_REGISTRATION),this.passkeyName=e}},w=class extends l{constructor(e){super(`User selected authenticator for passkey ${e} is not compatible with Crossmint's Smart Wallets.`,void 0,m.PASSKEY_INCOMPATIBLE_AUTHENTICATOR),this.passkeyName=e}},S=class extends l{constructor(e){super(e,void 0,m.WALLET_CONFIG)}},W=class extends S{constructor(){super("This signer was already used to create another wallet. Please use a different signer.");this.code=m.ADMIN_SIGNER_ALREADY_USED}},v=class extends S{constructor(){super("Smart wallets are not enabled for this project. They can be enabled on the project settings page in the developer console.");this.code=m.SMART_WALLETS_NOT_ENABLED}};import{SmartWalletErrorCode as Kn,CrossmintSDKError as $n,CrossmintServiceError as Bn,TransferError as Yn,JWTDecryptionError as Gn,JWTExpiredError as jn,JWTIdentifierError as Fn,JWTInvalidError as Hn,NotAuthorizedError as zn}from"@crossmint/client-sdk-base";import{stringify as vt}from"viem";import{validateAPIKey as kt}from"@crossmint/common-sdk-base";import{APIErrorService as Ve,BaseCrossmintService as Le,CrossmintServiceError as Ke}from"@crossmint/client-sdk-base";import{blockchainToChainId as $e}from"@crossmint/common-sdk-base";import{PasskeyValidatorContractVersion as ke}from"@zerodev/passkey-validator";import{isAddress as Ie,isHex as Re}from"viem";import{z as p}from"zod";var Oe=p.custom(r=>Re(r),{message:"Invalid hex string"}),O=p.custom(r=>Ie(r),{message:"Invalid evm address"}),_e=p.object({eoaAddress:O,type:p.literal("eoa")}),De=p.object({entryPoint:O,validatorAddress:O,pubKeyX:p.string(),pubKeyY:p.string(),authenticatorIdHash:Oe,authenticatorId:p.string()}),Ne=De.extend({passkeyName:p.string(),validatorContractVersion:p.nativeEnum(ke),domain:p.string(),type:p.literal("passkeys")}),Ue=p.discriminatedUnion("type",[Ne,_e]),_=p.object({kernelVersion:p.enum(F,{errorMap:(r,e)=>({message:`Unsupported kernel version. Supported versions: ${F.join(", ")}. Version used: ${e.data}. Please contact support`})}),entryPointVersion:p.enum(H,{errorMap:(r,e)=>({message:`Unsupported entry point version. Supported versions: ${H.join(", ")}. Version used: ${e.data}. Please contact support`})}),userId:p.string().min(1),signers:p.array(p.object({signerData:Ue})).min(0).max(1,"Invalid wallet signer configuration. Please contact support"),smartContractWalletAddress:O.optional()});import{toHex as Me}from"viem";function D(r,e){let t=e(r);return t.replace?t.value:Array.isArray(r)?r.map(n=>D(n,e)):r!==null&&typeof r=="object"?Object.fromEntries(Object.entries(r).map(([n,a])=>[n,D(a,e)])):t.value}function se(r){return D(r,e=>typeof e=="bigint"?{value:Me(e),replace:!0}:{value:e,replace:!1})}function oe(r){return D(r,e=>e!=null&&typeof e=="object"&&"__xm_serializedType"in e&&"value"in e&&e.__xm_serializedType==="bigint"&&typeof e.value=="string"?{value:BigInt(e.value),replace:!0}:{value:e,replace:!1})}var N=class extends Le{constructor(){super(...arguments);this.logger=y;this.apiErrorService=new Ve({ERROR_USER_WALLET_ALREADY_CREATED:({userId:t})=>new T(t),ERROR_ADMIN_SIGNER_ALREADY_USED:()=>new W,ERROR_PROJECT_NONCUSTODIAL_WALLETS_NOT_ENABLED:()=>new v})}async idempotentCreateSmartWallet(t,n){await this.fetchCrossmintAPI(`${R}/sdk/smart-wallet`,{method:"PUT",body:JSON.stringify(n)},"Error creating abstract wallet. Please contact support",t.jwt)}async sponsorUserOperation(t,n,a,o){let s=$e(o),i=await this.fetchCrossmintAPI(`${R}/sdk/paymaster`,{method:"POST",body:JSON.stringify({userOp:se(n),entryPoint:a,chainId:s})},"Error sponsoring user operation. Please contact support",t.jwt);return oe(i)}async getSmartWalletConfig(t,n){let a=await this.fetchCrossmintAPI(`${R}/sdk/smart-wallet/config?chain=${n}`,{method:"GET"},"Error getting smart wallet version configuration. Please contact support",t.jwt),o=_.safeParse(a);if(!o.success)throw new Ke(`Invalid smart wallet config, please contact support. Details below:
2
- ${o.error.toString()}`);return o.data}async fetchNFTs(t,n){return this.fetchCrossmintAPI(`v1-alpha1/wallets/${n}:${t}/nfts`,{method:"GET"},`Error fetching NFTs for wallet: ${t}`)}getPasskeyServerUrl(){return this.crossmintBaseUrl+"api/internal/passkeys"}};import{keccak256 as Be,toHex as Ye}from"viem";var U=class{constructor(e){this.keyPrefix=e}set(e,t){localStorage.setItem(this.key(e),JSON.stringify(t))}get(e){let t=this.key(e),n=localStorage.getItem(t);if(n==null)return null;let a=_.safeParse(JSON.parse(n));return a.success?a.data:(localStorage.removeItem(t),null)}clear(){for(let e=0;e<localStorage.length;e++){let t=localStorage.key(e);t&&t.startsWith(this.keyPrefix)&&(localStorage.removeItem(t),e--)}}key(e){return`${this.keyPrefix}-${Be(Ye(e.jwt))}`}};var h=class{constructor(e){this.type="passkeys";this.data=e}display(){return{pubKeyX:this.data.pubKeyX,pubKeyY:this.data.pubKeyY,passkeyName:this.data.passkeyName,type:this.type}}},P=class{constructor(e){this.type="eoa";this.data=e}display(){return this.data}};var M=class{constructor(e,t){this.crossmintService=e;this.configCache=t}async get(e,t){let n=this.configCache.get(e);if(n!=null)return{config:this.validateAndFormat(e,n),cached:!0};let a=await this.crossmintService.getSmartWalletConfig(e,t);return{config:this.validateAndFormat(e,a),cached:!1}}cache({entryPointVersion:e,kernelVersion:t,user:n,existing:a}){this.configCache.clear(),this.configCache.set(n,{entryPointVersion:e,kernelVersion:t,userId:n.id,signers:[{signerData:a.signerConfig.data}],smartContractWalletAddress:a.address})}validateAndFormat(e,{entryPointVersion:t,kernelVersion:n,signers:a,smartContractWalletAddress:o,userId:s}){if(t==="v0.7"&&n.startsWith("0.2")||t==="v0.6"&&n.startsWith("0.3"))throw new l(`Unsupported combination: entryPoint ${t} and kernel version ${n}. Please contact support`);let i=a.map(u=>u.signerData),c=this.getSigner(i);if(o!=null&&c==null||c!=null&&o==null)throw new l("Either both signer and address must be present, or both must be null");return c==null||o==null?{entryPointVersion:t,kernelVersion:n,userWithId:{...e,id:s}}:{entryPointVersion:t,kernelVersion:n,userWithId:{...e,id:s},existing:{signerConfig:c,address:o}}}getSigner(e){if(e.length===0)return;let t=e[0];if(t.type==="eoa")return new P(t);if(t.type==="passkeys")return new h(t)}};function z(r){return"signer"in r&&"type"in r.signer&&r.signer.type==="PASSKEY"}function ie(r){let e=r.existing==null||r.existing.signerConfig.type==="passkeys";return z(r.walletParams)&&e}function Ge(r){return"signer"in r&&("type"in r.signer&&r.signer.type==="VIEM_ACCOUNT"||"request"in r.signer&&typeof r.signer.request=="function")}function le(r){let e=r.existing==null||r.existing.signerConfig.type==="eoa";return Ge(r.walletParams)&&e}var V=class{constructor(e,t){this.eoaStrategy=e;this.passkeyStrategy=t}get(e){if(ie(e))return this.passkeyStrategy.create(e);if(le(e))return this.eoaStrategy.create(e);if(e.existing==null)throw new S(`Unsupported wallet params:
3
- ${e.walletParams}`);let t=e.existing.signerConfig.display(),n=z(e.walletParams)?"passkey":"eoa";throw new f(`Cannot create wallet with ${n} signer for user ${e.user.id}', they already have a wallet with signer:
4
- '${JSON.stringify(t,null,2)}'`,t)}};import{signerToEcdsaValidator as ze}from"@zerodev/ecdsa-validator";import{createKernelAccount as qe}from"@zerodev/sdk";function pe(r,e){return r?.toLowerCase()===e?.toLowerCase()}import{providerToSmartAccountSigner as je}from"permissionless";async function ce({walletParams:r}){if(Fe(r.signer))return await je(r.signer);if(He(r.signer))return r.signer.account;{let e=r.signer;throw new l(`The signer type ${e.type} is not supported`)}}function Fe(r){return r&&typeof r.request=="function"}function He(r){return r&&r.type==="VIEM_ACCOUNT"}var L=class{async create({chain:e,publicClient:t,entryPoint:n,walletParams:a,kernelVersion:o,user:s,existing:i}){let c=await ce({chain:e,walletParams:a});if(i!=null&&!pe(c.address,i.signerConfig.data.eoaAddress))throw new f(`User '${s.id}' has an existing wallet with an eoa signer '${i.signerConfig.data.eoaAddress}', this does not match input eoa signer '${c.address}'.`,i.signerConfig.display(),{type:"eoa",eoaAddress:i.signerConfig.data.eoaAddress});let u=await ze(t,{signer:c,entryPoint:n,kernelVersion:o});return{account:await qe(t,{plugins:{sudo:u},index:0n,entryPoint:n,kernelVersion:o,deployedAccountAddress:i?.address}),signerConfig:new P({eoaAddress:c.address,type:"eoa"})}}};import{PasskeyValidatorContractVersion as Je,WebAuthnMode as Xe,toPasskeyValidator as Ze}from"@zerodev/passkey-validator";import{createKernelAccount as Qe}from"@zerodev/sdk";import{toWebAuthnKey as et}from"@zerodev/webauthn-key";var K=class{constructor(e,t){this.passkeyServerUrl=e;this.apiKey=t}async create({user:e,publicClient:t,walletParams:n,entryPoint:a,kernelVersion:o,existing:s}){let i=n.signer.passkeyName??e.id;if(s!=null&&s.signerConfig.data.passkeyName!==i)throw new A(`User '${e.id}' has an existing wallet created with a passkey named '${s.signerConfig.data.passkeyName}', this does match input passkey name '${i}'.`,s.signerConfig.display());try{let c=await this.getPasskey(e,i,s?.signerConfig.data),u=Je.V0_0_2,d=s==null?u:s.signerConfig.data.validatorContractVersion,C=await Ze(t,{webAuthnKey:c,entryPoint:a,validatorContractVersion:d,kernelVersion:o}),j=await Qe(t,{plugins:{sudo:C},entryPoint:a,kernelVersion:o,deployedAccountAddress:s?.address});return{signerConfig:this.getSignerConfig(C,d,i),account:this.decorate(j,i)}}catch(c){throw this.mapError(c,i)}}async getPasskey(e,t,n){return n!=null?{pubX:BigInt(n.pubKeyX),pubY:BigInt(n.pubKeyY),authenticatorId:n.authenticatorId,authenticatorIdHash:n.authenticatorIdHash}:et({passkeyName:t,passkeyServerUrl:this.passkeyServerUrl,mode:Xe.Register,passkeyServerHeaders:this.createPasskeysServerHeaders(e)})}getSignerConfig(e,t,n){return new h({...nt(e.getSerializedData()),passkeyName:n,validatorContractVersion:t,domain:window.location.hostname,type:"passkeys"})}createPasskeysServerHeaders(e){return{"x-api-key":this.apiKey,Authorization:`Bearer ${e.jwt}`}}mapError(e,t){return e.code===0&&e.name==="DataError"?new w(t):e.message==="Registration not verified"?new x(t):e.code==="ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY"&&e.name==="NotAllowedError"?new b(t):e}decorate(e,t){return new Proxy(e,{get:(n,a,o)=>{let s=Reflect.get(n,a,o);return typeof s!="function"||typeof a!="string"||!rt(a)?s:async(...i)=>{try{return await s.call(n,...i)}catch(c){throw this.mapError(c,t)}}}})}},tt=["signMessage","signTypedData","signUserOperation","signTransaction"];function rt(r){return tt.includes(r)}var nt=r=>{let e=at(r),t=new TextDecoder().decode(e);return JSON.parse(t)};function at(r){let e=atob(r);return Uint8Array.from(e,t=>t.codePointAt(0))}import{stringify as me}from"viem";function $(r){return!1}var st=["sendTransaction","writeContract","sendUserOperation"],ot=["signMessage","signTypedData"];function q(r){return st.includes(r)}function it(r){return ot.includes(r)}var B=class{constructor(e,t=y){this.errorProcessor=e;this.logger=t}decorate({crossmintChain:e,smartAccountClient:t}){return new Proxy(t,{get:(n,a,o)=>{let s=Reflect.get(n,a,o);return typeof s!="function"||typeof a!="string"||!(it(a)||q(a))?s:(...i)=>this.logger.logPerformance(`CrossmintSmartWallet.${a}`,()=>this.execute(n,a,s,i,e))}})}async execute(e,t,n,a,o){try{this.logger.log(`[CrossmintSmartWallet.${t}] - params: ${me(a)}`);let s=q(t)?this.processTxnArgs(t,o,a):a;return await n.call(e,...s)}catch(s){let i=q(t)?"signing":"sending transaction";throw this.errorProcessor.map(s,new l(`Error ${i}: ${s.message}`,me(s)))}}processTxnArgs(e,t,n){if(e==="sendUserOperation"){let[{userOperation:o,middleware:s,account:i}]=n;return[{middleware:s,account:i,userOperation:this.addGelatoBundlerProperties(t,o)},...n.slice(1)]}let[a]=n;return[this.addGelatoBundlerProperties(t,a),...n.slice(1)]}addGelatoBundlerProperties(e,t){return $(e)?{...t,maxFeePerGas:"0x0",maxPriorityFeePerGas:"0x0"}:t}};import{createKernelAccountClient as Et}from"@zerodev/sdk";import{ENTRYPOINT_ADDRESS_V06 as At,ENTRYPOINT_ADDRESS_V07 as Tt}from"permissionless";import{createPublicClient as bt,http as Pe}from"viem";import{blockchainToChainId as xt}from"@crossmint/common-sdk-base";import{arbitrum as lt,arbitrumSepolia as pt,base as ct,baseSepolia as mt,optimism as dt,optimismSepolia as ut,polygon as yt,polygonAmoy as gt}from"viem/chains";import{BlockchainIncludingTestnet as g,objectValues as J}from"@crossmint/common-sdk-base";var de={BASE_SEPOLIA:g.BASE_SEPOLIA,POLYGON_AMOY:g.POLYGON_AMOY,OPTIMISM_SEPOLIA:g.OPTIMISM_SEPOLIA,ARBITRUM_SEPOLIA:g.ARBITRUM_SEPOLIA},zr=J(de),ue={BASE:g.BASE,POLYGON:g.POLYGON,OPTIMISM:g.OPTIMISM,ARBITRUM:g.ARBITRUM},qr=J(ue),ft={...de,...ue},Jr=J(ft),St={polygon:"5c9f4865-ca8e-44bb-9b9e-3810b2b46f9f","polygon-amoy":"3deef404-ca06-4a5d-9a58-907c99e7ef00","base-sepolia":"5a127978-6473-4784-9dfb-f74395b220a6",base:"e8b3020f-4dde-4176-8a7d-be8102527a5c","optimism-sepolia":"f8dd488e-eaed-467d-a5de-0184c160f3b1",optimism:"505950ab-ee07-4a9c-bd16-320ac71a9350",arbitrum:"a965100f-fedf-4e6b-a207-20f5687fcc4f","arbitrum-sepolia":"76c860ca-af77-4fb1-8eac-07825952f6f4"},ye={polygon:yt,"polygon-amoy":gt,base:ct,"base-sepolia":mt,optimism:dt,"optimism-sepolia":ut,arbitrum:lt,"arbitrum-sepolia":pt};function ge(r){return Q+St[r]}var ht="-7M6vRDBDknwvMxnqah_jbcieWg0qad9",Pt={polygon:"polygon-mainnet","polygon-amoy":"polygon-amoy",base:"base-mainnet","base-sepolia":"base-sepolia",optimism:"opt-mainnet","optimism-sepolia":"opt-sepolia",arbitrum:"arb-mainnet","arbitrum-sepolia":"arb-sepolia"};function fe(r){return`https://${Pt[r]}.g.alchemy.com/v2/${ht}`}function Se(r){return!$(r)}function he({entryPoint:r,chain:e,walletService:t,user:n}){return{middleware:{sponsorUserOperation:async({userOperation:a})=>{let{sponsorUserOpParams:o}=await t.sponsorUserOperation(n,a,r,e);return o}}}}var Y=class{constructor(e,t,n,a){this.crossmintService=e;this.accountConfigService=t;this.accountCreator=n;this.clientDecorator=a}async getOrCreate(e,t,n){let{config:{entryPointVersion:a,kernelVersion:o,existing:s,userWithId:i},cached:c}=await this.accountConfigService.get(e,t),u=bt({transport:Pe(fe(t))}),{account:d,signerConfig:C}=await this.accountCreator.get({chain:t,walletParams:n,publicClient:u,user:i,entryPoint:a==="v0.6"?At:Tt,kernelVersion:o,existing:s});s==null&&await this.crossmintService.idempotentCreateSmartWallet(e,{type:Z,smartContractWalletAddress:d.address,signerData:C.data,version:0,baseLayer:"evm",chainId:xt(t),entryPointVersion:a,kernelVersion:o}),c||this.accountConfigService.cache({entryPointVersion:a,kernelVersion:o,user:i,existing:{address:d.address,signerConfig:C}});let j=Et({account:d,chain:ye[t],entryPoint:d.entryPoint,bundlerTransport:Pe(ge(t)),...Se(t)&&he({entryPoint:d.entryPoint,chain:t,walletService:this.crossmintService,user:e})}),Ee=this.clientDecorator.decorate({crossmintChain:t,smartAccountClient:j});return new E(this.crossmintService,Ee,u,t)}};import{BaseError as wt,stringify as Wt}from"viem";var G=class{constructor(e){this.logger=e}map(e,t){return this.record(e),e instanceof l||e instanceof wt?e:t}record(e){let t=e instanceof Error?e.message:String(e);this.logger.error(`Smart Wallet SDK Error: ${t}`,{stack:e instanceof Error?e.stack:void 0,name:e instanceof Error?e.name:"UnknownError",details:Wt(e),domain:window.location.hostname,sdk_version:I})}};function Ce(){return typeof window<"u"}var X=class r{constructor(e,t,n=y){this.smartWalletService=e;this.errorProcessor=t;this.logger=n}static init({clientApiKey:e}){if(!Ce())throw new l("Smart Wallet SDK should only be used client side.");if(!kt(e).isValid)throw new Error("API key invalid");let n=new N(e),a=new G(te),o=new V(new L,new K(n.getPasskeyServerUrl(),e)),s=new U(`smart-wallet-${I}`),i=new Y(n,new M(n,s),o,new B(a));return new r(i,a)}async getOrCreateWallet(e,t,n={signer:{type:"PASSKEY"}}){return this.logger.logPerformance("GET_OR_CREATE_WALLET",async()=>{try{return await this.smartWalletService.getOrCreate(e,t,n)}catch(a){throw this.errorProcessor.map(a,new l(`Wallet creation failed: ${a.message}.`,vt(a)))}})}};export{W as AdminAlreadyUsedError,f as AdminMismatchError,Un as Chain,S as ConfigError,$n as CrossmintSDKError,Bn as CrossmintServiceError,E as EVMSmartWallet,Gn as JWTDecryptionError,jn as JWTExpiredError,Fn as JWTIdentifierError,Hn as JWTInvalidError,zn as NotAuthorizedError,w as PasskeyIncompatibleAuthenticatorError,A as PasskeyMismatchError,b as PasskeyPromptError,x as PasskeyRegistrationError,l as SmartWalletError,Kn as SmartWalletErrorCode,X as SmartWalletSDK,v as SmartWalletsNotEnabledError,Yn as TransferError,T as UserWalletAlreadyCreatedError,Nn as blockchainToChainId};
1
+ import{blockchainToChainId as Qn,EVMBlockchainIncludingTestnet as ea}from"@crossmint/common-sdk-base";import{isAddress as le,publicActions as Ie}from"viem";import{TransferError as Re}from"@crossmint/client-sdk-base";import{SDKLogger as ne,getBrowserLogger as xe}from"@crossmint/client-sdk-base";var re="ZeroDev";var O="SCW_SDK",I="0.1.0",R="2024-06-09",z=["0.3.1","0.3.0","0.2.4"],q=["v0.6","v0.7"];var u=new ne(O),ae=new ne(O,xe(O,{onlyDatadog:!0}));import{erc20Abi as We,erc721Abi as ke}from"viem";var ie=[{inputs:[{internalType:"string",name:"uri_",type:"string"}],stateMutability:"nonpayable",type:"constructor"},{anonymous:!1,inputs:[{indexed:!0,internalType:"address",name:"account",type:"address"},{indexed:!0,internalType:"address",name:"operator",type:"address"},{indexed:!1,internalType:"bool",name:"approved",type:"bool"}],name:"ApprovalForAll",type:"event"},{anonymous:!1,inputs:[{indexed:!0,internalType:"address",name:"operator",type:"address"},{indexed:!0,internalType:"address",name:"from",type:"address"},{indexed:!0,internalType:"address",name:"to",type:"address"},{indexed:!1,internalType:"uint256[]",name:"ids",type:"uint256[]"},{indexed:!1,internalType:"uint256[]",name:"values",type:"uint256[]"}],name:"TransferBatch",type:"event"},{anonymous:!1,inputs:[{indexed:!0,internalType:"address",name:"operator",type:"address"},{indexed:!0,internalType:"address",name:"from",type:"address"},{indexed:!0,internalType:"address",name:"to",type:"address"},{indexed:!1,internalType:"uint256",name:"id",type:"uint256"},{indexed:!1,internalType:"uint256",name:"value",type:"uint256"}],name:"TransferSingle",type:"event"},{anonymous:!1,inputs:[{indexed:!1,internalType:"string",name:"value",type:"string"},{indexed:!0,internalType:"uint256",name:"id",type:"uint256"}],name:"URI",type:"event"},{inputs:[{internalType:"address",name:"account",type:"address"},{internalType:"uint256",name:"id",type:"uint256"}],name:"balanceOf",outputs:[{internalType:"uint256",name:"",type:"uint256"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"address[]",name:"accounts",type:"address[]"},{internalType:"uint256[]",name:"ids",type:"uint256[]"}],name:"balanceOfBatch",outputs:[{internalType:"uint256[]",name:"",type:"uint256[]"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"address",name:"account",type:"address"},{internalType:"address",name:"operator",type:"address"}],name:"isApprovedForAll",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"address",name:"from",type:"address"},{internalType:"address",name:"to",type:"address"},{internalType:"uint256[]",name:"ids",type:"uint256[]"},{internalType:"uint256[]",name:"amounts",type:"uint256[]"},{internalType:"bytes",name:"data",type:"bytes"}],name:"safeBatchTransferFrom",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"address",name:"from",type:"address"},{internalType:"address",name:"to",type:"address"},{internalType:"uint256",name:"id",type:"uint256"},{internalType:"uint256",name:"amount",type:"uint256"},{internalType:"bytes",name:"data",type:"bytes"}],name:"safeTransferFrom",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"address",name:"operator",type:"address"},{internalType:"bool",name:"approved",type:"bool"}],name:"setApprovalForAll",outputs:[],stateMutability:"nonpayable",type:"function"},{inputs:[{internalType:"bytes4",name:"interfaceId",type:"bytes4"}],name:"supportsInterface",outputs:[{internalType:"bool",name:"",type:"bool"}],stateMutability:"view",type:"function"},{inputs:[{internalType:"uint256",name:"",type:"uint256"}],name:"uri",outputs:[{internalType:"string",name:"",type:"string"}],stateMutability:"view",type:"function"}];function oe({contract:r,config:e,from:t,to:n}){switch(e.token.type){case"ft":return{account:t,address:r,abi:We,functionName:"transfer",args:[n,e.amount]};case"sft":return{account:t,address:r,abi:ie,functionName:"safeTransferFrom",args:[t.address,n,e.token.tokenId,e.quantity,"0x00"],tokenId:e.token.tokenId};case"nft":return{account:t,address:r,abi:ke,functionName:"safeTransferFrom",args:[t.address,n,e.token.tokenId],tokenId:e.token.tokenId}}}import{BaseError as X,ContractFunctionRevertedError as _}from"viem";import{CrossmintSDKError as Oe,WalletErrorCode as se}from"@crossmint/client-sdk-base";var h=class extends Oe{constructor(t,n,a,o=se.SEND_TRANSACTION_FAILED){super(t,o);this.viemError=n;this.stage=a}},N=class extends h{constructor(t,n,a,o,i,s=a.data,p=a.reason){super(t,n,i,se.SEND_TRANSACTION_EXECUTION_REVERTED);this.viemError=n;this.txId=o;this.stage=i;this.data=s;this.reason=p}},D=class{constructor(e,t={confirmations:2,transactionConfirmationTimeout:3e4}){this.publicClient=e;this.defaultSendTransactionOptions=t}async sendTransaction(e,t,n={}){let{confirmations:a,transactionConfirmationTimeout:o}=this.getConfig(n);await this.simulateCall(e,void 0,"simulation");let i;try{i=await t.writeContract({...e,account:t.account,chain:t.chain})}catch(s){throw s instanceof X?new h(s.message,s,"send"):s}try{let s=await this.publicClient.waitForTransactionReceipt({hash:i,confirmations:a,timeout:o});return await this.handleReceipt(s,e)}catch(s){throw s instanceof X?new h(s.message,s,"confirmation"):s}}getConfig(e){return{...this.defaultSendTransactionOptions,...e}}async handleReceipt(e,t){if(e.status==="reverted")throw await this.simulateCall(t,e.transactionHash,"execution"),new N("Transaction reverted but unable to detect the reason",new _({abi:t.abi,functionName:t.functionName}),new _({abi:t.abi,functionName:t.functionName}),e.transactionHash,"execution");return e.transactionHash}async simulateCall(e,t,n){try{await this.publicClient.simulateContract({...e,account:e.address,chain:this.publicClient.chain})}catch(a){if(a instanceof X){let o=a.walk(i=>i instanceof _);throw o instanceof _?new N(o.message,a,o,t,n):new h(a.message,a,n)}throw a}}};var A=class{constructor(e,t,n,a,o=u){this.crossmintService=e;this.accountClient=t;this.logger=o;this.chain=a,this.client={wallet:t,public:n},this.sendTransactionService=new D(n)}get address(){return this.accountClient.account.address}async transferToken(e,t){return this.logger.logPerformance("TRANSFER",async()=>{if(this.chain!==t.token.chain)throw new Error(`Chain mismatch: Expected ${t.token.chain}, but got ${this.chain}. Ensure you are interacting with the correct blockchain.`);if(!le(e))throw new Error(`Invalid recipient address: '${e}' is not a valid EVM address.`);if(!le(t.token.contractAddress))throw new Error(`Invalid contract address: '${t.token.contractAddress}' is not a valid EVM address.`);let n=oe({contract:t.token.contractAddress,to:e,from:this.accountClient.account,config:t});try{let a=this.accountClient.extend(Ie),{request:o}=await a.simulateContract(n),i=await a.writeContract(o);return this.logger.log(`[TRANSFER] - Transaction hash from transfer: ${i}`),i}catch(a){this.logger.error("[TRANSFER] - ERROR_TRANSFERRING_TOKEN",{error:a instanceof Error?a.message:JSON.stringify(a),tokenId:n.tokenId,contractAddress:t.token.contractAddress,chain:t.token.chain});let o=n.tokenId==null?"":`:${n.tokenId}}`;throw new Re(`Error transferring token ${t.token.contractAddress}${o}`)}},{toAddress:e,config:t})}async nfts(){return this.crossmintService.fetchNFTs(this.address,this.chain)}async executeContract({address:e,abi:t,functionName:n,args:a,value:o,config:i}){return this.sendTransactionService.sendTransaction({address:e,abi:t,functionName:n,args:a,value:o},this.accountClient,i)}};import{CrossmintSDKError as _e,SmartWalletErrorCode as m}from"@crossmint/client-sdk-base";var l=class extends _e{constructor(e,t,n=m.UNCATEGORIZED){super(e,n,t)}},f=class extends l{constructor(e,t,n){super(e,m.ADMIN_MISMATCH),this.required=t,this.used=n}},T=class extends l{constructor(e,t,n){super(e,m.PASSKEY_MISMATCH),this.required=t,this.used=n}},b=class extends l{constructor(t){super(`The user with userId ${t.toString()} already has a wallet created for this project`);this.code=m.USER_WALLET_ALREADY_CREATED}},w=class extends l{constructor(e){super(`Prompt was either cancelled or timed out for passkey ${e}`,void 0,m.PASSKEY_PROMPT),this.passkeyName=e}},x=class extends l{constructor(e){super(`Registration for passkey ${e} failed, either the registration took too long, or passkey signature vaildation failed.`,void 0,m.PASSKEY_REGISTRATION),this.passkeyName=e}},v=class extends l{constructor(e){super(`User selected authenticator for passkey ${e} is not compatible with Crossmint's Smart Wallets.`,void 0,m.PASSKEY_INCOMPATIBLE_AUTHENTICATOR),this.passkeyName=e}},S=class extends l{constructor(e){super(e,void 0,m.WALLET_CONFIG)}},W=class extends S{constructor(){super("This signer was already used to create another wallet. Please use a different signer.");this.code=m.ADMIN_SIGNER_ALREADY_USED}},k=class extends S{constructor(){super("Smart wallets are not enabled for this project. They can be enabled on the project settings page in the developer console.");this.code=m.SMART_WALLETS_NOT_ENABLED}};import{SmartWalletErrorCode as aa,CrossmintSDKError as ia,CrossmintServiceError as oa,TransferError as sa,JWTDecryptionError as la,JWTExpiredError as ca,JWTIdentifierError as pa,JWTInvalidError as ma,NotAuthorizedError as da}from"@crossmint/client-sdk-base";import{stringify as Dt}from"viem";import{validateAPIKey as Ut}from"@crossmint/common-sdk-base";import{APIErrorService as Fe,BaseCrossmintService as Ye,CrossmintServiceError as He}from"@crossmint/client-sdk-base";import{blockchainToChainId as Ge}from"@crossmint/common-sdk-base";import{PasskeyValidatorContractVersion as Ne}from"@zerodev/passkey-validator";import{isAddress as De,isHex as Ue}from"viem";import{z as c}from"zod";var Me=c.custom(r=>Ue(r),{message:"Invalid hex string"}),U=c.custom(r=>De(r),{message:"Invalid evm address"}),Ve=c.object({eoaAddress:U,type:c.literal("eoa")}),Le=c.object({entryPoint:U,validatorAddress:U,pubKeyX:c.string(),pubKeyY:c.string(),authenticatorIdHash:Me,authenticatorId:c.string()}),Ke=Le.extend({passkeyName:c.string(),validatorContractVersion:c.nativeEnum(Ne),domain:c.string(),type:c.literal("passkeys")}),$e=c.discriminatedUnion("type",[Ke,Ve]),M=c.object({kernelVersion:c.enum(z,{errorMap:(r,e)=>({message:`Unsupported kernel version. Supported versions: ${z.join(", ")}. Version used: ${e.data}. Please contact support`})}),entryPointVersion:c.enum(q,{errorMap:(r,e)=>({message:`Unsupported entry point version. Supported versions: ${q.join(", ")}. Version used: ${e.data}. Please contact support`})}),userId:c.string().min(1),signers:c.array(c.object({signerData:$e})).min(0).max(1,"Invalid wallet signer configuration. Please contact support"),smartContractWalletAddress:U.optional()});import{toHex as Be}from"viem";function V(r,e){let t=e(r);return t.replace?t.value:Array.isArray(r)?r.map(n=>V(n,e)):r!==null&&typeof r=="object"?Object.fromEntries(Object.entries(r).map(([n,a])=>[n,V(a,e)])):t.value}function ce(r){return V(r,e=>typeof e=="bigint"?{value:Be(e),replace:!0}:{value:e,replace:!1})}function pe(r){return V(r,e=>e!=null&&typeof e=="object"&&"__xm_serializedType"in e&&"value"in e&&e.__xm_serializedType==="bigint"&&typeof e.value=="string"?{value:BigInt(e.value),replace:!0}:{value:e,replace:!1})}var L=class extends Ye{constructor(){super(...arguments);this.logger=u;this.apiErrorService=new Fe({ERROR_USER_WALLET_ALREADY_CREATED:({userId:t})=>new b(t),ERROR_ADMIN_SIGNER_ALREADY_USED:()=>new W,ERROR_PROJECT_NONCUSTODIAL_WALLETS_NOT_ENABLED:()=>new k})}async idempotentCreateSmartWallet(t,n){await this.fetchCrossmintAPI(`${R}/sdk/smart-wallet`,{method:"PUT",body:JSON.stringify(n)},"Error creating abstract wallet. Please contact support",t.jwt)}async sponsorUserOperation(t,n,a,o){let i=Ge(o),s=await this.fetchCrossmintAPI(`${R}/sdk/paymaster`,{method:"POST",body:JSON.stringify({userOp:ce(n),entryPoint:a,chainId:i})},"Error sponsoring user operation. Please contact support",t.jwt);return pe(s)}async getSmartWalletConfig(t,n){let a=await this.fetchCrossmintAPI(`${R}/sdk/smart-wallet/config?chain=${n}`,{method:"GET"},"Error getting smart wallet version configuration. Please contact support",t.jwt),o=M.safeParse(a);if(!o.success)throw new He(`Invalid smart wallet config, please contact support. Details below:
2
+ ${o.error.toString()}`);return o.data}async fetchNFTs(t,n){return this.fetchCrossmintAPI(`v1-alpha1/wallets/${n}:${t}/nfts`,{method:"GET"},`Error fetching NFTs for wallet: ${t}`)}getPasskeyServerUrl(){return this.crossmintBaseUrl+"api/internal/passkeys"}};import{keccak256 as je,toHex as Je}from"viem";var K=class{constructor(e){this.keyPrefix=e}set(e,t){localStorage.setItem(this.key(e),JSON.stringify(t))}get(e){let t=this.key(e),n=localStorage.getItem(t);if(n==null)return null;let a=M.safeParse(JSON.parse(n));return a.success?a.data:(localStorage.removeItem(t),null)}clear(){for(let e=0;e<localStorage.length;e++){let t=localStorage.key(e);t&&t.startsWith(this.keyPrefix)&&(localStorage.removeItem(t),e--)}}key(e){return`${this.keyPrefix}-${je(Je(e.jwt))}`}};var C=class{constructor(e){this.type="passkeys";this.data=e}display(){return{pubKeyX:this.data.pubKeyX,pubKeyY:this.data.pubKeyY,passkeyName:this.data.passkeyName,type:this.type}}},P=class{constructor(e){this.type="eoa";this.data=e}display(){return this.data}};var $=class{constructor(e,t){this.crossmintService=e;this.configCache=t}async get(e,t){let n=this.configCache.get(e);if(n!=null)return{config:this.validateAndFormat(e,n),cached:!0};let a=await this.crossmintService.getSmartWalletConfig(e,t);return{config:this.validateAndFormat(e,a),cached:!1}}cache({entryPointVersion:e,kernelVersion:t,user:n,existing:a}){this.configCache.clear(),this.configCache.set(n,{entryPointVersion:e,kernelVersion:t,userId:n.id,signers:[{signerData:a.signerConfig.data}],smartContractWalletAddress:a.address})}validateAndFormat(e,{entryPointVersion:t,kernelVersion:n,signers:a,smartContractWalletAddress:o,userId:i}){if(t==="v0.7"&&n.startsWith("0.2")||t==="v0.6"&&n.startsWith("0.3"))throw new l(`Unsupported combination: entryPoint ${t} and kernel version ${n}. Please contact support`);let s=a.map(d=>d.signerData),p=this.getSigner(s);if(o!=null&&p==null||p!=null&&o==null)throw new l("Either both signer and address must be present, or both must be null");return p==null||o==null?{entryPointVersion:t,kernelVersion:n,userWithId:{...e,id:i}}:{entryPointVersion:t,kernelVersion:n,userWithId:{...e,id:i},existing:{signerConfig:p,address:o}}}getSigner(e){if(e.length===0)return;let t=e[0];if(t.type==="eoa")return new P(t);if(t.type==="passkeys")return new C(t)}};function Z(r){return"signer"in r&&"type"in r.signer&&r.signer.type==="PASSKEY"}function me(r){let e=r.existing==null||r.existing.signerConfig.type==="passkeys";return Z(r.walletParams)&&e}function ze(r){return"signer"in r&&("type"in r.signer&&r.signer.type==="VIEM_ACCOUNT"||"request"in r.signer&&typeof r.signer.request=="function")}function de(r){let e=r.existing==null||r.existing.signerConfig.type==="eoa";return ze(r.walletParams)&&e}var B=class{constructor(e,t){this.eoaStrategy=e;this.passkeyStrategy=t}get(e){if(me(e))return this.passkeyStrategy.create(e);if(de(e))return this.eoaStrategy.create(e);if(e.existing==null)throw new S(`Unsupported wallet params:
3
+ ${e.walletParams}`);let t=e.existing.signerConfig.display(),n=Z(e.walletParams)?"passkey":"eoa";throw new f(`Cannot create wallet with ${n} signer for user ${e.user.id}', they already have a wallet with signer:
4
+ '${JSON.stringify(t,null,2)}'`,t)}};import{signerToEcdsaValidator as Qe}from"@zerodev/ecdsa-validator";import{createKernelAccount as et}from"@zerodev/sdk";function ue(r,e){return r?.toLowerCase()===e?.toLowerCase()}import{providerToSmartAccountSigner as qe}from"permissionless";async function ye({walletParams:r}){if(Xe(r.signer))return await qe(r.signer);if(Ze(r.signer))return r.signer.account;{let e=r.signer;throw new l(`The signer type ${e.type} is not supported`)}}function Xe(r){return r&&typeof r.request=="function"}function Ze(r){return r&&r.type==="VIEM_ACCOUNT"}var F=class{async create({chain:e,publicClient:t,entryPoint:n,walletParams:a,kernelVersion:o,user:i,existing:s}){let p=await ye({chain:e,walletParams:a});if(s!=null&&!ue(p.address,s.signerConfig.data.eoaAddress))throw new f(`User '${i.id}' has an existing wallet with an eoa signer '${s.signerConfig.data.eoaAddress}', this does not match input eoa signer '${p.address}'.`,s.signerConfig.display(),{type:"eoa",eoaAddress:s.signerConfig.data.eoaAddress});let d=await Qe(t,{signer:p,entryPoint:n,kernelVersion:o});return{account:await et(t,{plugins:{sudo:d},index:0n,entryPoint:n,kernelVersion:o,deployedAccountAddress:s?.address}),signerConfig:new P({eoaAddress:p.address,type:"eoa"})}}};import{PasskeyValidatorContractVersion as tt,WebAuthnMode as rt,toPasskeyValidator as nt}from"@zerodev/passkey-validator";import{createKernelAccount as at}from"@zerodev/sdk";import{toWebAuthnKey as it}from"@zerodev/webauthn-key";var Y=class{constructor(e,t){this.passkeyServerUrl=e;this.apiKey=t}async create({user:e,publicClient:t,walletParams:n,entryPoint:a,kernelVersion:o,existing:i}){let s=n.signer.passkeyName??e.id;if(i!=null&&i.signerConfig.data.passkeyName!==s)throw new T(`User '${e.id}' has an existing wallet created with a passkey named '${i.signerConfig.data.passkeyName}', this does match input passkey name '${s}'.`,i.signerConfig.display());try{let p=await this.getPasskey(e,s,i?.signerConfig.data),d=tt.V0_0_2,g=i==null?d:i.signerConfig.data.validatorContractVersion,E=await nt(t,{webAuthnKey:p,entryPoint:a,validatorContractVersion:g,kernelVersion:o}),we=await at(t,{plugins:{sudo:E},entryPoint:a,kernelVersion:o,deployedAccountAddress:i?.address});return{signerConfig:this.getSignerConfig(E,g,s),account:this.decorate(we,s)}}catch(p){throw this.mapError(p,s)}}async getPasskey(e,t,n){return n!=null?{pubX:BigInt(n.pubKeyX),pubY:BigInt(n.pubKeyY),authenticatorId:n.authenticatorId,authenticatorIdHash:n.authenticatorIdHash}:it({passkeyName:t,passkeyServerUrl:this.passkeyServerUrl,mode:rt.Register,passkeyServerHeaders:this.createPasskeysServerHeaders(e)})}getSignerConfig(e,t,n){return new C({...lt(e.getSerializedData()),passkeyName:n,validatorContractVersion:t,domain:window.location.hostname,type:"passkeys"})}createPasskeysServerHeaders(e){return{"x-api-key":this.apiKey,Authorization:`Bearer ${e.jwt}`}}mapError(e,t){return e.code===0&&e.name==="DataError"?new v(t):e.message==="Registration not verified"?new x(t):e.code==="ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY"&&e.name==="NotAllowedError"?new w(t):e}decorate(e,t){return new Proxy(e,{get:(n,a,o)=>{let i=Reflect.get(n,a,o);return typeof i!="function"||typeof a!="string"||!st(a)?i:async(...s)=>{try{return await i.call(n,...s)}catch(p){throw this.mapError(p,t)}}}})}},ot=["signMessage","signTypedData","signUserOperation","signTransaction"];function st(r){return ot.includes(r)}var lt=r=>{let e=ct(r),t=new TextDecoder().decode(e);return JSON.parse(t)};function ct(r){let e=atob(r);return Uint8Array.from(e,t=>t.codePointAt(0))}import{stringify as ge}from"viem";function H(r){return!1}var pt=["sendTransaction","writeContract","sendUserOperation"],mt=["signMessage","signTypedData"];function Q(r){return pt.includes(r)}function dt(r){return mt.includes(r)}var G=class{constructor(e,t=u){this.errorProcessor=e;this.logger=t}decorate({crossmintChain:e,smartAccountClient:t}){return new Proxy(t,{get:(n,a,o)=>{let i=Reflect.get(n,a,o);return typeof i!="function"||typeof a!="string"||!(dt(a)||Q(a))?i:(...s)=>this.logger.logPerformance(`CrossmintSmartWallet.${a}`,()=>this.execute(n,a,i,s,e))}})}async execute(e,t,n,a,o){try{this.logger.log(`[CrossmintSmartWallet.${t}] - params: ${ge(a)}`);let i=Q(t)?this.processTxnArgs(t,o,a):a;return await n.call(e,...i)}catch(i){let s=Q(t)?"signing":"sending transaction";throw this.errorProcessor.map(i,new l(`Error ${s}: ${i.message}`,ge(i)))}}processTxnArgs(e,t,n){if(e==="sendUserOperation"){let[{userOperation:o,middleware:i,account:s}]=n;return[{middleware:i,account:s,userOperation:this.addGelatoBundlerProperties(t,o)},...n.slice(1)]}let[a]=n;return[this.addGelatoBundlerProperties(t,a),...n.slice(1)]}addGelatoBundlerProperties(e,t){return H(e)?{...t,maxFeePerGas:"0x0",maxPriorityFeePerGas:"0x0"}:t}};import{ENTRYPOINT_ADDRESS_V06 as vt,ENTRYPOINT_ADDRESS_V07 as Wt,createSmartAccountClient as kt}from"permissionless";import{createPimlicoBundlerClient as Ot}from"permissionless/clients/pimlico";import{createPublicClient as It,http as Te}from"viem";import{blockchainToChainId as Rt}from"@crossmint/common-sdk-base";import{arbitrum as ut,arbitrumSepolia as yt,base as gt,baseSepolia as ft,optimism as St,optimismSepolia as ht,polygon as Ct,polygonAmoy as Pt}from"viem/chains";import{BlockchainIncludingTestnet as y,objectValues as ee}from"@crossmint/common-sdk-base";var fe={BASE_SEPOLIA:y.BASE_SEPOLIA,POLYGON_AMOY:y.POLYGON_AMOY,OPTIMISM_SEPOLIA:y.OPTIMISM_SEPOLIA,ARBITRUM_SEPOLIA:y.ARBITRUM_SEPOLIA},mn=ee(fe),Se={BASE:y.BASE,POLYGON:y.POLYGON,OPTIMISM:y.OPTIMISM,ARBITRUM:y.ARBITRUM},dn=ee(Se),Et={...fe,...Se},un=ee(Et),he={polygon:Ct,"polygon-amoy":Pt,base:gt,"base-sepolia":ft,optimism:St,"optimism-sepolia":ht,arbitrum:ut,"arbitrum-sepolia":yt};import{blockchainToChainId as At}from"@crossmint/common-sdk-base";var Tt="-7M6vRDBDknwvMxnqah_jbcieWg0qad9",bt="pim_9dKmQPxiTCvtbUNF7XFBbA",wt={polygon:"polygon-mainnet","polygon-amoy":"polygon-amoy",base:"base-mainnet","base-sepolia":"base-sepolia",optimism:"opt-mainnet","optimism-sepolia":"opt-sepolia",arbitrum:"arb-mainnet","arbitrum-sepolia":"arb-sepolia"};function Ce(r){return`https://${wt[r]}.g.alchemy.com/v2/${Tt}`}function Pe(r){return`https://api.pimlico.io/v2/${At(r)}/rpc?apikey=${bt}`}function Ee(r){return!H(r)}function Ae({bundlerClient:r,entryPoint:e,chain:t,walletService:n,user:a}){return{middleware:{gasPrice:async()=>(await r.getUserOperationGasPrice()).fast,sponsorUserOperation:async({userOperation:o})=>{let{sponsorUserOpParams:i}=await n.sponsorUserOperation(a,o,e,t);return i}}}}var j=class{constructor(e,t,n,a){this.crossmintService=e;this.accountConfigService=t;this.accountCreator=n;this.clientDecorator=a}async getOrCreate(e,t,n){let{config:{entryPointVersion:a,kernelVersion:o,existing:i,userWithId:s},cached:p}=await this.accountConfigService.get(e,t),d=It({transport:Te(Ce(t))}),{account:g,signerConfig:E}=await this.accountCreator.get({chain:t,walletParams:n,publicClient:d,user:s,entryPoint:a==="v0.6"?vt:Wt,kernelVersion:o,existing:i});return i==null&&await this.crossmintService.idempotentCreateSmartWallet(e,{type:re,smartContractWalletAddress:g.address,signerData:E.data,version:0,baseLayer:"evm",chainId:Rt(t),entryPointVersion:a,kernelVersion:o}),p||this.accountConfigService.cache({entryPointVersion:a,kernelVersion:o,user:s,existing:{address:g.address,signerConfig:E}}),new A(this.crossmintService,this.smartAccountClient(t,g,e),d,t)}smartAccountClient(e,t,n){let a=Te(Pe(e)),o={chain:he[e],entryPoint:t.entryPoint},i=Ot({...o,transport:a}),s=kt({account:t,bundlerTransport:a,...o,...Ee(e)&&Ae({bundlerClient:i,entryPoint:t.entryPoint,chain:e,walletService:this.crossmintService,user:n})});return this.clientDecorator.decorate({crossmintChain:e,smartAccountClient:s})}};import{BaseError as _t,stringify as Nt}from"viem";var J=class{constructor(e){this.logger=e}map(e,t){return this.record(e),e instanceof l||e instanceof _t?e:t}record(e){let t=e instanceof Error?e.message:String(e);this.logger.error(`Smart Wallet SDK Error: ${t}`,{stack:e instanceof Error?e.stack:void 0,name:e instanceof Error?e.name:"UnknownError",details:Nt(e),domain:window.location.hostname,sdk_version:I})}};function be(){return typeof window<"u"}var te=class r{constructor(e,t,n=u){this.smartWalletService=e;this.errorProcessor=t;this.logger=n}static init({clientApiKey:e}){if(!be())throw new l("Smart Wallet SDK should only be used client side.");if(!Ut(e).isValid)throw new Error("API key invalid");let n=new L(e),a=new J(ae),o=new B(new F,new Y(n.getPasskeyServerUrl(),e)),i=new K(`smart-wallet-${I}`),s=new j(n,new $(n,i),o,new G(a));return new r(s,a)}async getOrCreateWallet(e,t,n={signer:{type:"PASSKEY"}}){return this.logger.logPerformance("GET_OR_CREATE_WALLET",async()=>{try{return await this.smartWalletService.getOrCreate(e,t,n)}catch(a){throw this.errorProcessor.map(a,new l(`Wallet creation failed: ${a.message}.`,Dt(a)))}})}};export{W as AdminAlreadyUsedError,f as AdminMismatchError,ea as Chain,S as ConfigError,ia as CrossmintSDKError,oa as CrossmintServiceError,A as EVMSmartWallet,la as JWTDecryptionError,ca as JWTExpiredError,pa as JWTIdentifierError,ma as JWTInvalidError,da as NotAuthorizedError,v as PasskeyIncompatibleAuthenticatorError,T as PasskeyMismatchError,w as PasskeyPromptError,x as PasskeyRegistrationError,l as SmartWalletError,aa as SmartWalletErrorCode,te as SmartWalletSDK,k as SmartWalletsNotEnabledError,sa as TransferError,b as UserWalletAlreadyCreatedError,Qn as blockchainToChainId};
5
5
  //# sourceMappingURL=index.js.map