Skip to content

Commit 2a044dd

Browse files
committed
feat: more paymaster support
1 parent 428e9f3 commit 2a044dd

File tree

7 files changed

+66
-5
lines changed

7 files changed

+66
-5
lines changed

examples/demo-app/scripts/deploy-msa-anvil.sh

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,30 @@ echo " ModularSmartAccount impl: $ACCOUNT_IMPL"
5858
echo " UpgradeableBeacon: $BEACON"
5959
echo " MSAFactory: $FACTORY"
6060

61+
# Deploy MockPaymaster for gas sponsorship
62+
echo ""
63+
echo "📦 Deploying MockPaymaster..."
64+
PAYMASTER_OUTPUT=$(forge create test/mocks/MockPaymaster.sol:MockPaymaster \
65+
--rpc-url $RPC_URL \
66+
--private-key 0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6 \
67+
--json 2>&1 | tail -1)
68+
69+
PAYMASTER=$(echo "$PAYMASTER_OUTPUT" | jq -r '.deployedTo // empty')
70+
if [ -z "$PAYMASTER" ]; then
71+
echo "⚠️ Failed to deploy MockPaymaster, continuing without it"
72+
PAYMASTER=""
73+
else
74+
echo "✅ MockPaymaster deployed to: $PAYMASTER"
75+
76+
# Fund the paymaster by calling deposit() with ETH
77+
echo "💰 Funding paymaster via deposit()..."
78+
cast send $PAYMASTER "deposit()" \
79+
--rpc-url $RPC_URL \
80+
--private-key 0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6 \
81+
--value 10ether
82+
echo "✅ Paymaster funded with 10 ETH"
83+
fi
84+
6185
# Create contracts-anvil.json
6286
echo ""
6387
echo "💾 Creating contracts-anvil.json..."
@@ -75,6 +99,7 @@ cat > contracts-anvil.json << EOF
7599
"accountImplementation": "$ACCOUNT_IMPL",
76100
"beacon": "$BEACON",
77101
"factory": "$FACTORY",
102+
"paymaster": "$PAYMASTER",
78103
"entryPoint": "0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108",
79104
"bundlerUrl": "http://localhost:4337"
80105
}
@@ -90,6 +115,10 @@ echo "✅ Updated contracts.json to use Anvil addresses"
90115
cp contracts-anvil.json public/contracts.json
91116
echo "✅ Copied to public/contracts.json"
92117

118+
# Copy to auth-server-api for local development
119+
cp contracts-anvil.json "$WORKSPACE_ROOT/packages/auth-server-api/src/contracts.json"
120+
echo "✅ Copied to packages/auth-server-api/src/contracts.json"
121+
93122
echo ""
94123
echo "🎉 Deployment complete!"
95124
echo ""

examples/nft-quest/stores/connector.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { connect, createConfig, type CreateConnectorFn, disconnect, getAccount, http, reconnect, watchAccount } from "@wagmi/core";
2-
import type { Address, Hash } from "viem";
2+
import { type Address, type Hash, parseEther } from "viem";
33
import type { Chain } from "viem/chains";
44
import { zksyncSsoConnector } from "zksync-sso-4337/connector";
55

@@ -36,7 +36,7 @@ export const useConnectorStore = defineStore("connector", () => {
3636
},
3737
authServerUrl,
3838
session: {
39-
feeLimit: 0n,
39+
feeLimit: parseEther("0.1"), // Allow up to 0.1 ETH for gas fees
4040
contractCalls: [
4141
{
4242
address: contracts.nft as Hash,
@@ -67,10 +67,12 @@ export const useConnectorStore = defineStore("connector", () => {
6767
});
6868

6969
const connectAccount = async () => {
70-
return await connect(wagmiConfig, {
70+
const result = await connect(wagmiConfig, {
7171
connector,
7272
chainId: chain.id,
7373
});
74+
75+
return result;
7476
};
7577

7678
const disconnectAccount = () => {

packages/auth-server/composables/useAccountCreate.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ export const useAccountCreate = (_chainId: MaybeRef<SupportedChainId>, prividium
5757
credentialId,
5858
credentialPublicKey,
5959
originDomain: window.location.origin,
60-
session: sessionData ? sessionSpecToJSON(sessionData) : undefined,
60+
// sessionSpecToJSON returns a JSON string, so parse it to get an object
61+
session: sessionData ? JSON.parse(sessionSpecToJSON(sessionData)) : undefined,
6162
userId: credentialId, // Use credential ID as unique user ID
6263
eoaSigners: [ownerAddress],
6364
}),

packages/auth-server/stores/client.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ type ChainContracts = {
4949
factory: Address;
5050
bundlerUrl?: string;
5151
beacon?: Address; // Optional, for deployment
52+
paymaster?: Address; // Optional, for gas sponsorship
5253
};
5354

5455
export const contractsByChain: Record<SupportedChainId, ChainContracts> = {

packages/auth-server/utils/constructReturn.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export const constructReturn = (address: `0x${string}`, chainId: number, session
1212
id: chain.id,
1313
capabilities: {
1414
paymasterService: {
15-
supported: true,
15+
supported: !!contractsByChain[chain.id].paymaster,
1616
},
1717
atomicBatch: {
1818
supported: true,
@@ -23,6 +23,7 @@ export const constructReturn = (address: `0x${string}`, chainId: number, session
2323
},
2424
contracts: contractsByChain[chain.id],
2525
bundlerUrl: contractsByChain[chain.id].bundlerUrl,
26+
paymaster: contractsByChain[chain.id].paymaster,
2627
})),
2728
};
2829
};

packages/sdk-4337/src/client-auth-server/Signer.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,10 +155,36 @@ export class Signer implements SignerInterface {
155155
transport: this.transports[chain.id] || http(),
156156
});
157157

158+
// Build paymaster configuration if paymaster address is available
159+
const paymasterAddress = chainInfo.paymaster;
160+
const paymasterConfig = paymasterAddress
161+
? {
162+
async getPaymasterData() {
163+
// For a simple verifying paymaster, we just need to specify the paymaster address
164+
// The MockPaymaster doesn't require any additional data
165+
return {
166+
paymaster: paymasterAddress,
167+
paymasterData: "0x" as `0x${string}`,
168+
paymasterVerificationGasLimit: 500_000n,
169+
paymasterPostOpGasLimit: 100_000n,
170+
};
171+
},
172+
async getPaymasterStubData() {
173+
return {
174+
paymaster: paymasterAddress,
175+
paymasterData: "0x" as `0x${string}`,
176+
paymasterVerificationGasLimit: 500_000n,
177+
paymasterPostOpGasLimit: 100_000n,
178+
};
179+
},
180+
}
181+
: undefined;
182+
158183
this.bundlerClients[chain.id] = createBundlerClient({
159184
client: publicClient,
160185
chain,
161186
transport: http(chainInfo.bundlerUrl),
187+
paymaster: paymasterConfig,
162188
userOperation: {
163189
// Use fixed gas values matching old Rust SDK implementation
164190
// (old SDK used: 2M callGas, 2M verificationGas, 1M preVerificationGas)

packages/sdk-4337/src/client-auth-server/rpc.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export type AuthServerRpcSchema = [
2828
capabilities: Record<string, unknown>;
2929
contracts: SessionRequiredContracts;
3030
bundlerUrl?: string;
31+
paymaster?: Address;
3132
}[];
3233
};
3334
},

0 commit comments

Comments
 (0)