Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: remove hardcoded gas, fix estimation, sdk improvements #193

Merged
merged 54 commits into from
Nov 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
17daeb5
feat: store sessions offchain to reduce gas
ly0va Nov 1, 2024
d628d0c
feat: signer assertion and more events
ly0va Nov 1, 2024
82fc11d
chore: update abi
ly0va Nov 1, 2024
efd733a
fix: remove max_constraints
ly0va Nov 1, 2024
edb2472
chore: rename
ly0va Nov 1, 2024
8789160
Merge remote-tracking branch 'origin/main' into lyova-offchain-sessions
ly0va Nov 2, 2024
9c5db07
fix: update abi
ly0va Nov 2, 2024
3bce3f0
fix: gas estimation
ly0va Nov 2, 2024
109a2fb
chore: add more logs
ly0va Nov 2, 2024
56c4be3
Merge branch 'main' into lyova-offchain-sessions
ly0va Nov 11, 2024
077ec6e
chore: update sdk
ly0va Nov 11, 2024
9e5a417
feat: pass session in sdk
ly0va Nov 12, 2024
fbefbfe
fix: sdk bug
ly0va Nov 12, 2024
499c680
fix: remove hardcoded gas limits
ly0va Nov 12, 2024
89c631c
fix: leave hardcoded gas limit in sdk for now
ly0va Nov 12, 2024
5bb0d63
Merge branch 'main' into lyova-offchain-sessions
ly0va Nov 12, 2024
677fa53
Merge branch 'main' into lyova-offchain-sessions
JackHamer09 Nov 12, 2024
2bd1bb3
fix: session interface improvements
JackHamer09 Nov 12, 2024
c0578b3
fix: enable ci and fix docs
JackHamer09 Nov 12, 2024
4bc524d
fix: readme formatting
JackHamer09 Nov 12, 2024
13b4e07
fix: remove redundant workflow triggers
JackHamer09 Nov 12, 2024
f404b9e
fix: update contract addresses
JackHamer09 Nov 12, 2024
d09bd78
fix: update addresses
JackHamer09 Nov 12, 2024
6659e39
fix: popup communicator
JackHamer09 Nov 12, 2024
9ece621
Merge branch 'lyova-offchain-sessions' of https://github.com/matter-l…
JackHamer09 Nov 12, 2024
827512c
fix: e2e
JackHamer09 Nov 12, 2024
95c3af8
fix: move session defaults out of computed
JackHamer09 Nov 12, 2024
c7636ba
fix: rename fee to feeLimit
JackHamer09 Nov 13, 2024
fd4333c
fix: limit zero incorrect LimitType
JackHamer09 Nov 13, 2024
f2fb3fd
fix: remove session spec, which is copy of createSession from abi
JackHamer09 Nov 13, 2024
fcb0d79
fix: sdk build
JackHamer09 Nov 13, 2024
da9aa0d
fix: remove redundant bigint conversions
JackHamer09 Nov 13, 2024
c762d9d
fix: update interface to support specifying limit type
JackHamer09 Nov 13, 2024
c008cc0
fix: use unlimited default limit for calls constraints
JackHamer09 Nov 13, 2024
78d30d3
Merge pull request #164 from matter-labs/session-interface-improvements
ly0va Nov 13, 2024
ff882e5
Merge branch 'main' into lyova-offchain-sessions
JackHamer09 Nov 13, 2024
3499fe2
fix: pass custom signature during session transaction estimation
JackHamer09 Nov 13, 2024
580a529
fix: try fix estimation
JackHamer09 Nov 14, 2024
4092f84
Revert "fix: try fix estimation"
JackHamer09 Nov 14, 2024
94faafc
Revert "fix: pass custom signature during session transaction estimat…
JackHamer09 Nov 14, 2024
6e8aac5
Reapply "fix: pass custom signature during session transaction estima…
JackHamer09 Nov 14, 2024
a5f5123
Reapply "fix: try fix estimation"
JackHamer09 Nov 14, 2024
ad58810
Merge branch 'main' into fix-estimation
JackHamer09 Nov 14, 2024
59a4a02
fix: some more updates, getting closer to figure out the issue
JackHamer09 Nov 15, 2024
5403531
fix: estimation
JackHamer09 Nov 15, 2024
bf99429
fix: undo hardocde data and gasPerPubdata
JackHamer09 Nov 15, 2024
710edc3
fix: undo using gas price
JackHamer09 Nov 15, 2024
9311342
Merge branch 'main' of https://github.com/matter-labs/zksync-account-…
JackHamer09 Nov 18, 2024
d22aaf0
Merge branch 'main' into fix-estimation
JackHamer09 Nov 20, 2024
4ae8789
fix: sdk improvements
JackHamer09 Nov 20, 2024
f1d9726
Merge branch 'main' into fix-estimation
JackHamer09 Nov 20, 2024
cece0c8
fix: copy readme from root during deployment
JackHamer09 Nov 20, 2024
ae1a19d
fix: add separate readme for sdk
JackHamer09 Nov 20, 2024
d8c3f76
Merge branch 'main' into fix-estimation
JackHamer09 Nov 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cspell-config/cspell-misc.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Nuxt
nuxtjs
testid
vueuse
ethereum

// examples/bank-demo
ctap
Expand All @@ -25,4 +26,3 @@ usdc
// examples/nft-quest
Fren
fren
trxn
8 changes: 5 additions & 3 deletions examples/demo-app/pages/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
</template>

<script lang="ts" setup>
import { disconnect, getBalance, watchAccount, sendTransaction, createConfig, connect, reconnect, type GetBalanceReturnType } from "@wagmi/core";
import { disconnect, getBalance, watchAccount, sendTransaction, createConfig, connect, reconnect, waitForTransactionReceipt, type GetBalanceReturnType } from "@wagmi/core";
import { zksyncSsoConnector } from "zksync-sso/connector";
import { zksyncInMemoryNode } from "@wagmi/core/chains";
import { createWalletClient, http, parseEther, type Address } from "viem";
Expand Down Expand Up @@ -142,15 +142,17 @@ const sendTokens = async () => {
errorMessage.value = "";
isSendingEth.value = true;
try {
await sendTransaction(wagmiConfig, {
const transactionHash = await sendTransaction(wagmiConfig, {
to: testTransferTarget,
value: parseEther("0.1"),
gas: 100_000_000n,
});

balance.value = await getBalance(wagmiConfig, {
address: address.value,
});

const receipt = await waitForTransactionReceipt(wagmiConfig, { hash: transactionHash });
if (receipt.status === "reverted") throw new Error("Transaction reverted");
} catch (error) {
// eslint-disable-next-line no-console
console.error("Transaction failed:", error);
Expand Down
17 changes: 2 additions & 15 deletions examples/nft-quest/composables/useMintNft.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { estimateGas, waitForTransactionReceipt, writeContract } from "@wagmi/core";
import { type Address, encodeFunctionData } from "viem";
import { waitForTransactionReceipt, writeContract } from "@wagmi/core";
import type { Address } from "viem";
import { getGeneralPaymasterInput } from "viem/zksync";

export const useMintNft = async (_address: MaybeRef<Address>) => {
Expand All @@ -10,24 +10,11 @@ export const useMintNft = async (_address: MaybeRef<Address>) => {
const { wagmiConfig } = storeToRefs(useConnectorStore());

const mintingForAddress = address.value;
const data = encodeFunctionData({
abi: nftAbi,
functionName: "mint",
args: [address.value],
});

const estimatedGas = await estimateGas(wagmiConfig.value, {
to: runtimeConfig.public.contracts.nft as Address,
chainId: runtimeConfig.public.chain.id,
data,
});

const transactionHash = await writeContract(wagmiConfig.value, {
address: runtimeConfig.public.contracts.nft as Address,
abi: nftAbi,
functionName: "mint",
args: [mintingForAddress],
gas: estimatedGas + (estimatedGas / 100n * 25n), // gas may be underestimated
paymaster: runtimeConfig.public.contracts.paymaster as Address,
paymasterInput: getGeneralPaymasterInput({ innerInput: "0x" }),
});
Expand Down
10 changes: 10 additions & 0 deletions examples/nft-quest/nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,4 +102,14 @@ export default defineNuxtConfig({
},
},
},

vite: {
css: {
preprocessorOptions: {
scss: {
api: "modern", // Fix warning: "The legacy JS API is deprecated and will be removed in Dart Sass 2.0.0"
},
},
},
},
});
10 changes: 10 additions & 0 deletions packages/auth-server/nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,14 @@ export default defineNuxtConfig({
chainId: parseInt(process.env.NUXT_PUBLIC_DEFAULT_CHAIN_ID || "") || zksyncInMemoryNode.id,
},
},

vite: {
css: {
preprocessorOptions: {
scss: {
api: "modern", // Fix warning: "The legacy JS API is deprecated and will be removed in Dart Sass 2.0.0"
},
},
},
},
});
3 changes: 0 additions & 3 deletions packages/contracts/test/PasskeyModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,9 +220,6 @@ async function rawVerify(
const hashedData = await toHash(concat([authDataBuffer, clientDataHash]));
const rs = unwrapEC2Signature(toBuffer(b64SignedChallange));
const publicKeys = await getPublicKey(publicKeyEs256Bytes);
/* console.log("externalSignature", ethers.hexlify(hashedData));
console.log("rs", ethers.hexlify(rs[0]), ethers.hexlify(rs[1]));
console.log("pubkey xy", publicKeys); */
return await passkeyValidator.rawVerify(hashedData, rs, publicKeys);
}

Expand Down
1 change: 0 additions & 1 deletion packages/contracts/test/SessionKeyTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,6 @@ describe("SessionKeyModule tests", function () {
await tester.sendTxSuccess({
to: sessionTarget,
value: parseEther("0.01"),
gasLimit: 10_000_000n,
});
expect(await provider.getBalance(sessionTarget))
.to.equal(parseEther("0.01"), "session target should have received the funds");
Expand Down
108 changes: 106 additions & 2 deletions packages/sdk/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,107 @@
# zksync-sso
# zksync-sso SDK

ZKsync SSO SDK
[![License](https://img.shields.io/badge/license-MIT-blue)](LICENSE-MIT)
[![CI](https://github.com/matter-labs/zksync-account-sdk/actions/workflows/ci.yml/badge.svg)](https://github.com/matter-labs/zksync-account-sdk/actions/workflows/ci.yml)

A user & developer friendly modular smart account implementation on ZKsync;
simplifying user authentication, session management, and transaction processing.

## Features and Goals

<!-- prettier-ignore -->
> [!CAUTION]
> ZKsync SSO is under active development and is not yet feature
> complete. Use it to improve your development applications and tooling. Please
> do not use it in production environments.

- 🧩 Modular smart accounts based on
[ERC-7579](https://eips.ethereum.org/EIPS/eip-7579#modules)
- 🔑 Passkey authentication (no seed phrases)
- ⏰ Sessions w/ easy configuration and management
- 💰 Integrated paymaster support
- ❤️‍🩹 Account recovery _(Coming Soon)_
- 💻 Simple SDKs : JavaScript, iOS/Android _(Coming Soon)_
- 🤝 Open-source authentication server
- 🎓 Examples to get started quickly

## Getting started

Install the ZKsync SSO SDK package:

```sh
npm i zksync-sso
```

Add ZKsync SSO connector to your app (using `wagmi`):

```ts
import { zksyncSepoliaTestnet } from "viem/chains";
import { createConfig, connect } from "@wagmi/core";
import { zksyncSsoConnector } from "zksync-sso/connector";

const ssoConnector = zksyncSsoConnector({
// Optional session configuration,
// if omitted user will have to sign every transaction via Auth Server
session: {
// Allow up to 0.1 ETH to be spend in gas fees
feeLimit: parseEther("0.1"),

transfers: [
// Allow ETH transfers of up to 0.1 ETH to specific address
{
to: "0x188bd99cd7D4d78d4E605Aeea12C17B32CC3135A",
valueLimit: parseEther("0.1"),
},

// Allow ETH transfers to specific address with a limit of 0.1 ETH per hour
// until the session expires
{
to: "0x188bd99cd7D4d78d4E605Aeea12C17B32CC3135A",
valueLimit: {
limit: parseEther("0.1"),
period: BigInt(60 * 60), // 1 hour in seconds
},
},
],

// Allow calling specific smart contracts (e.g. ERC20 transfer):
contractCalls: [
{
address: "0xa1cf087DB965Ab02Fb3CFaCe1f5c63935815f044",
function: "transfer(address,uint256)",

// Optional call constraints (unconstrained otherwise):
constraints: [

// Only allow transfers to this address
{
index: 0,
condition: "Equal",
refValue: pad("0x6cC8cf7f6b488C58AA909B77E6e65c631c204784"),
},

// Transfer up to 0.2 tokens
{
index: 1,
limit: parseUnits("0.2", TOKEN.decimals), // Unlimited if omitted
},
],
},
],
},
});

const wagmiConfig = createConfig({
connectors: [ssoConnector],
..., // your wagmi config https://wagmi.sh/core/api/createConfig
});

const connectWithSSO = () => {
connect(wagmiConfig, {
connector: ssoConnector,
chainId: zksyncSepoliaTestnet.id, // or another chain id that has SSO support
});
};
```

[Find more information here in our docs.](https://docs.zksync.io/build/zksync-sso)
8 changes: 2 additions & 6 deletions packages/sdk/prepare-package.mjs
Original file line number Diff line number Diff line change
@@ -1,20 +1,16 @@
import { promises as fs } from "fs";
import path from "path";

// Define the path to the package.json
const packageJsonPath = path.resolve("./package.json");
console.log(packageJsonPath);

// Get the version from environment variables
const version = process.env.INPUT_VERSION;
if (!version) {
console.error("Error: INPUT_VERSION is required.");
process.exit(1);
}

const packageJsonPath = path.resolve("./package.json");

async function preparePackageJson() {
try {
// Read the existing package.json
const packageJsonData = await fs.readFile(packageJsonPath, "utf8");
const packageJson = JSON.parse(packageJsonData);

Expand Down
10 changes: 10 additions & 0 deletions packages/sdk/src/client-auth-server/Signer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type Account = {
interface SignerInterface {
accounts: Address[];
chain: Chain;
getClient(parameters?: { chainId?: number }): ZksyncSsoSessionClient;
handshake(): Promise<Address[]>;
request<TMethod extends Method>(request: RequestArguments<TMethod>): Promise<ExtractReturnType<TMethod>>;
disconnect: () => Promise<void>;
Expand Down Expand Up @@ -83,6 +84,15 @@ export class Signer implements SignerInterface {
}
}

getClient(parameters?: { chainId?: number }) {
const chainId = parameters?.chainId || this.chain.id;
const chain = this.chains.find((e) => e.id === chainId);
if (!chain) throw new Error(`Chain with id ${chainId} is not supported`);

if (!this.walletClient) throw new Error("Wallet client is not created");
return this.walletClient;
}

private get account(): Account | null {
const account = this._account.get();
if (!account) return null;
Expand Down
4 changes: 4 additions & 0 deletions packages/sdk/src/client-auth-server/WalletProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ export class WalletProvider extends EventEmitter implements ProviderInterface {
return this.signer.accounts.length > 0;
}

public getClient(parameters?: { chainId?: number }) {
return this.signer.getClient(parameters);
}

public async request<M extends Method>(request: RequestArguments<M>): Promise<ExtractReturnType<M>> {
try {
switch (request.method) {
Expand Down
2 changes: 2 additions & 0 deletions packages/sdk/src/client-auth-server/interface.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { EventEmitter } from "eventemitter3";
import type { RpcSchema as RpcSchemaGeneric } from "viem";

import type { ZksyncSsoSessionClient } from "../client/index.js";
import type { ExtractParams, ExtractReturnType, Method, RpcSchema } from "./rpc.js";

export interface RequestArguments<M extends Method<TSchema>, TSchema extends RpcSchemaGeneric = RpcSchema> {
Expand All @@ -26,6 +27,7 @@ interface ProviderConnectInfo {
export interface ProviderInterface extends EventEmitter {
request<M extends Method>(args: RequestArguments<M>): Promise<ExtractReturnType<M>>;
disconnect(): Promise<void>;
getClient(parameters?: { chainId?: number }): Promise<ZksyncSsoSessionClient> | ZksyncSsoSessionClient;
on(event: "connect", listener: (info: ProviderConnectInfo) => void): this;
on(event: "disconnect", listener: (error: ProviderRpcError) => void): this;
on(event: "chainChanged", listener: (chainId: string) => void): this;
Expand Down
Loading
Loading