@crossmint/client-sdk-smart-wallet 0.1.15 → 0.1.17
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.cjs +4 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +36 -9
- package/dist/index.d.ts +36 -9
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/SmartWalletSDK.ts +3 -9
- package/src/blockchain/chains.ts +2 -2
- package/src/blockchain/rpc.ts +1 -1
- package/src/blockchain/transfer.ts +1 -1
- package/src/blockchain/wallets/EVMSmartWallet.ts +33 -69
- package/src/blockchain/wallets/SendTransactionService.test.ts +51 -55
- package/src/blockchain/wallets/SendTransactionService.ts +12 -10
- package/src/blockchain/wallets/account/cache.test.ts +1 -1
- package/src/blockchain/wallets/account/cache.ts +1 -1
- package/src/blockchain/wallets/account/config.test.ts +3 -3
- package/src/blockchain/wallets/account/config.ts +1 -1
- package/src/blockchain/wallets/account/creator.ts +2 -2
- package/src/blockchain/wallets/account/eoa.ts +1 -1
- package/src/blockchain/wallets/account/passkey.ts +5 -2
- package/src/blockchain/wallets/account/strategy.ts +1 -1
- package/src/blockchain/wallets/clientDecorator.ts +6 -4
- package/src/blockchain/wallets/paymaster.ts +6 -6
- package/src/blockchain/wallets/service.ts +6 -7
- package/src/error/index.ts +1 -1
- package/src/error/processor.ts +1 -1
- package/src/index.ts +0 -1
- package/src/types/service.ts +1 -1
- package/src/types/token.ts +3 -1
- package/src/utils/blockchain.ts +1 -1
- package/src/utils/constants.ts +3 -1
- package/src/utils/signer.ts +3 -3
- package/src/utils/test.ts +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crossmint/client-sdk-smart-wallet",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.17",
|
|
4
4
|
"repository": "https://github.com/Crossmint/crossmint-sdk",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Paella Labs Inc",
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
"permissionless": "0.1.36",
|
|
27
27
|
"viem": "2.17.5",
|
|
28
28
|
"zod": "3.22.4",
|
|
29
|
-
"@crossmint/
|
|
30
|
-
"@crossmint/
|
|
29
|
+
"@crossmint/client-sdk-base": "1.2.7",
|
|
30
|
+
"@crossmint/common-sdk-base": "0.1.4"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"typedoc": "0.26.5",
|
package/src/SmartWalletSDK.ts
CHANGED
|
@@ -1,15 +1,9 @@
|
|
|
1
1
|
import { stringify } from "viem";
|
|
2
2
|
|
|
3
|
-
import { APIKeyEnvironmentPrefix, validateAPIKey } from "@crossmint/common-sdk-base";
|
|
3
|
+
import { type APIKeyEnvironmentPrefix, validateAPIKey } from "@crossmint/common-sdk-base";
|
|
4
4
|
|
|
5
5
|
import { CrossmintWalletService } from "./api/CrossmintWalletService";
|
|
6
|
-
import {
|
|
7
|
-
SMART_WALLET_MAINNETS,
|
|
8
|
-
SMART_WALLET_TESTNETS,
|
|
9
|
-
type SmartWalletChain,
|
|
10
|
-
isMainnetChain,
|
|
11
|
-
isTestnetChain,
|
|
12
|
-
} from "./blockchain/chains";
|
|
6
|
+
import { type SmartWalletChain, isMainnetChain, isTestnetChain } from "./blockchain/chains";
|
|
13
7
|
import type { EVMSmartWallet } from "./blockchain/wallets";
|
|
14
8
|
import { AccountConfigCache } from "./blockchain/wallets/account/cache";
|
|
15
9
|
import { AccountConfigService } from "./blockchain/wallets/account/config";
|
|
@@ -80,7 +74,7 @@ export class SmartWalletSDK {
|
|
|
80
74
|
}
|
|
81
75
|
this.assertValidChain(chain);
|
|
82
76
|
|
|
83
|
-
return this.logger.logPerformance("GET_OR_CREATE_WALLET", async () => {
|
|
77
|
+
return await this.logger.logPerformance("GET_OR_CREATE_WALLET", async () => {
|
|
84
78
|
try {
|
|
85
79
|
return await this.smartWalletService.getOrCreate(user, chain, walletParams);
|
|
86
80
|
} catch (error: any) {
|
package/src/blockchain/chains.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
-
Chain,
|
|
2
|
+
type Chain,
|
|
3
3
|
arbitrum,
|
|
4
4
|
arbitrumSepolia,
|
|
5
5
|
base,
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
polygonAmoy,
|
|
11
11
|
} from "viem/chains";
|
|
12
12
|
|
|
13
|
-
import { BlockchainIncludingTestnet as Blockchain, ObjectValues, objectValues } from "@crossmint/common-sdk-base";
|
|
13
|
+
import { BlockchainIncludingTestnet as Blockchain, type ObjectValues, objectValues } from "@crossmint/common-sdk-base";
|
|
14
14
|
|
|
15
15
|
export const SmartWalletTestnet = {
|
|
16
16
|
BASE_SEPOLIA: Blockchain.BASE_SEPOLIA,
|
package/src/blockchain/rpc.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { blockchainToChainId } from "@crossmint/common-sdk-base";
|
|
2
2
|
|
|
3
|
-
import { SmartWalletChain } from "./chains";
|
|
3
|
+
import type { SmartWalletChain } from "./chains";
|
|
4
4
|
|
|
5
5
|
const ALCHEMY_API_KEY = "-7M6vRDBDknwvMxnqah_jbcieWg0qad9";
|
|
6
6
|
const PIMLICO_API_KEY = "pim_9dKmQPxiTCvtbUNF7XFBbA";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Abi, Account, Address, erc20Abi, erc721Abi } from "viem";
|
|
1
|
+
import { type Abi, type Account, type Address, erc20Abi, erc721Abi } from "viem";
|
|
2
2
|
|
|
3
3
|
import erc1155Abi from "../ABI/ERC1155.json";
|
|
4
4
|
import type { ERC20TransferType, SFTTransferType, TransferType } from "../types/token";
|
|
@@ -1,24 +1,21 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type {
|
|
2
2
|
Abi,
|
|
3
|
+
Address,
|
|
3
4
|
ContractFunctionArgs,
|
|
4
5
|
ContractFunctionName,
|
|
5
6
|
Hex,
|
|
6
|
-
|
|
7
|
-
|
|
7
|
+
HttpTransport,
|
|
8
|
+
PublicClient,
|
|
8
9
|
WriteContractParameters,
|
|
9
|
-
isAddress,
|
|
10
|
-
publicActions,
|
|
11
10
|
} from "viem";
|
|
12
11
|
|
|
13
|
-
import { TransferError } from "@crossmint/client-sdk-base";
|
|
14
|
-
|
|
15
12
|
import type { CrossmintWalletService } from "../../api/CrossmintWalletService";
|
|
16
|
-
import {
|
|
17
|
-
import { SmartWalletClient } from "../../types/internal";
|
|
13
|
+
import { SmartWalletError } from "../../error";
|
|
14
|
+
import type { SmartWalletClient } from "../../types/internal";
|
|
18
15
|
import type { TransferType } from "../../types/token";
|
|
19
|
-
import { SmartWalletChain } from "../chains";
|
|
16
|
+
import type { SmartWalletChain } from "../chains";
|
|
20
17
|
import { transferParams } from "../transfer";
|
|
21
|
-
import { SendTransactionOptions, SendTransactionService } from "./SendTransactionService";
|
|
18
|
+
import { type SendTransactionOptions, SendTransactionService } from "./SendTransactionService";
|
|
22
19
|
|
|
23
20
|
/**
|
|
24
21
|
* Smart wallet interface for EVM chains enhanced with Crossmint capabilities.
|
|
@@ -41,79 +38,47 @@ export class EVMSmartWallet {
|
|
|
41
38
|
*/
|
|
42
39
|
public: PublicClient;
|
|
43
40
|
};
|
|
44
|
-
private readonly sendTransactionService: SendTransactionService;
|
|
45
41
|
|
|
46
42
|
constructor(
|
|
47
|
-
|
|
48
|
-
private readonly accountClient: SmartWalletClient,
|
|
49
|
-
publicClient: PublicClient<HttpTransport>,
|
|
43
|
+
client: { public: PublicClient<HttpTransport>; wallet: SmartWalletClient },
|
|
50
44
|
chain: SmartWalletChain,
|
|
51
|
-
|
|
45
|
+
private readonly crossmintService: CrossmintWalletService,
|
|
46
|
+
private readonly sendTransactionService = new SendTransactionService(client)
|
|
52
47
|
) {
|
|
53
48
|
this.chain = chain;
|
|
54
|
-
this.client =
|
|
55
|
-
wallet: accountClient,
|
|
56
|
-
public: publicClient,
|
|
57
|
-
};
|
|
58
|
-
this.sendTransactionService = new SendTransactionService(publicClient);
|
|
49
|
+
this.client = client;
|
|
59
50
|
}
|
|
60
51
|
|
|
61
52
|
/**
|
|
62
53
|
* The address of the smart wallet.
|
|
63
54
|
*/
|
|
64
55
|
public get address() {
|
|
65
|
-
return this.
|
|
56
|
+
return this.client.wallet.account.address;
|
|
66
57
|
}
|
|
67
58
|
|
|
68
59
|
/**
|
|
60
|
+
* Transfers tokens from the smart wallet to a specified address.
|
|
61
|
+
* @param toAddress The recipient's address.
|
|
62
|
+
* @param config The transfer configuration, including token details and amount.
|
|
69
63
|
* @returns The transaction hash.
|
|
64
|
+
* @throws {SmartWalletError} If there's a chain mismatch between this wallet and the input configuration.
|
|
65
|
+
* @throws {SendTransactionError} If the transaction fails to send. Contains the error thrown by the viem client.
|
|
66
|
+
* @throws {SendTransactionExecutionRevertedError} A subclass of SendTransactionError if the transaction fails due to a contract execution error.
|
|
70
67
|
*/
|
|
71
|
-
public async transferToken(toAddress:
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
`Chain mismatch: Expected ${config.token.chain}, but got ${this.chain}. Ensure you are interacting with the correct blockchain.`
|
|
78
|
-
);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
if (!isAddress(toAddress)) {
|
|
82
|
-
throw new Error(`Invalid recipient address: '${toAddress}' is not a valid EVM address.`);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
if (!isAddress(config.token.contractAddress)) {
|
|
86
|
-
throw new Error(
|
|
87
|
-
`Invalid contract address: '${config.token.contractAddress}' is not a valid EVM address.`
|
|
88
|
-
);
|
|
89
|
-
}
|
|
68
|
+
public async transferToken(toAddress: Address, config: TransferType): Promise<string> {
|
|
69
|
+
if (this.chain !== config.token.chain) {
|
|
70
|
+
throw new SmartWalletError(
|
|
71
|
+
`Chain mismatch: Expected ${config.token.chain}, but got ${this.chain}. Ensure you are interacting with the correct blockchain.`
|
|
72
|
+
);
|
|
73
|
+
}
|
|
90
74
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
try {
|
|
99
|
-
const client = this.accountClient.extend(publicActions);
|
|
100
|
-
const { request } = await client.simulateContract(tx);
|
|
101
|
-
const hash = await client.writeContract(request);
|
|
102
|
-
this.logger.log(`[TRANSFER] - Transaction hash from transfer: ${hash}`);
|
|
103
|
-
|
|
104
|
-
return hash;
|
|
105
|
-
} catch (error) {
|
|
106
|
-
this.logger.error("[TRANSFER] - ERROR_TRANSFERRING_TOKEN", {
|
|
107
|
-
error: error instanceof Error ? error.message : JSON.stringify(error),
|
|
108
|
-
tokenId: tx.tokenId,
|
|
109
|
-
contractAddress: config.token.contractAddress,
|
|
110
|
-
chain: config.token.chain,
|
|
111
|
-
});
|
|
112
|
-
const tokenIdString = tx.tokenId == null ? "" : `:${tx.tokenId}}`;
|
|
113
|
-
throw new TransferError(`Error transferring token ${config.token.contractAddress}${tokenIdString}`);
|
|
114
|
-
}
|
|
115
|
-
},
|
|
116
|
-
{ toAddress, config }
|
|
75
|
+
return this.executeContract(
|
|
76
|
+
transferParams({
|
|
77
|
+
contract: config.token.contractAddress,
|
|
78
|
+
to: toAddress,
|
|
79
|
+
from: this.client.wallet.account,
|
|
80
|
+
config,
|
|
81
|
+
})
|
|
117
82
|
);
|
|
118
83
|
}
|
|
119
84
|
|
|
@@ -167,7 +132,7 @@ export class EVMSmartWallet {
|
|
|
167
132
|
TAbi,
|
|
168
133
|
"nonpayable" | "payable",
|
|
169
134
|
TFunctionName
|
|
170
|
-
|
|
135
|
+
>,
|
|
171
136
|
>({
|
|
172
137
|
address,
|
|
173
138
|
abi,
|
|
@@ -186,7 +151,6 @@ export class EVMSmartWallet {
|
|
|
186
151
|
args,
|
|
187
152
|
value,
|
|
188
153
|
},
|
|
189
|
-
this.accountClient,
|
|
190
154
|
config
|
|
191
155
|
);
|
|
192
156
|
}
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import { SmartAccountClient } from "permissionless";
|
|
2
|
-
import { SmartAccount } from "permissionless/accounts";
|
|
3
|
-
import { EntryPoint } from "permissionless/types";
|
|
1
|
+
import type { SmartAccountClient } from "permissionless";
|
|
2
|
+
import type { SmartAccount } from "permissionless/accounts";
|
|
3
|
+
import type { EntryPoint } from "permissionless/types";
|
|
4
4
|
import {
|
|
5
|
+
type Address,
|
|
5
6
|
BaseError,
|
|
6
|
-
Chain,
|
|
7
|
+
type Chain,
|
|
7
8
|
ContractFunctionRevertedError,
|
|
8
|
-
PublicClient,
|
|
9
|
-
SimulateContractReturnType,
|
|
10
|
-
TransactionReceipt,
|
|
11
|
-
Transport,
|
|
9
|
+
type PublicClient,
|
|
10
|
+
type SimulateContractReturnType,
|
|
11
|
+
type TransactionReceipt,
|
|
12
|
+
type Transport,
|
|
12
13
|
zeroAddress,
|
|
13
14
|
} from "viem";
|
|
14
15
|
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
@@ -27,9 +28,13 @@ function makeMockError<E extends Error, F extends object>(error: E, fields?: F):
|
|
|
27
28
|
}
|
|
28
29
|
|
|
29
30
|
describe("SendTransactionService", () => {
|
|
31
|
+
const walletAddress: Address = "0xE898BBd704CCE799e9593a9ADe2c1cA0351Ab660";
|
|
32
|
+
const mockSmartAccount = mock<SmartAccount<EntryPoint>>({ address: walletAddress });
|
|
30
33
|
const mockPublicClient = mock<PublicClient>();
|
|
31
|
-
const mockAccountClient = mock<SmartAccountClient<EntryPoint, Transport, Chain, SmartAccount<EntryPoint>>>(
|
|
32
|
-
|
|
34
|
+
const mockAccountClient = mock<SmartAccountClient<EntryPoint, Transport, Chain, SmartAccount<EntryPoint>>>({
|
|
35
|
+
account: mockSmartAccount,
|
|
36
|
+
});
|
|
37
|
+
const sendTransactionService = new SendTransactionService({ public: mockPublicClient, wallet: mockAccountClient });
|
|
33
38
|
|
|
34
39
|
beforeEach(() => {
|
|
35
40
|
vi.resetAllMocks();
|
|
@@ -49,15 +54,12 @@ describe("SendTransactionService", () => {
|
|
|
49
54
|
mockPublicClient.simulateContract.mockRejectedValue(mockError);
|
|
50
55
|
let rejected = false;
|
|
51
56
|
try {
|
|
52
|
-
await sendTransactionService.sendTransaction(
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
},
|
|
59
|
-
mockAccountClient
|
|
60
|
-
);
|
|
57
|
+
await sendTransactionService.sendTransaction({
|
|
58
|
+
address: zeroAddress,
|
|
59
|
+
abi: [],
|
|
60
|
+
functionName: "mockFunction",
|
|
61
|
+
args: [],
|
|
62
|
+
});
|
|
61
63
|
} catch (e) {
|
|
62
64
|
rejected = true;
|
|
63
65
|
expect(e).toBeInstanceOf(EVMSendTransactionExecutionRevertedError);
|
|
@@ -74,15 +76,12 @@ describe("SendTransactionService", () => {
|
|
|
74
76
|
mockPublicClient.waitForTransactionReceipt.mockResolvedValueOnce(mockReceipt);
|
|
75
77
|
let rejected = false;
|
|
76
78
|
try {
|
|
77
|
-
await sendTransactionService.sendTransaction(
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
},
|
|
84
|
-
mockAccountClient
|
|
85
|
-
);
|
|
79
|
+
await sendTransactionService.sendTransaction({
|
|
80
|
+
address: zeroAddress,
|
|
81
|
+
abi: [],
|
|
82
|
+
functionName: "mockFunction",
|
|
83
|
+
args: [],
|
|
84
|
+
});
|
|
86
85
|
} catch (e) {
|
|
87
86
|
rejected = true;
|
|
88
87
|
expect(e).toBeInstanceOf(EVMSendTransactionExecutionRevertedError);
|
|
@@ -96,15 +95,12 @@ describe("SendTransactionService", () => {
|
|
|
96
95
|
mockPublicClient.waitForTransactionReceipt.mockRejectedValue(mockError);
|
|
97
96
|
let rejected = false;
|
|
98
97
|
try {
|
|
99
|
-
await sendTransactionService.sendTransaction(
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
},
|
|
106
|
-
mockAccountClient
|
|
107
|
-
);
|
|
98
|
+
await sendTransactionService.sendTransaction({
|
|
99
|
+
address: zeroAddress,
|
|
100
|
+
abi: [],
|
|
101
|
+
functionName: "mockFunction",
|
|
102
|
+
args: [],
|
|
103
|
+
});
|
|
108
104
|
} catch (e) {
|
|
109
105
|
rejected = true;
|
|
110
106
|
expect(e).toBeInstanceOf(EVMSendTransactionError);
|
|
@@ -118,15 +114,12 @@ describe("SendTransactionService", () => {
|
|
|
118
114
|
mockAccountClient.writeContract.mockRejectedValue(mockError);
|
|
119
115
|
let rejected = false;
|
|
120
116
|
try {
|
|
121
|
-
await sendTransactionService.sendTransaction(
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
},
|
|
128
|
-
mockAccountClient
|
|
129
|
-
);
|
|
117
|
+
await sendTransactionService.sendTransaction({
|
|
118
|
+
address: zeroAddress,
|
|
119
|
+
abi: [],
|
|
120
|
+
functionName: "mockFunction",
|
|
121
|
+
args: [],
|
|
122
|
+
});
|
|
130
123
|
} catch (e) {
|
|
131
124
|
rejected = true;
|
|
132
125
|
expect(e).toBeInstanceOf(EVMSendTransactionError);
|
|
@@ -148,16 +141,19 @@ describe("SendTransactionService", () => {
|
|
|
148
141
|
return "0xmockTxHash";
|
|
149
142
|
});
|
|
150
143
|
await expect(
|
|
151
|
-
sendTransactionService.sendTransaction(
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
},
|
|
158
|
-
mockAccountClient
|
|
159
|
-
)
|
|
144
|
+
sendTransactionService.sendTransaction({
|
|
145
|
+
address: zeroAddress,
|
|
146
|
+
abi: [],
|
|
147
|
+
functionName: "mockFunction",
|
|
148
|
+
args: [],
|
|
149
|
+
})
|
|
160
150
|
).resolves.toBeDefined();
|
|
161
151
|
expect(callOrder).toEqual(["simulateContract", "sendTransaction"]);
|
|
152
|
+
|
|
153
|
+
expect(mockPublicClient.simulateContract).toHaveBeenCalledWith(
|
|
154
|
+
expect.objectContaining({
|
|
155
|
+
account: walletAddress,
|
|
156
|
+
})
|
|
157
|
+
);
|
|
162
158
|
});
|
|
163
159
|
});
|
|
@@ -87,8 +87,11 @@ export interface SendTransactionOptions {
|
|
|
87
87
|
|
|
88
88
|
export class SendTransactionService {
|
|
89
89
|
constructor(
|
|
90
|
-
private
|
|
91
|
-
|
|
90
|
+
private readonly client: {
|
|
91
|
+
public: PublicClient;
|
|
92
|
+
wallet: SmartAccountClient<EntryPoint, Transport, Chain, SmartAccount<EntryPoint>>;
|
|
93
|
+
},
|
|
94
|
+
private readonly defaultSendTransactionOptions: SendTransactionOptions = {
|
|
92
95
|
confirmations: 2,
|
|
93
96
|
transactionConfirmationTimeout: 30_000,
|
|
94
97
|
}
|
|
@@ -96,7 +99,6 @@ export class SendTransactionService {
|
|
|
96
99
|
|
|
97
100
|
async sendTransaction(
|
|
98
101
|
request: TransactionServiceTransactionRequest,
|
|
99
|
-
client: SmartAccountClient<EntryPoint, Transport, Chain, SmartAccount<EntryPoint>>,
|
|
100
102
|
config: Partial<SendTransactionOptions> = {}
|
|
101
103
|
): Promise<Hex> {
|
|
102
104
|
const { confirmations, transactionConfirmationTimeout } = this.getConfig(config);
|
|
@@ -105,10 +107,10 @@ export class SendTransactionService {
|
|
|
105
107
|
|
|
106
108
|
let hash;
|
|
107
109
|
try {
|
|
108
|
-
hash = await client.writeContract({
|
|
110
|
+
hash = await this.client.wallet.writeContract({
|
|
109
111
|
...request,
|
|
110
|
-
account: client.account,
|
|
111
|
-
chain: client.chain,
|
|
112
|
+
account: this.client.wallet.account,
|
|
113
|
+
chain: this.client.wallet.chain,
|
|
112
114
|
});
|
|
113
115
|
} catch (e) {
|
|
114
116
|
if (e instanceof BaseError) {
|
|
@@ -118,7 +120,7 @@ export class SendTransactionService {
|
|
|
118
120
|
}
|
|
119
121
|
|
|
120
122
|
try {
|
|
121
|
-
const receipt = await this.
|
|
123
|
+
const receipt = await this.client.public.waitForTransactionReceipt({
|
|
122
124
|
hash,
|
|
123
125
|
confirmations,
|
|
124
126
|
timeout: transactionConfirmationTimeout,
|
|
@@ -161,10 +163,10 @@ export class SendTransactionService {
|
|
|
161
163
|
stage: SendTransactionFailureStage
|
|
162
164
|
) {
|
|
163
165
|
try {
|
|
164
|
-
await this.
|
|
166
|
+
await this.client.public.simulateContract({
|
|
165
167
|
...request,
|
|
166
|
-
account:
|
|
167
|
-
chain: this.
|
|
168
|
+
account: this.client.wallet.account.address,
|
|
169
|
+
chain: this.client.public.chain,
|
|
168
170
|
});
|
|
169
171
|
} catch (e) {
|
|
170
172
|
if (e instanceof BaseError) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
2
|
|
|
3
|
-
import { UserParams } from "../../../types/params";
|
|
3
|
+
import type { UserParams } from "../../../types/params";
|
|
4
4
|
import { mockConfig } from "../../../utils/test";
|
|
5
5
|
import { AccountConfigCache } from "./cache";
|
|
6
6
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { keccak256, toHex } from "viem";
|
|
2
2
|
|
|
3
|
-
import { UserParams } from "../../../types/params";
|
|
3
|
+
import type { UserParams } from "../../../types/params";
|
|
4
4
|
import { SmartWalletConfigSchema } from "../../../types/schema";
|
|
5
5
|
import type { SmartWalletConfig } from "../../../types/service";
|
|
6
6
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { beforeEach, describe, expect, it } from "vitest";
|
|
2
2
|
import { mock } from "vitest-mock-extended";
|
|
3
3
|
|
|
4
|
-
import { CrossmintWalletService } from "../../../api/CrossmintWalletService";
|
|
5
|
-
import { SmartWalletConfig } from "../../../types/service";
|
|
4
|
+
import type { CrossmintWalletService } from "../../../api/CrossmintWalletService";
|
|
5
|
+
import type { SmartWalletConfig } from "../../../types/service";
|
|
6
6
|
import { mockConfig } from "../../../utils/test";
|
|
7
7
|
import { SmartWalletChain } from "../../chains";
|
|
8
|
-
import { AccountConfigCache } from "./cache";
|
|
8
|
+
import type { AccountConfigCache } from "./cache";
|
|
9
9
|
import { AccountConfigService } from "./config";
|
|
10
10
|
import { PasskeySignerConfig } from "./signer";
|
|
11
11
|
|
|
@@ -8,7 +8,7 @@ import type {
|
|
|
8
8
|
} from "../../../types/internal";
|
|
9
9
|
import type { UserParams } from "../../../types/params";
|
|
10
10
|
import type { SignerData, SmartWalletConfig } from "../../../types/service";
|
|
11
|
-
import { AccountConfigCache } from "./cache";
|
|
11
|
+
import type { AccountConfigCache } from "./cache";
|
|
12
12
|
import { EOASignerConfig, PasskeySignerConfig, type SignerConfig } from "./signer";
|
|
13
13
|
|
|
14
14
|
interface AccountConfig {
|
|
@@ -6,8 +6,8 @@ import {
|
|
|
6
6
|
isPasskeyCreationContext,
|
|
7
7
|
isPasskeyWalletParams,
|
|
8
8
|
} from "../../../types/internal";
|
|
9
|
-
import { EOACreationStrategy } from "./eoa";
|
|
10
|
-
import { PasskeyCreationStrategy } from "./passkey";
|
|
9
|
+
import type { EOACreationStrategy } from "./eoa";
|
|
10
|
+
import type { PasskeyCreationStrategy } from "./passkey";
|
|
11
11
|
|
|
12
12
|
export class AccountCreator {
|
|
13
13
|
constructor(
|
|
@@ -6,7 +6,7 @@ import type { AccountAndSigner, EOACreationContext } from "../../../types/intern
|
|
|
6
6
|
import { equalsIgnoreCase } from "../../../utils/helpers";
|
|
7
7
|
import { createOwnerSigner } from "../../../utils/signer";
|
|
8
8
|
import { EOASignerConfig } from "./signer";
|
|
9
|
-
import { AccountCreationStrategy } from "./strategy";
|
|
9
|
+
import type { AccountCreationStrategy } from "./strategy";
|
|
10
10
|
|
|
11
11
|
export class EOACreationStrategy implements AccountCreationStrategy {
|
|
12
12
|
public async create({
|
|
@@ -14,13 +14,16 @@ import type { AccountAndSigner, PasskeyCreationContext } from "../../../types/in
|
|
|
14
14
|
import type { UserParams } from "../../../types/params";
|
|
15
15
|
import type { PasskeySignerData, PasskeyValidatorSerializedData } from "../../../types/service";
|
|
16
16
|
import { PasskeySignerConfig } from "./signer";
|
|
17
|
-
import { AccountCreationStrategy } from "./strategy";
|
|
17
|
+
import type { AccountCreationStrategy } from "./strategy";
|
|
18
18
|
|
|
19
19
|
type PasskeyValidator = KernelValidator<EntryPoint, "WebAuthnValidator"> & {
|
|
20
20
|
getSerializedData: () => string;
|
|
21
21
|
};
|
|
22
22
|
export class PasskeyCreationStrategy implements AccountCreationStrategy {
|
|
23
|
-
constructor(
|
|
23
|
+
constructor(
|
|
24
|
+
private readonly passkeyServerUrl: string,
|
|
25
|
+
private readonly apiKey: string
|
|
26
|
+
) {}
|
|
24
27
|
|
|
25
28
|
public async create({
|
|
26
29
|
user,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AccountAndSigner, WalletCreationContext } from "../../../types/internal";
|
|
1
|
+
import type { AccountAndSigner, WalletCreationContext } from "../../../types/internal";
|
|
2
2
|
|
|
3
3
|
export interface AccountCreationStrategy {
|
|
4
4
|
create(params: WalletCreationContext): Promise<AccountAndSigner>;
|
|
@@ -3,10 +3,10 @@ import type { EntryPoint } from "permissionless/types/entrypoint";
|
|
|
3
3
|
import { stringify } from "viem";
|
|
4
4
|
|
|
5
5
|
import { SmartWalletError } from "../../error";
|
|
6
|
-
import { ErrorProcessor } from "../../error/processor";
|
|
6
|
+
import type { ErrorProcessor } from "../../error/processor";
|
|
7
7
|
import { scwLogger } from "../../services";
|
|
8
8
|
import { usesGelatoBundler } from "../../utils/blockchain";
|
|
9
|
-
import { SmartWalletChain } from "../chains";
|
|
9
|
+
import type { SmartWalletChain } from "../chains";
|
|
10
10
|
|
|
11
11
|
const transactionMethods = [
|
|
12
12
|
"sendTransaction",
|
|
@@ -37,7 +37,10 @@ function isSignMethod(method: string): method is SignMethod {
|
|
|
37
37
|
* - Automatic formatting of transactions for Gelato bundler compatibility.
|
|
38
38
|
* */
|
|
39
39
|
export class ClientDecorator {
|
|
40
|
-
constructor(
|
|
40
|
+
constructor(
|
|
41
|
+
private readonly errorProcessor: ErrorProcessor,
|
|
42
|
+
protected logger = scwLogger
|
|
43
|
+
) {}
|
|
41
44
|
|
|
42
45
|
public decorate<Client extends SmartAccountClient<EntryPoint>>({
|
|
43
46
|
crossmintChain,
|
|
@@ -69,7 +72,6 @@ export class ClientDecorator {
|
|
|
69
72
|
private async execute<M extends TxnMethod | SignMethod>(
|
|
70
73
|
target: SmartAccountClient<EntryPoint>,
|
|
71
74
|
prop: M,
|
|
72
|
-
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
73
75
|
originalMethod: Function,
|
|
74
76
|
args: any[],
|
|
75
77
|
crossmintChain: SmartWalletChain
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { CrossmintWalletService } from "@/api/CrossmintWalletService";
|
|
2
|
-
import { Middleware } from "permissionless/actions/smartAccount";
|
|
3
|
-
import { PimlicoBundlerClient } from "permissionless/clients/pimlico";
|
|
4
|
-
import { EntryPoint } from "permissionless/types/entrypoint";
|
|
1
|
+
import type { CrossmintWalletService } from "@/api/CrossmintWalletService";
|
|
2
|
+
import type { Middleware } from "permissionless/actions/smartAccount";
|
|
3
|
+
import type { PimlicoBundlerClient } from "permissionless/clients/pimlico";
|
|
4
|
+
import type { EntryPoint } from "permissionless/types/entrypoint";
|
|
5
5
|
|
|
6
|
-
import { UserParams } from "../../types/params";
|
|
6
|
+
import type { UserParams } from "../../types/params";
|
|
7
7
|
import { usesGelatoBundler } from "../../utils/blockchain";
|
|
8
|
-
import { SmartWalletChain } from "../chains";
|
|
8
|
+
import type { SmartWalletChain } from "../chains";
|
|
9
9
|
|
|
10
10
|
export function usePaymaster(chain: SmartWalletChain) {
|
|
11
11
|
return !usesGelatoBundler(chain);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { KernelSmartAccount } from "@zerodev/sdk";
|
|
1
|
+
import type { KernelSmartAccount } from "@zerodev/sdk";
|
|
2
2
|
import { ENTRYPOINT_ADDRESS_V06, ENTRYPOINT_ADDRESS_V07, createSmartAccountClient } from "permissionless";
|
|
3
3
|
import { createPimlicoBundlerClient } from "permissionless/clients/pimlico";
|
|
4
|
-
import { EntryPoint } from "permissionless/types/entrypoint";
|
|
5
|
-
import { HttpTransport, createPublicClient, http } from "viem";
|
|
4
|
+
import type { EntryPoint } from "permissionless/types/entrypoint";
|
|
5
|
+
import { type HttpTransport, createPublicClient, http } from "viem";
|
|
6
6
|
|
|
7
7
|
import { blockchainToChainId } from "@crossmint/common-sdk-base";
|
|
8
8
|
|
|
@@ -71,10 +71,9 @@ export class SmartWalletService {
|
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
return new EVMSmartWallet(
|
|
74
|
-
this.
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
chain
|
|
74
|
+
{ wallet: this.smartAccountClient(chain, account, user), public: publicClient },
|
|
75
|
+
chain,
|
|
76
|
+
this.crossmintService
|
|
78
77
|
);
|
|
79
78
|
}
|
|
80
79
|
|
package/src/error/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CrossmintSDKError, SmartWalletErrorCode } from "@crossmint/client-sdk-base";
|
|
2
2
|
|
|
3
|
-
import { PasskeyDisplay, SignerDisplay } from "../types/service";
|
|
3
|
+
import type { PasskeyDisplay, SignerDisplay } from "../types/service";
|
|
4
4
|
|
|
5
5
|
export class SmartWalletError extends CrossmintSDKError {
|
|
6
6
|
constructor(message: string, details?: string, code: SmartWalletErrorCode = SmartWalletErrorCode.UNCATEGORIZED) {
|
package/src/error/processor.ts
CHANGED