Skip to content

Commit

Permalink
feat: paymaster utils for zkSync (#2136)
Browse files Browse the repository at this point in the history
* feat: paymaster utils for zkSync

* chore: change function description and params ordering

* tweaks

* format

* tweak

---------

Co-authored-by: Marko Arambasic <makiarambasic@gmail.com>
Co-authored-by: moxey.eth <jakemoxey@gmail.com>
  • Loading branch information
3 people committed May 2, 2024
1 parent a2fc57f commit 1f39629
Show file tree
Hide file tree
Showing 10 changed files with 331 additions and 0 deletions.
Binary file modified bun.lockb
Binary file not shown.
@@ -0,0 +1,75 @@
---
description: Returns encoded formatted approval-based paymaster params.
---

# getApprovalBasedPaymasterInput

Returns encoded formatted approval-based paymaster params.

## Import

```ts
import { getApprovalBasedPaymasterInput } from 'viem/zksync'
```

## Usage

```ts
import { getApprovalBasedPaymasterInput } from 'viem/zksync'

const data = getApprovalBasedPaymasterInput({
innerInput: '0x',
minAllowance: 1n,
token: "0x65C899B5fb8Eb9ae4da51D67E1fc417c7CB7e964",
})
```

## Returns

`EncodeFunctionDataReturnType`

The `Hex` value of the provided approval-based paymaster inputs.

## Parameters

### token

- **Type:** `Address`

The token address.

```ts
const data = getApprovalBasedPaymasterInput({
innerInput: '0x',
minAllowance: 1n,
token: "0x65C899B5fb8Eb9ae4da51D67E1fc417c7CB7e964", // [!code focus]
})
```

### minAllowance

- **Type:** `bigint`

Minimum allowance (in wei) of token that can be sent towards the paymaster.

```ts
const data = getApprovalBasedPaymasterInput({
innerInput: new Uint8Array(),
minAllowance: 1n, // [!code focus]
token: "0x65C899B5fb8Eb9ae4da51D67E1fc417c7CB7e964",
})
```

### innerInput

- **Type:** `Hex | ByteArray`

Additional payload that can be sent to the paymaster to implement any logic .

```ts
const data = getApprovalBasedPaymasterInput({
innerInput: "0x0005040302010", // [!code focus]
minAllowance: 1n,
token: "0x65C899B5fb8Eb9ae4da51D67E1fc417c7CB7e964",
})
```
48 changes: 48 additions & 0 deletions site/pages/zksync/utilities/paymaster/getGeneralPaymasterInput.md
@@ -0,0 +1,48 @@
---
description: Returns encoded formatted general-based paymaster params.
---

# getGeneralPaymasterInput

Returns encoded formatted general-based paymaster params.

## Import
```ts
import { getGeneralPaymasterInput } from 'viem/zksync'
```

## Usage

```ts
import { getGeneralPaymasterInput } from 'viem/zksync'

const data = getGeneralPaymasterInput({
innerInput: '0x',
})
```

## Returns

`EncodeFunctionDataReturnType`

The `Hex` value of the provided general-based paymaster inputs.

## Parameters

### innerInput

Additional payload that can be sent to the paymaster to implement any logic

- **Type:** `Hex` or `ByteArray`

```ts
const data = getGeneralPaymasterInput({
innerInput: new Uint8Array([0, 1, 2, 3, 4, 5]), // [!code focus]
})
```

```ts
const data = getGeneralPaymasterInput({
innerInput: "0x0005040302010", // [!code focus]
})
```
18 changes: 18 additions & 0 deletions site/sidebar.ts
Expand Up @@ -1348,6 +1348,24 @@ export const sidebar = {
},
],
},
{
text: 'Utilities',
items: [
{
text: 'Paymaster',
items: [
{
text: 'getApprovalBasedPaymasterInput',
link: '/zksync/utilities/paymaster/getApprovalBasedPaymasterInput',
},
{
text: 'getGeneralPaymasterInput',
link: '/zksync/utilities/paymaster/getGeneralPaymasterInput',
},
],
},
],
},
],
},
} as const satisfies Sidebar
39 changes: 39 additions & 0 deletions src/zksync/constants/abis.ts
Expand Up @@ -422,3 +422,42 @@ export const contractDeployerAbi = [
type: 'function',
},
]

export const paymasterAbi = [
{
inputs: [
{
internalType: 'address',
name: '_token',
type: 'address',
},
{
internalType: 'uint256',
name: '_minAllowance',
type: 'uint256',
},
{
internalType: 'bytes',
name: '_innerInput',
type: 'bytes',
},
],
name: 'approvalBased',
outputs: [],
stateMutability: 'nonpayable',
type: 'function',
},
{
inputs: [
{
internalType: 'bytes',
name: 'input',
type: 'bytes',
},
],
name: 'general',
outputs: [],
stateMutability: 'nonpayable',
type: 'function',
},
]
11 changes: 11 additions & 0 deletions src/zksync/index.ts
Expand Up @@ -84,3 +84,14 @@ export type {
ZkSyncTransactionSerializedEIP712,
ZkSyncTransactionType,
} from './types/transaction.js'

export {
type GetApprovalBasedPaymasterInputParameters,
type GetApprovalBasedPaymasterInputReturnType,
getApprovalBasedPaymasterInput,
} from './utils/paymaster/getApprovalBasedPaymasterInput.js'
export {
type GetGeneralPaymasterInputParameters,
type GetGeneralPaymasterInputReturnType,
getGeneralPaymasterInput,
} from './utils/paymaster/getGeneralPaymasterInput.js'
47 changes: 47 additions & 0 deletions src/zksync/utils/paymaster/getApprovalBasedPaymasterInput.test.ts
@@ -0,0 +1,47 @@
import { expect, test } from 'vitest'

import { getApprovalBasedPaymasterInput } from './getApprovalBasedPaymasterInput.js'

test('args: token, minAllowance and innerInput as hex', () => {
expect(
getApprovalBasedPaymasterInput({
innerInput: '0x',
minAllowance: 1n,
token: '0x65C899B5fb8Eb9ae4da51D67E1fc417c7CB7e964',
}),
).toEqual(
'0x949431dc00000000000000000000000065c899b5fb8eb9ae4da51d67e1fc417c7cb7e964000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000',
)

expect(
getApprovalBasedPaymasterInput({
innerInput: '0x000102030405',
minAllowance: 2n,
token: '0x65C899B5fb8Eb9ae4da51D67E1fc417c7CB7e964',
}),
).toEqual(
'0x949431dc00000000000000000000000065c899b5fb8eb9ae4da51d67e1fc417c7cb7e9640000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000060001020304050000000000000000000000000000000000000000000000000000',
)
})

test('args: token, minAllowance and innerInput as byte array', () => {
expect(
getApprovalBasedPaymasterInput({
innerInput: new Uint8Array(),
minAllowance: 1n,
token: '0x65C899B5fb8Eb9ae4da51D67E1fc417c7CB7e964',
}),
).toEqual(
'0x949431dc00000000000000000000000065c899b5fb8eb9ae4da51d67e1fc417c7cb7e964000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000',
)

expect(
getApprovalBasedPaymasterInput({
innerInput: new Uint8Array([0, 1, 2, 3, 4, 5]),
minAllowance: 2n,
token: '0x65C899B5fb8Eb9ae4da51D67E1fc417c7CB7e964',
}),
).toEqual(
'0x949431dc00000000000000000000000065c899b5fb8eb9ae4da51d67e1fc417c7cb7e9640000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000060001020304050000000000000000000000000000000000000000000000000000',
)
})
29 changes: 29 additions & 0 deletions src/zksync/utils/paymaster/getApprovalBasedPaymasterInput.ts
@@ -0,0 +1,29 @@
import { type Address } from 'abitype'
import type { ByteArray, Hex } from '../../../types/misc.js'
import type { EncodeFunctionDataReturnType } from '../../../utils/abi/encodeFunctionData.js'
import { bytesToHex, encodeFunctionData } from '../../../utils/index.js'
import { paymasterAbi } from '../../constants/abis.js'

export type GetApprovalBasedPaymasterInputParameters = {
innerInput: Hex | ByteArray
minAllowance: bigint
token: Address
}

export type GetApprovalBasedPaymasterInputReturnType =
EncodeFunctionDataReturnType

export function getApprovalBasedPaymasterInput(
parameters: GetApprovalBasedPaymasterInputParameters,
): GetApprovalBasedPaymasterInputReturnType {
const { innerInput, minAllowance, token } = parameters

const innerInputHex =
typeof innerInput === 'string' ? innerInput : bytesToHex(innerInput)

return encodeFunctionData({
abi: paymasterAbi,
functionName: 'approvalBased',
args: [token, minAllowance, innerInputHex],
})
}
39 changes: 39 additions & 0 deletions src/zksync/utils/paymaster/getGeneralPaymasterInput.test.ts
@@ -0,0 +1,39 @@
import { expect, test } from 'vitest'

import { getGeneralPaymasterInput } from './getGeneralPaymasterInput.js'

test('args: innerInput field as hex', () => {
expect(
getGeneralPaymasterInput({
innerInput: '0x',
}),
).toEqual(
'0x8c5a344500000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000',
)

expect(
getGeneralPaymasterInput({
innerInput: '0x000102030405',
}),
).toEqual(
'0x8c5a3445000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000060001020304050000000000000000000000000000000000000000000000000000',
)
})

test('args: innerInput field as byte array', () => {
expect(
getGeneralPaymasterInput({
innerInput: new Uint8Array(),
}),
).toEqual(
'0x8c5a344500000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000',
)

expect(
getGeneralPaymasterInput({
innerInput: new Uint8Array([0, 1, 2, 3, 4, 5]),
}),
).toEqual(
'0x8c5a3445000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000060001020304050000000000000000000000000000000000000000000000000000',
)
})
25 changes: 25 additions & 0 deletions src/zksync/utils/paymaster/getGeneralPaymasterInput.ts
@@ -0,0 +1,25 @@
import type { ByteArray, Hex } from '../../../types/misc.js'
import type { EncodeFunctionDataReturnType } from '../../../utils/abi/encodeFunctionData.js'
import { bytesToHex, encodeFunctionData } from '../../../utils/index.js'
import { paymasterAbi } from '../../constants/abis.js'

export type GetGeneralPaymasterInputParameters = {
innerInput: Hex | ByteArray
}

export type GetGeneralPaymasterInputReturnType = EncodeFunctionDataReturnType

export function getGeneralPaymasterInput(
parameters: GetGeneralPaymasterInputParameters,
): GetGeneralPaymasterInputReturnType {
const { innerInput } = parameters

const innerInputHex =
typeof innerInput === 'string' ? innerInput : bytesToHex(innerInput)

return encodeFunctionData({
abi: paymasterAbi,
functionName: 'general',
args: [innerInputHex],
})
}

0 comments on commit 1f39629

Please sign in to comment.