@crossmint/client-sdk-smart-wallet 0.1.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/LICENSE +201 -0
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +289 -0
- package/dist/index.d.ts +289 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/package.json +46 -0
- package/src/ABI/ERC1155.json +325 -0
- package/src/ABI/ERC20.json +222 -0
- package/src/ABI/ERC721.json +320 -0
- package/src/SmartWalletSDK.test.ts +32 -0
- package/src/SmartWalletSDK.ts +75 -0
- package/src/api/APIErrorService.ts +72 -0
- package/src/api/BaseCrossmintService.ts +82 -0
- package/src/api/CrossmintWalletService.test.ts +42 -0
- package/src/api/CrossmintWalletService.ts +50 -0
- package/src/blockchain/BlockchainNetworks.ts +121 -0
- package/src/blockchain/token/index.ts +1 -0
- package/src/blockchain/transfer.ts +54 -0
- package/src/blockchain/wallets/EVMSmartWallet.ts +109 -0
- package/src/blockchain/wallets/clientDecorator.ts +127 -0
- package/src/blockchain/wallets/eoa.ts +49 -0
- package/src/blockchain/wallets/index.ts +1 -0
- package/src/blockchain/wallets/passkey.ts +117 -0
- package/src/blockchain/wallets/paymaster.ts +49 -0
- package/src/blockchain/wallets/service.ts +193 -0
- package/src/error/index.ts +148 -0
- package/src/error/processor.ts +36 -0
- package/src/index.ts +34 -0
- package/src/services/logging/BrowserLoggerInterface.ts +5 -0
- package/src/services/logging/ConsoleProvider.ts +24 -0
- package/src/services/logging/DatadogProvider.ts +39 -0
- package/src/services/logging/index.ts +16 -0
- package/src/types/API.ts +40 -0
- package/src/types/Config.ts +35 -0
- package/src/types/Tokens.ts +27 -0
- package/src/types/internal.ts +50 -0
- package/src/utils/blockchain.ts +15 -0
- package/src/utils/constants.ts +31 -0
- package/src/utils/environment.ts +3 -0
- package/src/utils/helpers.ts +15 -0
- package/src/utils/log.test.ts +76 -0
- package/src/utils/log.ts +157 -0
- package/src/utils/signer.ts +36 -0
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
import { EVMBlockchainIncludingTestnet } from '@crossmint/common-sdk-base';
|
|
2
|
+
export { EVMBlockchainIncludingTestnet as Blockchain, blockchainToChainId } from '@crossmint/common-sdk-base';
|
|
3
|
+
import { LocalAccount, EIP1193Provider, HttpTransport, Chain, Hex, PublicClient } from 'viem';
|
|
4
|
+
import { PasskeyValidatorContractVersion } from '@zerodev/passkey-validator';
|
|
5
|
+
import { SmartAccountClient } from 'permissionless';
|
|
6
|
+
import { SmartAccount } from 'permissionless/accounts';
|
|
7
|
+
import { EntryPoint } from 'permissionless/types/entrypoint';
|
|
8
|
+
|
|
9
|
+
type SmartWalletSDKInitParams = {
|
|
10
|
+
clientApiKey: string;
|
|
11
|
+
};
|
|
12
|
+
type UserParams = {
|
|
13
|
+
jwt: string;
|
|
14
|
+
};
|
|
15
|
+
type ViemAccount = {
|
|
16
|
+
type: "VIEM_ACCOUNT";
|
|
17
|
+
account: LocalAccount & {
|
|
18
|
+
source: "custom";
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
type PasskeySigner = {
|
|
22
|
+
type: "PASSKEY";
|
|
23
|
+
/**
|
|
24
|
+
* Displayed to the user during passkey registration or signing prompts.
|
|
25
|
+
* If not provided, a default name identifier within the JWT
|
|
26
|
+
* that is specified in the project settings (typically `sub`) will be used.
|
|
27
|
+
*/
|
|
28
|
+
passkeyName?: string;
|
|
29
|
+
};
|
|
30
|
+
type EOASigner = EIP1193Provider | ViemAccount;
|
|
31
|
+
interface WalletParams {
|
|
32
|
+
signer: EOASigner | PasskeySigner;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
declare const SUPPORTED_KERNEL_VERSIONS: readonly ["0.3.1", "0.3.0", "0.2.4"];
|
|
36
|
+
type SupportedKernelVersion = (typeof SUPPORTED_KERNEL_VERSIONS)[number];
|
|
37
|
+
declare const SUPPORTED_ENTRYPOINT_VERSIONS: readonly ["v0.6", "v0.7"];
|
|
38
|
+
type SupportedEntryPointVersion = (typeof SUPPORTED_ENTRYPOINT_VERSIONS)[number];
|
|
39
|
+
type PasskeyValidatorSerializedData = {
|
|
40
|
+
passkeyServerUrl: string;
|
|
41
|
+
entryPoint: Hex;
|
|
42
|
+
validatorAddress: Hex;
|
|
43
|
+
pubKeyX: string;
|
|
44
|
+
pubKeyY: string;
|
|
45
|
+
authenticatorIdHash: Hex;
|
|
46
|
+
authenticatorId: string;
|
|
47
|
+
};
|
|
48
|
+
type SmartWalletClient = SmartAccountClient<EntryPoint, HttpTransport, Chain, SmartAccount<EntryPoint>>;
|
|
49
|
+
|
|
50
|
+
type StoreSmartWalletParams = {
|
|
51
|
+
type: string;
|
|
52
|
+
smartContractWalletAddress: string;
|
|
53
|
+
signerData: SignerData;
|
|
54
|
+
sessionKeySignerAddress?: string;
|
|
55
|
+
version: number;
|
|
56
|
+
baseLayer: string;
|
|
57
|
+
chainId: number;
|
|
58
|
+
entryPointVersion: SupportedEntryPointVersion;
|
|
59
|
+
kernelVersion: SupportedKernelVersion;
|
|
60
|
+
};
|
|
61
|
+
type SignerData = EOASignerData | PasskeySignerData;
|
|
62
|
+
interface EOASignerData {
|
|
63
|
+
eoaAddress: string;
|
|
64
|
+
type: "eoa";
|
|
65
|
+
}
|
|
66
|
+
type PasskeySignerData = PasskeyValidatorSerializedData & {
|
|
67
|
+
passkeyName: string;
|
|
68
|
+
validatorContractVersion: PasskeyValidatorContractVersion;
|
|
69
|
+
domain: string;
|
|
70
|
+
type: "passkeys";
|
|
71
|
+
};
|
|
72
|
+
type PasskeyDisplay = Pick<PasskeySignerData, "type" | "passkeyName" | "pubKeyX" | "pubKeyY">;
|
|
73
|
+
type SignerDisplay = EOASignerData | PasskeyDisplay;
|
|
74
|
+
|
|
75
|
+
declare class LoggerWrapper {
|
|
76
|
+
private extraInfo;
|
|
77
|
+
private logIdempotencyKey;
|
|
78
|
+
constructor(className: string, extraInfo?: {}, logIdempotencyKey?: string);
|
|
79
|
+
private logInput;
|
|
80
|
+
private logOutput;
|
|
81
|
+
private logError;
|
|
82
|
+
protected logPerformance<T>(name: string, cb: () => Promise<T>): Promise<T>;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
declare const SmartWalletErrors: {
|
|
86
|
+
readonly NOT_AUTHORIZED: "smart-wallet:not-authorized";
|
|
87
|
+
readonly TRANSFER: "smart-wallet:transfer.error";
|
|
88
|
+
readonly CROSSMINT_SERVICE: "smart-wallet:crossmint-service.error";
|
|
89
|
+
readonly ERROR_JWT_EXPIRED: "smart-wallet:not-authorized.jwt-expired";
|
|
90
|
+
readonly ERROR_JWT_INVALID: "smart-wallet:not-authorized.jwt-invalid";
|
|
91
|
+
readonly ERROR_JWT_DECRYPTION: "smart-wallet:not-authorized.jwt-decryption";
|
|
92
|
+
readonly ERROR_JWT_IDENTIFIER: "smart-wallet:not-authorized.jwt-identifier";
|
|
93
|
+
readonly ERROR_USER_WALLET_ALREADY_CREATED: "smart-wallet:user-wallet-already-created.error";
|
|
94
|
+
readonly ERROR_OUT_OF_CREDITS: "smart-wallet:out-of-credits.error";
|
|
95
|
+
readonly ERROR_WALLET_CONFIG: "smart-wallet:wallet-config.error";
|
|
96
|
+
readonly ERROR_ADMIN_MISMATCH: "smart-wallet:wallet-config.admin-mismatch";
|
|
97
|
+
readonly ERROR_PASSKEY_MISMATCH: "smart-wallet:wallet-config.passkey-mismatch";
|
|
98
|
+
readonly ERROR_ADMIN_SIGNER_ALREADY_USED: "smart-wallet:wallet-config.admin-signer-already-used";
|
|
99
|
+
readonly UNCATEGORIZED: "smart-wallet:uncategorized";
|
|
100
|
+
};
|
|
101
|
+
type SmartWalletErrorCode = (typeof SmartWalletErrors)[keyof typeof SmartWalletErrors];
|
|
102
|
+
declare class SmartWalletSDKError extends Error {
|
|
103
|
+
readonly code: SmartWalletErrorCode;
|
|
104
|
+
readonly details?: string;
|
|
105
|
+
constructor(message: string, details?: string, code?: SmartWalletErrorCode);
|
|
106
|
+
}
|
|
107
|
+
declare class TransferError extends SmartWalletSDKError {
|
|
108
|
+
constructor(message: string);
|
|
109
|
+
}
|
|
110
|
+
declare class CrossmintServiceError extends SmartWalletSDKError {
|
|
111
|
+
status?: number;
|
|
112
|
+
constructor(message: string, status?: number);
|
|
113
|
+
}
|
|
114
|
+
declare class AdminMismatchError extends SmartWalletSDKError {
|
|
115
|
+
readonly required: SignerDisplay;
|
|
116
|
+
readonly used?: SignerDisplay;
|
|
117
|
+
constructor(message: string, required: SignerDisplay, used?: SignerDisplay);
|
|
118
|
+
}
|
|
119
|
+
declare class PasskeyMismatchError extends SmartWalletSDKError {
|
|
120
|
+
readonly required: PasskeyDisplay;
|
|
121
|
+
readonly used?: PasskeyDisplay;
|
|
122
|
+
constructor(message: string, required: PasskeyDisplay, used?: PasskeyDisplay);
|
|
123
|
+
}
|
|
124
|
+
declare class NotAuthorizedError extends SmartWalletSDKError {
|
|
125
|
+
constructor(message: string);
|
|
126
|
+
}
|
|
127
|
+
declare class JWTExpiredError extends NotAuthorizedError {
|
|
128
|
+
readonly code: "smart-wallet:not-authorized.jwt-expired";
|
|
129
|
+
/**
|
|
130
|
+
* The expiry time of the JWT as an ISO 8601 timestamp.
|
|
131
|
+
*/
|
|
132
|
+
readonly expiredAt: string;
|
|
133
|
+
constructor(expiredAt: Date);
|
|
134
|
+
}
|
|
135
|
+
declare class JWTInvalidError extends NotAuthorizedError {
|
|
136
|
+
readonly code: "smart-wallet:not-authorized.jwt-invalid";
|
|
137
|
+
constructor();
|
|
138
|
+
}
|
|
139
|
+
declare class JWTDecryptionError extends NotAuthorizedError {
|
|
140
|
+
readonly code: "smart-wallet:not-authorized.jwt-decryption";
|
|
141
|
+
constructor();
|
|
142
|
+
}
|
|
143
|
+
declare class JWTIdentifierError extends NotAuthorizedError {
|
|
144
|
+
readonly code: "smart-wallet:not-authorized.jwt-identifier";
|
|
145
|
+
readonly identifierKey: string;
|
|
146
|
+
constructor(identifierKey: string);
|
|
147
|
+
}
|
|
148
|
+
declare class UserWalletAlreadyCreatedError extends SmartWalletSDKError {
|
|
149
|
+
readonly code: "smart-wallet:user-wallet-already-created.error";
|
|
150
|
+
constructor(userId: string);
|
|
151
|
+
}
|
|
152
|
+
declare class OutOfCreditsError extends SmartWalletSDKError {
|
|
153
|
+
constructor(message?: string);
|
|
154
|
+
}
|
|
155
|
+
declare class ConfigError extends SmartWalletSDKError {
|
|
156
|
+
constructor(message: string);
|
|
157
|
+
}
|
|
158
|
+
declare class AdminAlreadyUsedError extends ConfigError {
|
|
159
|
+
readonly code: "smart-wallet:wallet-config.admin-signer-already-used";
|
|
160
|
+
constructor();
|
|
161
|
+
}
|
|
162
|
+
declare class NonCustodialWalletsNotEnabledError extends ConfigError {
|
|
163
|
+
constructor();
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
type CrossmintAPIErrorCodes = "ERROR_JWT_INVALID" | "ERROR_JWT_DECRYPTION" | "ERROR_JWT_IDENTIFIER" | "ERROR_JWT_EXPIRED" | "ERROR_USER_WALLET_ALREADY_CREATED" | "ERROR_ADMIN_SIGNER_ALREADY_USED" | "ERROR_PROJECT_NONCUSTODIAL_WALLETS_NOT_ENABLED";
|
|
167
|
+
declare class APIErrorService {
|
|
168
|
+
private errors;
|
|
169
|
+
constructor(errors?: Partial<Record<CrossmintAPIErrorCodes, (apiResponse: any) => SmartWalletSDKError>>);
|
|
170
|
+
throwErrorFromResponse({ response, onServerErrorMessage, }: {
|
|
171
|
+
response: Response;
|
|
172
|
+
onServerErrorMessage: string;
|
|
173
|
+
}): Promise<void>;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
declare abstract class BaseCrossmintService extends LoggerWrapper {
|
|
177
|
+
crossmintAPIHeaders: Record<string, string>;
|
|
178
|
+
protected crossmintBaseUrl: string;
|
|
179
|
+
protected apiErrorService: APIErrorService;
|
|
180
|
+
private static urlMap;
|
|
181
|
+
constructor(apiKey: string);
|
|
182
|
+
protected fetchCrossmintAPI(endpoint: string, options: {
|
|
183
|
+
body?: string;
|
|
184
|
+
method: string;
|
|
185
|
+
} | undefined, onServerErrorMessage: string, authToken?: string): Promise<any>;
|
|
186
|
+
protected getUrlFromEnv(environment: string): string;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
declare class CrossmintWalletService extends BaseCrossmintService {
|
|
190
|
+
idempotentCreateSmartWallet(user: UserParams, input: StoreSmartWalletParams): Promise<any>;
|
|
191
|
+
getSmartWalletConfig(user: UserParams, chain: EVMBlockchainIncludingTestnet): Promise<{
|
|
192
|
+
kernelVersion: string;
|
|
193
|
+
entryPointVersion: string;
|
|
194
|
+
userId: string;
|
|
195
|
+
signers: {
|
|
196
|
+
signerData: SignerData;
|
|
197
|
+
}[];
|
|
198
|
+
smartContractWalletAddress?: string;
|
|
199
|
+
}>;
|
|
200
|
+
fetchNFTs(address: string, chain: EVMBlockchainIncludingTestnet): Promise<any>;
|
|
201
|
+
getPasskeyServerUrl(): string;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
interface EVMToken {
|
|
205
|
+
chain: EVMBlockchainIncludingTestnet;
|
|
206
|
+
contractAddress: string;
|
|
207
|
+
}
|
|
208
|
+
interface NFTEVMToken extends EVMToken {
|
|
209
|
+
tokenId: string;
|
|
210
|
+
type: "nft";
|
|
211
|
+
}
|
|
212
|
+
interface SFTEVMToken extends EVMToken {
|
|
213
|
+
tokenId: string;
|
|
214
|
+
type: "sft";
|
|
215
|
+
}
|
|
216
|
+
interface ERC2OEVMToken extends EVMToken {
|
|
217
|
+
type: "ft";
|
|
218
|
+
}
|
|
219
|
+
type ERC20TransferType = {
|
|
220
|
+
token: ERC2OEVMToken;
|
|
221
|
+
amount: bigint;
|
|
222
|
+
};
|
|
223
|
+
type SFTTransferType = {
|
|
224
|
+
token: SFTEVMToken;
|
|
225
|
+
quantity: number;
|
|
226
|
+
};
|
|
227
|
+
type NFTTransferType = {
|
|
228
|
+
token: NFTEVMToken;
|
|
229
|
+
};
|
|
230
|
+
type TransferType = ERC20TransferType | SFTTransferType | NFTTransferType;
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Smart wallet interface for EVM chains enhanced with Crossmint capabilities.
|
|
234
|
+
* Core functionality is exposed via [viem](https://viem.sh/) clients within the `client` property of the class.
|
|
235
|
+
*/
|
|
236
|
+
declare class EVMSmartWallet extends LoggerWrapper {
|
|
237
|
+
private readonly crossmintService;
|
|
238
|
+
private readonly accountClient;
|
|
239
|
+
readonly chain: EVMBlockchainIncludingTestnet;
|
|
240
|
+
/**
|
|
241
|
+
* [viem](https://viem.sh/) clients that provide an interface for core wallet functionality.
|
|
242
|
+
*/
|
|
243
|
+
readonly client: {
|
|
244
|
+
/**
|
|
245
|
+
* An interface to interact with the smart wallet, execute transactions, sign messages, etc.
|
|
246
|
+
*/
|
|
247
|
+
wallet: SmartWalletClient;
|
|
248
|
+
/**
|
|
249
|
+
* An interface to read onchain data, fetch transactions, retrieve account balances, etc. Corresponds to public [JSON-RPC API](https://ethereum.org/en/developers/docs/apis/json-rpc/) methods.
|
|
250
|
+
*/
|
|
251
|
+
public: PublicClient;
|
|
252
|
+
};
|
|
253
|
+
constructor(crossmintService: CrossmintWalletService, accountClient: SmartWalletClient, publicClient: PublicClient<HttpTransport>, chain: EVMBlockchainIncludingTestnet);
|
|
254
|
+
/**
|
|
255
|
+
* The address of the smart wallet.
|
|
256
|
+
*/
|
|
257
|
+
get address(): `0x${string}`;
|
|
258
|
+
/**
|
|
259
|
+
* @returns The transaction hash.
|
|
260
|
+
*/
|
|
261
|
+
transferToken(toAddress: string, config: TransferType): Promise<string>;
|
|
262
|
+
/**
|
|
263
|
+
* @returns A list of NFTs owned by the wallet.
|
|
264
|
+
*/
|
|
265
|
+
nfts(): Promise<any>;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
declare class SmartWalletSDK extends LoggerWrapper {
|
|
269
|
+
private readonly smartWalletService;
|
|
270
|
+
private readonly errorProcessor;
|
|
271
|
+
private constructor();
|
|
272
|
+
/**
|
|
273
|
+
* Initializes the SDK with the **client side** API key obtained from the Crossmint console.
|
|
274
|
+
* @throws error if the api key is not formatted correctly.
|
|
275
|
+
*/
|
|
276
|
+
static init({ clientApiKey }: SmartWalletSDKInitParams): SmartWalletSDK;
|
|
277
|
+
/**
|
|
278
|
+
* Retrieves or creates a wallet for the specified user.
|
|
279
|
+
* The default configuration is a `PasskeySigner` with the name, which is displayed to the user during creation or signing prompts, derived from the provided jwt.
|
|
280
|
+
*
|
|
281
|
+
* Example using the default passkey signer:
|
|
282
|
+
* ```ts
|
|
283
|
+
* const wallet = await smartWalletSDK.getOrCreateWallet({ jwt: "xxx" }, "base");
|
|
284
|
+
* ```
|
|
285
|
+
*/
|
|
286
|
+
getOrCreateWallet(user: UserParams, chain: EVMBlockchainIncludingTestnet, walletParams?: WalletParams): Promise<EVMSmartWallet>;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
export { AdminAlreadyUsedError, AdminMismatchError, ConfigError, CrossmintServiceError, type EOASigner, type ERC20TransferType, EVMSmartWallet, JWTDecryptionError, JWTExpiredError, JWTIdentifierError, JWTInvalidError, type NFTTransferType, NonCustodialWalletsNotEnabledError, NotAuthorizedError, OutOfCreditsError, PasskeyMismatchError, type PasskeySigner, type SFTTransferType, SmartWalletSDK, SmartWalletSDKError, type SmartWalletSDKInitParams, TransferError, type TransferType, type UserParams, UserWalletAlreadyCreatedError, type ViemAccount, type WalletParams };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
import { EVMBlockchainIncludingTestnet } from '@crossmint/common-sdk-base';
|
|
2
|
+
export { EVMBlockchainIncludingTestnet as Blockchain, blockchainToChainId } from '@crossmint/common-sdk-base';
|
|
3
|
+
import { LocalAccount, EIP1193Provider, HttpTransport, Chain, Hex, PublicClient } from 'viem';
|
|
4
|
+
import { PasskeyValidatorContractVersion } from '@zerodev/passkey-validator';
|
|
5
|
+
import { SmartAccountClient } from 'permissionless';
|
|
6
|
+
import { SmartAccount } from 'permissionless/accounts';
|
|
7
|
+
import { EntryPoint } from 'permissionless/types/entrypoint';
|
|
8
|
+
|
|
9
|
+
type SmartWalletSDKInitParams = {
|
|
10
|
+
clientApiKey: string;
|
|
11
|
+
};
|
|
12
|
+
type UserParams = {
|
|
13
|
+
jwt: string;
|
|
14
|
+
};
|
|
15
|
+
type ViemAccount = {
|
|
16
|
+
type: "VIEM_ACCOUNT";
|
|
17
|
+
account: LocalAccount & {
|
|
18
|
+
source: "custom";
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
type PasskeySigner = {
|
|
22
|
+
type: "PASSKEY";
|
|
23
|
+
/**
|
|
24
|
+
* Displayed to the user during passkey registration or signing prompts.
|
|
25
|
+
* If not provided, a default name identifier within the JWT
|
|
26
|
+
* that is specified in the project settings (typically `sub`) will be used.
|
|
27
|
+
*/
|
|
28
|
+
passkeyName?: string;
|
|
29
|
+
};
|
|
30
|
+
type EOASigner = EIP1193Provider | ViemAccount;
|
|
31
|
+
interface WalletParams {
|
|
32
|
+
signer: EOASigner | PasskeySigner;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
declare const SUPPORTED_KERNEL_VERSIONS: readonly ["0.3.1", "0.3.0", "0.2.4"];
|
|
36
|
+
type SupportedKernelVersion = (typeof SUPPORTED_KERNEL_VERSIONS)[number];
|
|
37
|
+
declare const SUPPORTED_ENTRYPOINT_VERSIONS: readonly ["v0.6", "v0.7"];
|
|
38
|
+
type SupportedEntryPointVersion = (typeof SUPPORTED_ENTRYPOINT_VERSIONS)[number];
|
|
39
|
+
type PasskeyValidatorSerializedData = {
|
|
40
|
+
passkeyServerUrl: string;
|
|
41
|
+
entryPoint: Hex;
|
|
42
|
+
validatorAddress: Hex;
|
|
43
|
+
pubKeyX: string;
|
|
44
|
+
pubKeyY: string;
|
|
45
|
+
authenticatorIdHash: Hex;
|
|
46
|
+
authenticatorId: string;
|
|
47
|
+
};
|
|
48
|
+
type SmartWalletClient = SmartAccountClient<EntryPoint, HttpTransport, Chain, SmartAccount<EntryPoint>>;
|
|
49
|
+
|
|
50
|
+
type StoreSmartWalletParams = {
|
|
51
|
+
type: string;
|
|
52
|
+
smartContractWalletAddress: string;
|
|
53
|
+
signerData: SignerData;
|
|
54
|
+
sessionKeySignerAddress?: string;
|
|
55
|
+
version: number;
|
|
56
|
+
baseLayer: string;
|
|
57
|
+
chainId: number;
|
|
58
|
+
entryPointVersion: SupportedEntryPointVersion;
|
|
59
|
+
kernelVersion: SupportedKernelVersion;
|
|
60
|
+
};
|
|
61
|
+
type SignerData = EOASignerData | PasskeySignerData;
|
|
62
|
+
interface EOASignerData {
|
|
63
|
+
eoaAddress: string;
|
|
64
|
+
type: "eoa";
|
|
65
|
+
}
|
|
66
|
+
type PasskeySignerData = PasskeyValidatorSerializedData & {
|
|
67
|
+
passkeyName: string;
|
|
68
|
+
validatorContractVersion: PasskeyValidatorContractVersion;
|
|
69
|
+
domain: string;
|
|
70
|
+
type: "passkeys";
|
|
71
|
+
};
|
|
72
|
+
type PasskeyDisplay = Pick<PasskeySignerData, "type" | "passkeyName" | "pubKeyX" | "pubKeyY">;
|
|
73
|
+
type SignerDisplay = EOASignerData | PasskeyDisplay;
|
|
74
|
+
|
|
75
|
+
declare class LoggerWrapper {
|
|
76
|
+
private extraInfo;
|
|
77
|
+
private logIdempotencyKey;
|
|
78
|
+
constructor(className: string, extraInfo?: {}, logIdempotencyKey?: string);
|
|
79
|
+
private logInput;
|
|
80
|
+
private logOutput;
|
|
81
|
+
private logError;
|
|
82
|
+
protected logPerformance<T>(name: string, cb: () => Promise<T>): Promise<T>;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
declare const SmartWalletErrors: {
|
|
86
|
+
readonly NOT_AUTHORIZED: "smart-wallet:not-authorized";
|
|
87
|
+
readonly TRANSFER: "smart-wallet:transfer.error";
|
|
88
|
+
readonly CROSSMINT_SERVICE: "smart-wallet:crossmint-service.error";
|
|
89
|
+
readonly ERROR_JWT_EXPIRED: "smart-wallet:not-authorized.jwt-expired";
|
|
90
|
+
readonly ERROR_JWT_INVALID: "smart-wallet:not-authorized.jwt-invalid";
|
|
91
|
+
readonly ERROR_JWT_DECRYPTION: "smart-wallet:not-authorized.jwt-decryption";
|
|
92
|
+
readonly ERROR_JWT_IDENTIFIER: "smart-wallet:not-authorized.jwt-identifier";
|
|
93
|
+
readonly ERROR_USER_WALLET_ALREADY_CREATED: "smart-wallet:user-wallet-already-created.error";
|
|
94
|
+
readonly ERROR_OUT_OF_CREDITS: "smart-wallet:out-of-credits.error";
|
|
95
|
+
readonly ERROR_WALLET_CONFIG: "smart-wallet:wallet-config.error";
|
|
96
|
+
readonly ERROR_ADMIN_MISMATCH: "smart-wallet:wallet-config.admin-mismatch";
|
|
97
|
+
readonly ERROR_PASSKEY_MISMATCH: "smart-wallet:wallet-config.passkey-mismatch";
|
|
98
|
+
readonly ERROR_ADMIN_SIGNER_ALREADY_USED: "smart-wallet:wallet-config.admin-signer-already-used";
|
|
99
|
+
readonly UNCATEGORIZED: "smart-wallet:uncategorized";
|
|
100
|
+
};
|
|
101
|
+
type SmartWalletErrorCode = (typeof SmartWalletErrors)[keyof typeof SmartWalletErrors];
|
|
102
|
+
declare class SmartWalletSDKError extends Error {
|
|
103
|
+
readonly code: SmartWalletErrorCode;
|
|
104
|
+
readonly details?: string;
|
|
105
|
+
constructor(message: string, details?: string, code?: SmartWalletErrorCode);
|
|
106
|
+
}
|
|
107
|
+
declare class TransferError extends SmartWalletSDKError {
|
|
108
|
+
constructor(message: string);
|
|
109
|
+
}
|
|
110
|
+
declare class CrossmintServiceError extends SmartWalletSDKError {
|
|
111
|
+
status?: number;
|
|
112
|
+
constructor(message: string, status?: number);
|
|
113
|
+
}
|
|
114
|
+
declare class AdminMismatchError extends SmartWalletSDKError {
|
|
115
|
+
readonly required: SignerDisplay;
|
|
116
|
+
readonly used?: SignerDisplay;
|
|
117
|
+
constructor(message: string, required: SignerDisplay, used?: SignerDisplay);
|
|
118
|
+
}
|
|
119
|
+
declare class PasskeyMismatchError extends SmartWalletSDKError {
|
|
120
|
+
readonly required: PasskeyDisplay;
|
|
121
|
+
readonly used?: PasskeyDisplay;
|
|
122
|
+
constructor(message: string, required: PasskeyDisplay, used?: PasskeyDisplay);
|
|
123
|
+
}
|
|
124
|
+
declare class NotAuthorizedError extends SmartWalletSDKError {
|
|
125
|
+
constructor(message: string);
|
|
126
|
+
}
|
|
127
|
+
declare class JWTExpiredError extends NotAuthorizedError {
|
|
128
|
+
readonly code: "smart-wallet:not-authorized.jwt-expired";
|
|
129
|
+
/**
|
|
130
|
+
* The expiry time of the JWT as an ISO 8601 timestamp.
|
|
131
|
+
*/
|
|
132
|
+
readonly expiredAt: string;
|
|
133
|
+
constructor(expiredAt: Date);
|
|
134
|
+
}
|
|
135
|
+
declare class JWTInvalidError extends NotAuthorizedError {
|
|
136
|
+
readonly code: "smart-wallet:not-authorized.jwt-invalid";
|
|
137
|
+
constructor();
|
|
138
|
+
}
|
|
139
|
+
declare class JWTDecryptionError extends NotAuthorizedError {
|
|
140
|
+
readonly code: "smart-wallet:not-authorized.jwt-decryption";
|
|
141
|
+
constructor();
|
|
142
|
+
}
|
|
143
|
+
declare class JWTIdentifierError extends NotAuthorizedError {
|
|
144
|
+
readonly code: "smart-wallet:not-authorized.jwt-identifier";
|
|
145
|
+
readonly identifierKey: string;
|
|
146
|
+
constructor(identifierKey: string);
|
|
147
|
+
}
|
|
148
|
+
declare class UserWalletAlreadyCreatedError extends SmartWalletSDKError {
|
|
149
|
+
readonly code: "smart-wallet:user-wallet-already-created.error";
|
|
150
|
+
constructor(userId: string);
|
|
151
|
+
}
|
|
152
|
+
declare class OutOfCreditsError extends SmartWalletSDKError {
|
|
153
|
+
constructor(message?: string);
|
|
154
|
+
}
|
|
155
|
+
declare class ConfigError extends SmartWalletSDKError {
|
|
156
|
+
constructor(message: string);
|
|
157
|
+
}
|
|
158
|
+
declare class AdminAlreadyUsedError extends ConfigError {
|
|
159
|
+
readonly code: "smart-wallet:wallet-config.admin-signer-already-used";
|
|
160
|
+
constructor();
|
|
161
|
+
}
|
|
162
|
+
declare class NonCustodialWalletsNotEnabledError extends ConfigError {
|
|
163
|
+
constructor();
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
type CrossmintAPIErrorCodes = "ERROR_JWT_INVALID" | "ERROR_JWT_DECRYPTION" | "ERROR_JWT_IDENTIFIER" | "ERROR_JWT_EXPIRED" | "ERROR_USER_WALLET_ALREADY_CREATED" | "ERROR_ADMIN_SIGNER_ALREADY_USED" | "ERROR_PROJECT_NONCUSTODIAL_WALLETS_NOT_ENABLED";
|
|
167
|
+
declare class APIErrorService {
|
|
168
|
+
private errors;
|
|
169
|
+
constructor(errors?: Partial<Record<CrossmintAPIErrorCodes, (apiResponse: any) => SmartWalletSDKError>>);
|
|
170
|
+
throwErrorFromResponse({ response, onServerErrorMessage, }: {
|
|
171
|
+
response: Response;
|
|
172
|
+
onServerErrorMessage: string;
|
|
173
|
+
}): Promise<void>;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
declare abstract class BaseCrossmintService extends LoggerWrapper {
|
|
177
|
+
crossmintAPIHeaders: Record<string, string>;
|
|
178
|
+
protected crossmintBaseUrl: string;
|
|
179
|
+
protected apiErrorService: APIErrorService;
|
|
180
|
+
private static urlMap;
|
|
181
|
+
constructor(apiKey: string);
|
|
182
|
+
protected fetchCrossmintAPI(endpoint: string, options: {
|
|
183
|
+
body?: string;
|
|
184
|
+
method: string;
|
|
185
|
+
} | undefined, onServerErrorMessage: string, authToken?: string): Promise<any>;
|
|
186
|
+
protected getUrlFromEnv(environment: string): string;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
declare class CrossmintWalletService extends BaseCrossmintService {
|
|
190
|
+
idempotentCreateSmartWallet(user: UserParams, input: StoreSmartWalletParams): Promise<any>;
|
|
191
|
+
getSmartWalletConfig(user: UserParams, chain: EVMBlockchainIncludingTestnet): Promise<{
|
|
192
|
+
kernelVersion: string;
|
|
193
|
+
entryPointVersion: string;
|
|
194
|
+
userId: string;
|
|
195
|
+
signers: {
|
|
196
|
+
signerData: SignerData;
|
|
197
|
+
}[];
|
|
198
|
+
smartContractWalletAddress?: string;
|
|
199
|
+
}>;
|
|
200
|
+
fetchNFTs(address: string, chain: EVMBlockchainIncludingTestnet): Promise<any>;
|
|
201
|
+
getPasskeyServerUrl(): string;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
interface EVMToken {
|
|
205
|
+
chain: EVMBlockchainIncludingTestnet;
|
|
206
|
+
contractAddress: string;
|
|
207
|
+
}
|
|
208
|
+
interface NFTEVMToken extends EVMToken {
|
|
209
|
+
tokenId: string;
|
|
210
|
+
type: "nft";
|
|
211
|
+
}
|
|
212
|
+
interface SFTEVMToken extends EVMToken {
|
|
213
|
+
tokenId: string;
|
|
214
|
+
type: "sft";
|
|
215
|
+
}
|
|
216
|
+
interface ERC2OEVMToken extends EVMToken {
|
|
217
|
+
type: "ft";
|
|
218
|
+
}
|
|
219
|
+
type ERC20TransferType = {
|
|
220
|
+
token: ERC2OEVMToken;
|
|
221
|
+
amount: bigint;
|
|
222
|
+
};
|
|
223
|
+
type SFTTransferType = {
|
|
224
|
+
token: SFTEVMToken;
|
|
225
|
+
quantity: number;
|
|
226
|
+
};
|
|
227
|
+
type NFTTransferType = {
|
|
228
|
+
token: NFTEVMToken;
|
|
229
|
+
};
|
|
230
|
+
type TransferType = ERC20TransferType | SFTTransferType | NFTTransferType;
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Smart wallet interface for EVM chains enhanced with Crossmint capabilities.
|
|
234
|
+
* Core functionality is exposed via [viem](https://viem.sh/) clients within the `client` property of the class.
|
|
235
|
+
*/
|
|
236
|
+
declare class EVMSmartWallet extends LoggerWrapper {
|
|
237
|
+
private readonly crossmintService;
|
|
238
|
+
private readonly accountClient;
|
|
239
|
+
readonly chain: EVMBlockchainIncludingTestnet;
|
|
240
|
+
/**
|
|
241
|
+
* [viem](https://viem.sh/) clients that provide an interface for core wallet functionality.
|
|
242
|
+
*/
|
|
243
|
+
readonly client: {
|
|
244
|
+
/**
|
|
245
|
+
* An interface to interact with the smart wallet, execute transactions, sign messages, etc.
|
|
246
|
+
*/
|
|
247
|
+
wallet: SmartWalletClient;
|
|
248
|
+
/**
|
|
249
|
+
* An interface to read onchain data, fetch transactions, retrieve account balances, etc. Corresponds to public [JSON-RPC API](https://ethereum.org/en/developers/docs/apis/json-rpc/) methods.
|
|
250
|
+
*/
|
|
251
|
+
public: PublicClient;
|
|
252
|
+
};
|
|
253
|
+
constructor(crossmintService: CrossmintWalletService, accountClient: SmartWalletClient, publicClient: PublicClient<HttpTransport>, chain: EVMBlockchainIncludingTestnet);
|
|
254
|
+
/**
|
|
255
|
+
* The address of the smart wallet.
|
|
256
|
+
*/
|
|
257
|
+
get address(): `0x${string}`;
|
|
258
|
+
/**
|
|
259
|
+
* @returns The transaction hash.
|
|
260
|
+
*/
|
|
261
|
+
transferToken(toAddress: string, config: TransferType): Promise<string>;
|
|
262
|
+
/**
|
|
263
|
+
* @returns A list of NFTs owned by the wallet.
|
|
264
|
+
*/
|
|
265
|
+
nfts(): Promise<any>;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
declare class SmartWalletSDK extends LoggerWrapper {
|
|
269
|
+
private readonly smartWalletService;
|
|
270
|
+
private readonly errorProcessor;
|
|
271
|
+
private constructor();
|
|
272
|
+
/**
|
|
273
|
+
* Initializes the SDK with the **client side** API key obtained from the Crossmint console.
|
|
274
|
+
* @throws error if the api key is not formatted correctly.
|
|
275
|
+
*/
|
|
276
|
+
static init({ clientApiKey }: SmartWalletSDKInitParams): SmartWalletSDK;
|
|
277
|
+
/**
|
|
278
|
+
* Retrieves or creates a wallet for the specified user.
|
|
279
|
+
* The default configuration is a `PasskeySigner` with the name, which is displayed to the user during creation or signing prompts, derived from the provided jwt.
|
|
280
|
+
*
|
|
281
|
+
* Example using the default passkey signer:
|
|
282
|
+
* ```ts
|
|
283
|
+
* const wallet = await smartWalletSDK.getOrCreateWallet({ jwt: "xxx" }, "base");
|
|
284
|
+
* ```
|
|
285
|
+
*/
|
|
286
|
+
getOrCreateWallet(user: UserParams, chain: EVMBlockchainIncludingTestnet, walletParams?: WalletParams): Promise<EVMSmartWallet>;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
export { AdminAlreadyUsedError, AdminMismatchError, ConfigError, CrossmintServiceError, type EOASigner, type ERC20TransferType, EVMSmartWallet, JWTDecryptionError, JWTExpiredError, JWTIdentifierError, JWTInvalidError, type NFTTransferType, NonCustodialWalletsNotEnabledError, NotAuthorizedError, OutOfCreditsError, PasskeyMismatchError, type PasskeySigner, type SFTTransferType, SmartWalletSDK, SmartWalletSDKError, type SmartWalletSDKInitParams, TransferError, type TransferType, type UserParams, UserWalletAlreadyCreatedError, type ViemAccount, type WalletParams };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var it=Object.defineProperty,ct=Object.defineProperties;var lt=Object.getOwnPropertyDescriptors;var Te=Object.getOwnPropertySymbols;var pt=Object.prototype.hasOwnProperty,dt=Object.prototype.propertyIsEnumerable;var Se=(r,e,t)=>e in r?it(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,u=(r,e)=>{for(var t in e||(e={}))pt.call(e,t)&&Se(r,t,e[t]);if(Te)for(var t of Te(e))dt.call(e,t)&&Se(r,t,e[t]);return r},f=(r,e)=>ct(r,lt(e));var i=(r,e,t)=>new Promise((n,o)=>{var a=m=>{try{c(t.next(m))}catch(p){o(p)}},s=m=>{try{c(t.throw(m))}catch(p){o(p)}},c=m=>m.done?n(m.value):Promise.resolve(m.value).then(a,s);c((t=t.apply(r,e)).next())});import{EVMBlockchainIncludingTestnet as Ko,blockchainToChainId as Lo}from"@crossmint/common-sdk-base";function $(){return typeof window!="undefined"}function J(){return process.env.NODE_ENV==="test"?!1:window.location.origin.includes("localhost")}function Z(r,e){return(r==null?void 0:r.toLowerCase())===(e==null?void 0:e.toLowerCase())}var ie=!1,Y=class{logInfo(e,t){ie&&console.log(e,t)}logError(e,t){ie&&console.error(e,t)}logWarn(e,t){ie&&console.warn(e,t)}};var he="ZeroDev";var Ie="pub035be8a594b35be1887b6ba76c4029ca",Re="http://localhost:3000/api",_e="https://staging.crossmint.com/api",Ae="https://www.crossmint.com/api",De="9ee29857-8077-404b-9a9a-31eeea996a4a",Oe="023d4a21-d801-4450-b629-24439ab1369d",we="3d166617-da86-494b-9348-e8a13343bc04",Ce="e9314f9e-a13d-414f-b965-c591a0248243",be="1641cd99-c1ef-404a-9d26-a9dc67b1ba51",ke="3cfecfb6-9d7d-4ef6-acaa-ac8f79f6cd5a",ve="7ff22858-06f0-4f3a-8b46-5b41d8c75d0e",xe="3b24773b-d91e-4c01-8ce5-04807463bbca",We="d54706a0-304b-419e-8a33-03c26ba3f0e9",Ve="ce986d52-4f27-4a2b-b429-eb2322f15f32",Me="6204f336-643f-41af-94e1-f8d146c91675",Ne="3eb830c5-f91b-48e0-bb7d-dc30103a60b2",Be="6188b92b-993e-4f39-be22-56e4806416a8",Ue="8b8b6d1a-184c-4198-8f29-c07e63aad595",Ke="5535aa3b-4f9c-45af-9c38-0072369564a3",Le="b6a6db7c-65de-4f74-9d8f-f70d9c083531";var T="SCW_SDK",$e="0.1.0",ce="2024-06-09",Je="https://rpc.zerodev.app/api/v2/bundler/",Ze="https://rpc.zerodev.app/api/v2/paymaster/",F="https://api.developer.coinbase.com/rpc/v1/base-sepolia/6BTAmOQZ0x1YWtI24hIKKqdHWmVP1UXf",H="https://api.developer.coinbase.com/rpc/v1/base/6BTAmOQZ0x1YWtI24hIKKqdHWmVP1UXf";import{datadogLogs as pe}from"@datadog/browser-logs";var D=class{logInfo(e,t){le(e,"info",t)}logError(e,t){le(e,"error",t)}logWarn(e,t){le(e,"warn",t)}};function le(r,e,t){let n=t?f(u({},t),{service:T}):{service:T};mt(),pe.logger[e](r,n)}function mt(){pe.getInternalContext()==null&&pe.init({clientToken:Ie,site:"datadoghq.com",forwardErrorsToLogs:!1,sampleRate:100})}function ut(){return $()&&J()?new Y:new D}var{logInfo:G,logWarn:Ar,logError:I}=ut();import{isAddress as ze,publicActions as Tt}from"viem";var y={NOT_AUTHORIZED:"smart-wallet:not-authorized",TRANSFER:"smart-wallet:transfer.error",CROSSMINT_SERVICE:"smart-wallet:crossmint-service.error",ERROR_JWT_EXPIRED:"smart-wallet:not-authorized.jwt-expired",ERROR_JWT_INVALID:"smart-wallet:not-authorized.jwt-invalid",ERROR_JWT_DECRYPTION:"smart-wallet:not-authorized.jwt-decryption",ERROR_JWT_IDENTIFIER:"smart-wallet:not-authorized.jwt-identifier",ERROR_USER_WALLET_ALREADY_CREATED:"smart-wallet:user-wallet-already-created.error",ERROR_OUT_OF_CREDITS:"smart-wallet:out-of-credits.error",ERROR_WALLET_CONFIG:"smart-wallet:wallet-config.error",ERROR_ADMIN_MISMATCH:"smart-wallet:wallet-config.admin-mismatch",ERROR_PASSKEY_MISMATCH:"smart-wallet:wallet-config.passkey-mismatch",ERROR_ADMIN_SIGNER_ALREADY_USED:"smart-wallet:wallet-config.admin-signer-already-used",UNCATEGORIZED:"smart-wallet:uncategorized"},l=class extends Error{constructor(e,t,n=y.UNCATEGORIZED){super(e),this.details=t,this.code=n}},C=class extends l{constructor(e){super(e,void 0,y.TRANSFER)}},P=class extends l{constructor(e,t){super(e,void 0,y.CROSSMINT_SERVICE),this.status=t}},S=class extends l{constructor(e,t,n){super(e,y.ERROR_ADMIN_MISMATCH),this.required=t,this.used=n}},b=class extends l{constructor(e,t,n){super(e,y.ERROR_PASSKEY_MISMATCH),this.required=t,this.used=n}},R=class extends l{constructor(e){super(e,void 0,y.NOT_AUTHORIZED)}},k=class extends R{constructor(t){super(`JWT provided expired at timestamp ${t}`);this.code=y.ERROR_JWT_EXPIRED;this.expiredAt=t.toISOString()}},v=class extends R{constructor(){super("Invalid JWT provided");this.code=y.ERROR_JWT_INVALID}},x=class extends R{constructor(){super("Error decrypting JWT");this.code=y.ERROR_JWT_DECRYPTION}},W=class extends R{constructor(t){super(`Missing required identifier '${t}' in the JWT`);this.code=y.ERROR_JWT_IDENTIFIER;this.identifierKey=t}},_=class extends l{constructor(t){super(`The user with userId ${t.toString()} already has a wallet created for this project`);this.code=y.ERROR_USER_WALLET_ALREADY_CREATED}},V=class extends l{constructor(e){super("You've run out of Crossmint API credits. Visit https://docs.crossmint.com/docs/errors for more information",void 0,y.ERROR_OUT_OF_CREDITS)}},M=class extends l{constructor(e){super(e,void 0,y.ERROR_WALLET_CONFIG)}},N=class extends M{constructor(){super("This signer was already used to create another wallet. Please use a different signer.");this.code=y.ERROR_ADMIN_SIGNER_ALREADY_USED}},B=class extends M{constructor(){super("Non-custodial wallets are not enabled for this project")}};import{v4 as yt}from"uuid";var h=class{constructor(e,t={},n=yt()){this.extraInfo=t;this.logIdempotencyKey=n;return new Proxy(this,{get:(o,a,s)=>{let c=o[a],m=`[${T} - ${e} - ${String(a)}]`;return typeof c=="function"?(...p)=>{this.logInput(p,m);let d=c.apply(o,p);return d instanceof Promise?d.then(E=>(this.logOutput(E,m),E)).catch(E=>{throw this.logError(E,m),E}):(this.logOutput(d,m),d)}:Reflect.get(o,a,s)}})}logInput(e,t){O(`${t} input - ${g(e)} - extra_info - ${g(this.extraInfo)} - log_idempotency_key - ${this.logIdempotencyKey}`,f(u({args:e},this.extraInfo),{logIdempotencyKey:this.logIdempotencyKey}))}logOutput(e,t){O(`${t} output - ${g(e)} - extra_info - ${g(this.extraInfo)} - log_idempotency_key - ${this.logIdempotencyKey}`,f(u({res:e},this.extraInfo),{logIdempotencyKey:this.logIdempotencyKey}))}logError(e,t){I(`${t} threw_error - ${e} - extra_info - ${g(this.extraInfo)} - log_idempotency_key - ${this.logIdempotencyKey}`,u({err:e},this.extraInfo))}logPerformance(e,t){return A(e,t,this.extraInfo)}};function A(r,e,t){return i(this,null,function*(){let n=new Date().getTime(),o=yield e(),a=new Date().getTime()-n,s=u({durationInMs:a},t);return O(`[${T} - ${r} - TIME] - ${g(s)}`,{args:s}),o})}function Ye(r,e){return function(...t){let n=`[${T} - function: ${e}]`;O(`${n} input: ${g(t)}`,{args:t});try{let o=r.apply(this,t);return o instanceof Promise?o.then(a=>(O(`${n} output: ${g(a)}`,{res:a}),a)).catch(a=>{throw I(`${n} threw_error: ${g(a)}`,{err:a}),a}):(O(`${n} output: ${g(o)}`,{res:o}),o)}catch(o){throw I(`${n} threw_error: ${g(o)}`,{err:o}),o}}}function g(r){try{return r!=null?JSON.stringify(r,null,2):r}catch(e){return Et(r)}}function Et(r){let e={};for(let t in r)Object.prototype.hasOwnProperty.call(r,t)&&typeof r[t]!="object"&&typeof r[t]!="function"&&(e[t]=r[t]);return JSON.stringify(e,null,2)}function O(r,e){if(J()){console.log(r);return}G(r,e)}function Fe(r){var t;let e=r instanceof Error?r:{message:"Unknown error",name:"Unknown error"};if(!(e instanceof Error)&&((t=e.constructor)==null?void 0:t.name)!=="SyntheticBaseEvent")throw I("ERROR_TO_JSON_FAILED",{error:e}),new Error("[errorToJSON] err is not instanceof Error nor SyntheticBaseEvent");return JSON.parse(JSON.stringify(e,Object.getOwnPropertyNames(e)))}import{erc20Abi as Pt,erc721Abi as gt}from"viem";var He=[{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 Ge({contract:r,config:e,from:t,to:n}){switch(e.token.type){case"ft":return{account:t,address:r,abi:Pt,functionName:"transfer",args:[n,e.amount]};case"sft":return{account:t,address:r,abi:He,functionName:"safeTransferFrom",args:[t.address,n,e.token.tokenId,e.quantity,"0x00"],tokenId:e.token.tokenId};case"nft":return{account:t,address:r,abi:gt,functionName:"safeTransferFrom",args:[t.address,n,e.token.tokenId],tokenId:e.token.tokenId}}}var U=class extends h{constructor(t,n,o,a){super("EVMSmartWallet",{chain:a,address:n.account.address});this.crossmintService=t;this.accountClient=n;this.chain=a,this.client={wallet:n,public:o}}get address(){return this.accountClient.account.address}transferToken(t,n){return i(this,null,function*(){return this.logPerformance("TRANSFER",()=>i(this,null,function*(){if(this.chain!==n.token.chain)throw new Error(`Chain mismatch: Expected ${n.token.chain}, but got ${this.chain}. Ensure you are interacting with the correct blockchain.`);if(!ze(t))throw new Error(`Invalid recipient address: '${t}' is not a valid EVM address.`);if(!ze(n.token.contractAddress))throw new Error(`Invalid contract address: '${n.token.contractAddress}' is not a valid EVM address.`);let o=Ge({contract:n.token.contractAddress,to:t,from:this.accountClient.account,config:n});try{let a=this.accountClient.extend(Tt),{request:s}=yield a.simulateContract(o);return yield a.writeContract(s)}catch(a){I("[TRANSFER] - ERROR_TRANSFERRING_TOKEN",{service:T,error:Fe(a),tokenId:o.tokenId,contractAddress:n.token.contractAddress,chain:n.token.chain});let s=o.tokenId==null?"":`:${o.tokenId}}`;throw new C(`Error transferring token ${n.token.contractAddress}${s}`)}}))})}nfts(){return i(this,null,function*(){return this.crossmintService.fetchNFTs(this.address,this.chain)})}};import{stringify as pr}from"viem";import{validateAPIKey as dr}from"@crossmint/common-sdk-base";import{validateAPIKey as St}from"@crossmint/common-sdk-base";var z=class{constructor(e={ERROR_JWT_INVALID:()=>new v,ERROR_JWT_DECRYPTION:()=>new x,ERROR_JWT_EXPIRED:({expiredAt:t})=>new k(new Date(t)),ERROR_JWT_IDENTIFIER:({identifierKey:t})=>new W(t),ERROR_USER_WALLET_ALREADY_CREATED:({userId:t})=>new _(t),ERROR_ADMIN_SIGNER_ALREADY_USED:()=>new N,ERROR_PROJECT_NONCUSTODIAL_WALLETS_NOT_ENABLED:()=>new B}){this.errors=e}throwErrorFromResponse(n){return i(this,arguments,function*({response:e,onServerErrorMessage:t}){if(!e.ok){if(e.status>=500)throw new P(t,e.status);if(e.status===402)throw new V;try{let o=yield e.json(),a=o.code;if(a!=null&&this.errors[a]!=null)throw this.errors[a](o);if(o.message!=null)throw new P(o.message,e.status)}catch(o){console.error("Error parsing response",o)}throw new P(yield e.text(),e.status)}})}};var K=class K extends h{constructor(e){super("BaseCrossmintService");let t=St(e);if(!t.isValid)throw new Error("API key invalid");this.crossmintAPIHeaders={accept:"application/json","content-type":"application/json","x-api-key":e},this.crossmintBaseUrl=this.getUrlFromEnv(t.environment),this.apiErrorService=new z}fetchCrossmintAPI(a){return i(this,arguments,function*(e,t={method:"GET"},n,o){return A("FETCH_CROSSMINT_API",()=>i(this,null,function*(){let s=`${this.crossmintBaseUrl}/${e}`,{body:c,method:m}=t,p;try{p=yield fetch(s,{body:c,method:m,headers:u(u({},this.crossmintAPIHeaders),o!=null&&{Authorization:`Bearer ${o}`})})}catch(d){throw new P(`Error fetching Crossmint API: ${d}`)}return p.ok||(yield this.apiErrorService.throwErrorFromResponse({response:p,onServerErrorMessage:n})),yield p.json()}),{endpoint:e})})}getUrlFromEnv(e){let t=K.urlMap[e];if(!t)throw console.log(" CrossmintService.urlMap: ",K.urlMap),new Error(`URL not found for environment: ${e}`);return t}};K.urlMap={development:Re,staging:_e,production:Ae};var j=K;import{EVMBlockchainIncludingTestnet as dn}from"@crossmint/common-sdk-base";var q=class extends j{idempotentCreateSmartWallet(e,t){return i(this,null,function*(){return this.fetchCrossmintAPI(`${ce}/sdk/smart-wallet`,{method:"PUT",body:JSON.stringify(t)},"Error creating abstract wallet. Please contact support",e.jwt)})}getSmartWalletConfig(e,t){return i(this,null,function*(){return this.fetchCrossmintAPI(`${ce}/sdk/smart-wallet/config?chain=${t}`,{method:"GET"},"Error getting smart wallet version configuration. Please contact support",e.jwt)})}fetchNFTs(e,t){return i(this,null,function*(){return this.fetchCrossmintAPI(`v1-alpha1/wallets/${t}:${e}/nfts`,{method:"GET"},`Error fetching NFTs for wallet: ${e}`)})}getPasskeyServerUrl(){return this.crossmintBaseUrl+"/internal/passkeys"}};import{EVMBlockchainIncludingTestnet as X}from"@crossmint/common-sdk-base";function ht(r){return[X.ZKYOTO,X.ZKATANA,X.ASTAR_ZKEVM,X.HYPERSONIC_TESTNET].includes(r)}function Q(r){return ht(r)}import{stringify as je}from"viem";var It=["sendTransaction","writeContract","sendUserOperation"],Rt=["signMessage","signTypedData"];function de(r){return It.includes(r)}function _t(r){return Rt.includes(r)}var ee=class{constructor(e){this.errorProcessor=e}decorate({crossmintChain:e,smartAccountClient:t}){return new Proxy(t,{get:(n,o,a)=>{let s=Reflect.get(n,o,a);return typeof s!="function"||typeof o!="string"||!(_t(o)||de(o))?s:(...c)=>A(`CrossmintSmartWallet.${o}`,()=>this.execute(n,o,s,c,e))}})}execute(e,t,n,o,a){return i(this,null,function*(){try{G(`[CrossmintSmartWallet.${t}] - params: ${je(o)}`);let s=de(t)?this.processTxnArgs(t,a,o):o;return yield n.call(e,...s)}catch(s){let c=de(t)?"signing":"sending transaction";throw this.errorProcessor.map(s,new l(`Error ${c}: ${s.message}`,je(s)))}})}processTxnArgs(e,t,n){if(e==="sendUserOperation"){let[{userOperation:a,middleware:s,account:c}]=n;return[{middleware:s,account:c,userOperation:this.addGelatoBundlerProperties(t,a)},...n.slice(1)]}let[o]=n;return[this.addGelatoBundlerProperties(t,o),...n.slice(1)]}addGelatoBundlerProperties(e,t){return Q(e)?f(u({},t),{maxFeePerGas:"0x0",maxPriorityFeePerGas:"0x0"}):t}};function te(r){return{pubKeyX:r.pubKeyX,pubKeyY:r.pubKeyY,passkeyName:r.passkeyName,type:"passkeys"}}import{createKernelAccountClient as rr}from"@zerodev/sdk";import{ENTRYPOINT_ADDRESS_V06 as nr,ENTRYPOINT_ADDRESS_V07 as or}from"permissionless";import{createPublicClient as ar,getAddress as sr,http as at}from"viem";import{blockchainToChainId as ir}from"@crossmint/common-sdk-base";var me=["0.3.1","0.3.0","0.2.4"];function qe(r){return me.includes(r)}var ue=["v0.6","v0.7"];function Xe(r){return ue.includes(r)}import{arbitrum as At,arbitrumNova as Dt,arbitrumSepolia as Ot,astarZkEVM as wt,astarZkyoto as Ct,base as bt,baseSepolia as kt,bsc as vt,goerli as xt,mainnet as Wt,optimism as Vt,optimismSepolia as Mt,polygon as Nt,polygonAmoy as Bt,sepolia as Ut}from"viem/chains";import{EVMBlockchainIncludingTestnet as Qe}from"@crossmint/common-sdk-base";var ye=r=>{let e=new Map([["ethereum",De],["polygon",Oe],["bsc",we],["optimism",Ce],["arbitrum",be],["ethereum-goerli",ke],["ethereum-sepolia",ve],["polygon-amoy",xe],["zkatana",We],["zkyoto",Ve],["arbitrum-sepolia",Ue],["base-goerli",null],["base-sepolia",Ne],["bsc-testnet",null],["optimism-goerli",null],["optimism-sepolia",Be],["zora-goerli",null],["zora-sepolia",null],["base",Ke],["zora",null],["arbitrumnova",Le],["astar-zkevm",Me],["apex",null]]).get(r);if(e==null)throw new Error(`ZeroDev project id not found for chain ${r}`);return e},re=r=>{switch(r){case"ethereum":return Wt;case"ethereum-goerli":return xt;case"ethereum-sepolia":return Ut;case"polygon":return Nt;case"polygon-amoy":return Bt;case"optimism":return Vt;case"optimism-sepolia":return Mt;case"arbitrum":return At;case"arbitrumnova":return Dt;case"arbitrum-sepolia":return Ot;case"base":return bt;case"base-sepolia":return kt;case"zkyoto":return Ct;case"astar-zkevm":return wt;case"bsc":return vt;default:throw new Error(`Unsupported network: ${r}`)}},Ee=r=>{switch(r){case Qe.BASE_SEPOLIA:return F;case Qe.BASE:return H;default:return Je+ye(r)+"?bundlerProvider=STACKUP"}};import{providerToSmartAccountSigner as Kt}from"permissionless";var et=Ye(e=>i(void 0,[e],function*({walletParams:r}){if(Lt(r.signer))return yield Kt(r.signer);if($t(r.signer))return r.signer.account;{let t=r.signer;throw new l(`The signer type ${t.type} is not supported`)}}),"createOwnerSigner");function Lt(r){return r&&typeof r.request=="function"}function $t(r){return r&&r.type==="VIEM_ACCOUNT"}import{signerToEcdsaValidator as Jt}from"@zerodev/ecdsa-validator";import{createKernelAccount as Zt}from"@zerodev/sdk";var ne=class{get(m,p){return i(this,arguments,function*({chain:e,publicClient:t,entryPoint:n,walletParams:o,kernelVersion:a,user:s},c){let d=yield et({chain:e,walletParams:o});if(c!=null&&!Z(d.address,c.eoaAddress))throw new S(`User '${s.id}' has an existing wallet with an eoa signer '${c.eoaAddress}', this does not match input eoa signer '${d.address}'.`,c,{type:"eoa",eoaAddress:c.eoaAddress});let E=yield Jt(t,{signer:d,entryPoint:n.address,kernelVersion:a});return{account:yield Zt(t,{plugins:{sudo:E},index:BigInt(0),entryPoint:n.address,kernelVersion:a}),signerData:{eoaAddress:d.address,type:"eoa"}}})}};import{PasskeyValidatorContractVersion as Yt,WebAuthnMode as Ft,toPasskeyValidator as Ht}from"@zerodev/passkey-validator";import{createKernelAccount as Gt}from"@zerodev/sdk";import{toWebAuthnKey as zt}from"@zerodev/webauthn-key";function tt(r){return r.walletParams.signer.type==="PASSKEY"}var oe=class{constructor(e){this.crossmintService=e}get(c,m){return i(this,arguments,function*({user:e,publicClient:t,walletParams:n,entryPoint:o,kernelVersion:a},s){var ge;let p=(ge=n.signer.passkeyName)!=null?ge:e.id;if(s!=null&&s.passkeyName!==p)throw new b(`User '${e.id}' has an existing wallet created with a passkey named '${s.passkeyName}', this does match input passkey name '${p}'.`,te(s));let d=yield this.getPasskey(e,p,s),E=Yt.V0_0_2,w=s==null?E:s.validatorContractVersion,L=yield Ht(t,{webAuthnKey:d,entryPoint:o.address,validatorContractVersion:w,kernelVersion:a}),st=yield Gt(t,{plugins:{sudo:L},entryPoint:o.address,kernelVersion:a});return{signerData:this.getSignerData(L,w,p),account:st}})}getPasskey(e,t,n){return i(this,null,function*(){return n!=null?{pubX:BigInt(n.pubKeyX),pubY:BigInt(n.pubKeyY),authenticatorId:n.authenticatorId,authenticatorIdHash:n.authenticatorIdHash}:zt({passkeyName:t,passkeyServerUrl:this.crossmintService.getPasskeyServerUrl(),mode:Ft.Register,passkeyServerHeaders:this.createPasskeysServerHeaders(e)})})}getSignerData(e,t,n){return f(u({},jt(e.getSerializedData())),{passkeyName:n,validatorContractVersion:t,domain:window.location.hostname,type:"passkeys"})}createPasskeysServerHeaders(e){return{"x-api-key":this.crossmintService.crossmintAPIHeaders["x-api-key"],Authorization:`Bearer ${e.jwt}`}}},jt=r=>{let e=qt(r),t=new TextDecoder().decode(e);return JSON.parse(t)};function qt(r){let e=atob(r);return Uint8Array.from(e,t=>t.codePointAt(0))}import{createZeroDevPaymasterClient as Xt}from"@zerodev/sdk";import{http as Qt}from"viem";import{EVMBlockchainIncludingTestnet as rt}from"@crossmint/common-sdk-base";function nt(r){return!Q(r)}var er=r=>{switch(r){case rt.BASE_SEPOLIA:return F;case rt.BASE:return H;default:return Ze+ye(r)+"?paymasterProvider=STACKUP"}};function ot({entryPoint:r,chain:e}){return{middleware:{sponsorUserOperation:n=>i(this,[n],function*({userOperation:t}){return Xt({chain:re(e),transport:Qt(er(e)),entryPoint:r}).sponsorUserOperation({userOperation:t,entryPoint:r})})}}}var ae=class{constructor(e,t,n=new fe(new ne,new oe(e))){this.crossmintWalletService=e;this.clientDecorator=t;this.accountFactory=n}getOrCreate(e,t,n){return i(this,null,function*(){let{entryPoint:o,kernelVersion:a,existingSignerConfig:s,smartContractWalletAddress:c,userId:m}=yield this.fetchConfig(e,t),p=ar({transport:at(Ee(t))}),{account:d,signerData:E}=yield this.accountFactory.get({chain:t,walletParams:n,publicClient:p,user:f(u({},e),{id:m}),entryPoint:o,kernelVersion:a},s);if(c!=null&&!Z(c,d.address))throw new _(m);s==null&&(yield this.crossmintWalletService.idempotentCreateSmartWallet(e,{type:he,smartContractWalletAddress:d.address,signerData:E,version:0,baseLayer:"evm",chainId:ir(t),entryPointVersion:o.version,kernelVersion:a}));let w=rr(u({account:d,chain:re(t),entryPoint:d.entryPoint,bundlerTransport:at(Ee(t))},nt(t)&&ot({entryPoint:d.entryPoint,chain:t}))),L=this.clientDecorator.decorate({crossmintChain:t,smartAccountClient:w});return new U(this.crossmintWalletService,L,p,t)})}fetchConfig(e,t){return i(this,null,function*(){let{entryPointVersion:n,kernelVersion:o,signers:a,smartContractWalletAddress:s,userId:c}=yield this.crossmintWalletService.getSmartWalletConfig(e,t);if(!qe(o))throw new l(`Unsupported kernel version. Supported versions: ${me.join(", ")}. Version used: ${o}, Please contact support`);if(!Xe(n))throw new l(`Unsupported entry point version. Supported versions: ${ue.join(", ")}. Version used: ${n}. Please contact support`);if(n==="v0.7"&&o.startsWith("0.2")||n==="v0.6"&&o.startsWith("0.3"))throw new l(`Unsupported combination: entryPoint ${n} and kernel version ${o}. Please contact support`);return{entryPoint:{version:n,address:n==="v0.6"?nr:or},kernelVersion:o,userId:c,existingSignerConfig:this.getSigner(a),smartContractWalletAddress:s!=null?sr(s):void 0}})}getSigner(e){if(e.length!==0){if(e.length>1)throw new P("Invalid wallet signer configuration. Please contact support");return e[0].signerData}}},fe=class{constructor(e,t){this.eoa=e;this.passkey=t}get(e,t){if(tt(e)){if(t!=null&&(t==null?void 0:t.type)!=="passkeys")throw new S(`Cannot create wallet with passkey signer for user '${e.user.id}', they have an existing wallet with eoa signer '${t.eoaAddress}.'`,t);return this.passkey.get(e,t)}if(t!=null&&(t==null?void 0:t.type)!=="eoa")throw new S(`Cannot create wallet with eoa signer for user '${e.user.id}', they already have a wallet with a passkey named '${t.passkeyName}' as it's signer.`,te(t));return this.eoa.get(e,t)}};import{BaseError as cr,stringify as lr}from"viem";var se=class{constructor(e){this.logger=e}map(e,t){return this.record(e),e instanceof l||e instanceof cr?e:t}record(e){let t=e instanceof Error?e.message:String(e);this.logger.logError(`Smart Wallet SDK Error: ${t}`,{stack:e instanceof Error?e.stack:void 0,name:e instanceof Error?e.name:"UnknownError",details:lr(e),domain:window.location.hostname,sdk_version:$e})}};var Pe=class r extends h{constructor(t,n){super("SmartWalletSDK");this.smartWalletService=t;this.errorProcessor=n}static init({clientApiKey:t}){if(!$())throw new l("Smart Wallet SDK should only be used client side.");if(!dr(t).isValid)throw new Error("API key invalid");let o=new q(t),a=new se(new D);return new r(new ae(o,new ee(a)),a)}getOrCreateWallet(a,s){return i(this,arguments,function*(t,n,o={signer:{type:"PASSKEY"}}){return A("GET_OR_CREATE_WALLET",()=>i(this,null,function*(){try{return yield this.smartWalletService.getOrCreate(t,n,o)}catch(c){throw this.errorProcessor.map(c,new l(`Wallet creation failed: ${c.message}.`,pr(c)))}}),{user:t,chain:n})})}};export{N as AdminAlreadyUsedError,S as AdminMismatchError,Ko as Blockchain,M as ConfigError,P as CrossmintServiceError,U as EVMSmartWallet,x as JWTDecryptionError,k as JWTExpiredError,W as JWTIdentifierError,v as JWTInvalidError,B as NonCustodialWalletsNotEnabledError,R as NotAuthorizedError,V as OutOfCreditsError,b as PasskeyMismatchError,Pe as SmartWalletSDK,l as SmartWalletSDKError,C as TransferError,_ as UserWalletAlreadyCreatedError,Lo as blockchainToChainId};
|
|
2
|
+
//# sourceMappingURL=index.js.map
|