@0xsequence/relayer 3.0.0-beta.18 → 3.0.0-beta.19

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.
Files changed (38) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/.turbo/turbo-lint.log +4 -0
  3. package/.turbo/turbo-typecheck.log +4 -0
  4. package/CHANGELOG.md +8 -0
  5. package/dist/preconditions/codec.d.ts.map +1 -1
  6. package/dist/preconditions/codec.js +55 -45
  7. package/dist/relayer/relayer.d.ts +1 -1
  8. package/dist/relayer/relayer.d.ts.map +1 -1
  9. package/dist/relayer/relayer.js +3 -1
  10. package/dist/relayer/rpc-relayer/index.d.ts +2 -2
  11. package/dist/relayer/rpc-relayer/index.d.ts.map +1 -1
  12. package/dist/relayer/rpc-relayer/index.js +10 -13
  13. package/dist/relayer/standard/eip6963.d.ts +1 -1
  14. package/dist/relayer/standard/eip6963.d.ts.map +1 -1
  15. package/dist/relayer/standard/eip6963.js +1 -1
  16. package/dist/relayer/standard/local.d.ts +1 -1
  17. package/dist/relayer/standard/local.d.ts.map +1 -1
  18. package/dist/relayer/standard/local.js +12 -15
  19. package/dist/relayer/standard/pk-relayer.d.ts +2 -2
  20. package/dist/relayer/standard/pk-relayer.d.ts.map +1 -1
  21. package/dist/relayer/standard/pk-relayer.js +1 -1
  22. package/dist/relayer/standard/sequence.d.ts +2 -2
  23. package/dist/relayer/standard/sequence.d.ts.map +1 -1
  24. package/dist/relayer/standard/sequence.js +1 -1
  25. package/eslint.config.js +4 -0
  26. package/package.json +8 -6
  27. package/src/preconditions/codec.ts +63 -39
  28. package/src/relayer/relayer.ts +3 -1
  29. package/src/relayer/rpc-relayer/index.ts +31 -23
  30. package/src/relayer/standard/eip6963.ts +2 -2
  31. package/src/relayer/standard/local.ts +33 -27
  32. package/src/relayer/standard/pk-relayer.ts +2 -2
  33. package/src/relayer/standard/sequence.ts +2 -2
  34. package/test/preconditions/codec.test.ts +11 -11
  35. package/test/preconditions/preconditions.test.ts +97 -138
  36. package/test/preconditions/selectors.test.ts +76 -254
  37. package/test/preconditions/types.test.ts +6 -6
  38. package/test/relayer/relayer.test.ts +3 -3
@@ -1,4 +1,4 @@
1
- import { Address, Provider, RpcTransport, Secp256k1 } from 'ox'
1
+ import { Address, Hex, Secp256k1 } from 'ox'
2
2
  import { describe, expect, it, vi } from 'vitest'
3
3
  import {
4
4
  Erc1155ApprovalPrecondition,
@@ -9,49 +9,50 @@ import {
9
9
  Erc721OwnershipPrecondition,
10
10
  NativeBalancePrecondition,
11
11
  } from '../../src/preconditions/types.js'
12
- import { LocalRelayer } from '../../src/standard/local.js'
13
- import { CAN_RUN_LIVE, RPC_URL } from '../../../../wallet/core/test/constants'
12
+ import {
13
+ LocalRelayer,
14
+ type GenericProvider,
15
+ } from '../../src/relayer/standard/local.js'
14
16
  import { Network } from '@0xsequence/wallet-primitives'
15
17
 
18
+ const CAN_RUN_LIVE = false
19
+ const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'
16
20
  const ERC20_IMPLICIT_MINT_CONTRACT = '0x041E0CDC028050519C8e6485B2d9840caf63773F'
17
21
 
18
22
  function randomAddress(): Address.Address {
19
23
  return Address.fromPublicKey(Secp256k1.getPublicKey({ privateKey: Secp256k1.randomPrivateKey() }))
20
24
  }
21
25
 
26
+ function createMockProvider(): GenericProvider {
27
+ return {
28
+ sendTransaction: vi.fn(),
29
+ getBalance: vi.fn(),
30
+ call: vi.fn(),
31
+ getTransactionReceipt: vi.fn(),
32
+ }
33
+ }
34
+
22
35
  describe('Preconditions', () => {
23
- const getProvider = async (): Promise<{ provider: Provider.Provider; chainId: number }> => {
24
- let provider: Provider.Provider
25
- let chainId: number = Network.ChainId.MAINNET
36
+ const getProvider = async (): Promise<{ provider: GenericProvider; chainId: number }> => {
37
+ const chainId = Network.ChainId.MAINNET
26
38
  if (CAN_RUN_LIVE) {
27
- provider = Provider.from(RpcTransport.fromHttp(RPC_URL!!))
28
- chainId = Number(await provider.request({ method: 'eth_chainId' }))
29
- } else {
30
- provider = {
31
- request: vi.fn(),
32
- on: vi.fn(),
33
- removeListener: vi.fn(),
34
- call: vi.fn(),
35
- sendTransaction: vi.fn(),
36
- getBalance: vi.fn(),
37
- } as unknown as Provider.Provider
39
+ throw new Error('Live tests not configured: set up RPC and GenericProvider adapter')
38
40
  }
39
-
40
- return { provider: provider!, chainId }
41
+ const provider = createMockProvider()
42
+ return { provider, chainId }
41
43
  }
42
44
 
43
45
  const testWalletAddress = randomAddress()
44
46
 
45
- const requireContractDeployed = async (provider: Provider.Provider, contract: Address.Address) => {
46
- const code = await provider.request({ method: 'eth_getCode', params: [contract, 'latest'] })
47
- if (code === '0x') {
48
- throw new Error(`Contract ${contract} not deployed`)
47
+ const requireContractDeployed = async (_provider: GenericProvider, _contract: Address.Address) => {
48
+ if (CAN_RUN_LIVE) {
49
+ throw new Error('Live contract check not implemented')
49
50
  }
50
51
  }
51
52
 
52
53
  it('should create and check native balance precondition', async () => {
53
54
  const { provider, chainId } = await getProvider()
54
- const relayer = new LocalRelayer(provider as any)
55
+ const relayer = new LocalRelayer(provider)
55
56
 
56
57
  const precondition = new NativeBalancePrecondition(
57
58
  testWalletAddress,
@@ -59,225 +60,183 @@ describe('Preconditions', () => {
59
60
  2000000000000000000n, // 2 ETH max
60
61
  )
61
62
 
62
- const intentPrecondition = {
63
+ const transactionPrecondition = {
63
64
  type: precondition.type(),
64
- chainId: chainId.toString(),
65
- data: JSON.stringify({
66
- address: precondition.address.toString(),
67
- min: precondition.min?.toString(),
68
- max: precondition.max?.toString(),
69
- }),
65
+ chainId,
66
+ ownerAddress: precondition.address.toString(),
67
+ tokenAddress: ZERO_ADDRESS,
68
+ minAmount: precondition.min ?? 0n,
70
69
  }
71
70
 
72
- if (!CAN_RUN_LIVE) {
73
- // Mock the balance check
74
- ;(provider as any).request.mockResolvedValue('0x16345785d8a0000') // 1.5 ETH in hex
75
- }
71
+ vi.mocked(provider.getBalance).mockResolvedValue(1500000000000000000n) // 1.5 ETH
76
72
 
77
- const isValid = await relayer.checkPrecondition(intentPrecondition)
73
+ const isValid = await relayer.checkPrecondition(transactionPrecondition)
78
74
  expect(isValid).toBe(true)
79
75
  })
80
76
 
81
77
  it('should create and check ERC20 balance precondition', async () => {
82
78
  const { provider, chainId } = await getProvider()
83
- const relayer = new LocalRelayer(provider as any)
84
- await requireContractDeployed(provider, ERC20_IMPLICIT_MINT_CONTRACT)
79
+ const relayer = new LocalRelayer(provider)
80
+ await requireContractDeployed(provider, Address.from(ERC20_IMPLICIT_MINT_CONTRACT))
85
81
 
86
82
  const precondition = new Erc20BalancePrecondition(
87
83
  testWalletAddress,
88
- ERC20_IMPLICIT_MINT_CONTRACT,
84
+ Address.from(ERC20_IMPLICIT_MINT_CONTRACT),
89
85
  1000000n, // 1 token min
90
86
  2000000n, // 2 tokens max
91
87
  )
92
88
 
93
- const intentPrecondition = {
89
+ const transactionPrecondition = {
94
90
  type: precondition.type(),
95
- chainId: chainId.toString(),
96
- data: JSON.stringify({
97
- address: precondition.address.toString(),
98
- token: precondition.token.toString(),
99
- min: precondition.min?.toString(),
100
- max: precondition.max?.toString(),
101
- }),
91
+ chainId,
92
+ ownerAddress: precondition.address.toString(),
93
+ tokenAddress: precondition.token.toString(),
94
+ minAmount: precondition.min ?? 0n,
102
95
  }
103
96
 
104
- if (!CAN_RUN_LIVE) {
105
- // Mock the balanceOf call
106
- ;(provider as any).call.mockResolvedValue('0x1e8480') // 1.5 tokens in hex
107
- }
97
+ vi.mocked(provider.call).mockResolvedValue('0x1e8480' as Hex.Hex) // 1.5 tokens in hex
108
98
 
109
- const isValid = await relayer.checkPrecondition(intentPrecondition)
99
+ const isValid = await relayer.checkPrecondition(transactionPrecondition)
110
100
  expect(isValid).toBe(true)
111
101
  })
112
102
 
113
103
  it('should create and check ERC20 approval precondition', async () => {
114
104
  const { provider, chainId } = await getProvider()
115
- const relayer = new LocalRelayer(provider as any)
116
- await requireContractDeployed(provider, ERC20_IMPLICIT_MINT_CONTRACT)
105
+ const relayer = new LocalRelayer(provider)
106
+ await requireContractDeployed(provider, Address.from(ERC20_IMPLICIT_MINT_CONTRACT))
117
107
 
118
108
  const operator = randomAddress()
119
109
  const precondition = new Erc20ApprovalPrecondition(
120
110
  testWalletAddress,
121
- ERC20_IMPLICIT_MINT_CONTRACT,
111
+ Address.from(ERC20_IMPLICIT_MINT_CONTRACT),
122
112
  operator,
123
113
  1000000n, // 1 token min approval
124
114
  )
125
115
 
126
- const intentPrecondition = {
116
+ const transactionPrecondition = {
127
117
  type: precondition.type(),
128
- chainId: chainId.toString(),
129
- data: JSON.stringify({
130
- address: precondition.address.toString(),
131
- token: precondition.token.toString(),
132
- operator: precondition.operator.toString(),
133
- min: precondition.min.toString(),
134
- }),
118
+ chainId,
119
+ ownerAddress: precondition.address.toString(),
120
+ tokenAddress: precondition.token.toString(),
121
+ minAmount: precondition.min,
135
122
  }
136
123
 
137
- if (!CAN_RUN_LIVE) {
138
- // Mock the allowance call
139
- ;(provider as any).call.mockResolvedValue('0x1e8480') // 1.5 tokens in hex
140
- }
124
+ vi.mocked(provider.call).mockResolvedValue('0x1e8480' as Hex.Hex) // 1.5 tokens in hex
141
125
 
142
- const isValid = await relayer.checkPrecondition(intentPrecondition)
126
+ const isValid = await relayer.checkPrecondition(transactionPrecondition)
143
127
  expect(isValid).toBe(true)
144
128
  })
145
129
 
146
130
  it('should create and check ERC721 ownership precondition', async () => {
147
131
  const { provider, chainId } = await getProvider()
148
- const relayer = new LocalRelayer(provider as any)
149
- await requireContractDeployed(provider, ERC20_IMPLICIT_MINT_CONTRACT)
132
+ const relayer = new LocalRelayer(provider)
133
+ await requireContractDeployed(provider, Address.from(ERC20_IMPLICIT_MINT_CONTRACT))
150
134
 
151
135
  const precondition = new Erc721OwnershipPrecondition(
152
136
  testWalletAddress,
153
- ERC20_IMPLICIT_MINT_CONTRACT,
137
+ Address.from(ERC20_IMPLICIT_MINT_CONTRACT),
154
138
  1n, // tokenId
155
139
  true, // must own
156
140
  )
157
141
 
158
- const intentPrecondition = {
142
+ const transactionPrecondition = {
159
143
  type: precondition.type(),
160
- chainId: chainId.toString(),
161
- data: JSON.stringify({
162
- address: precondition.address.toString(),
163
- token: precondition.token.toString(),
164
- tokenId: precondition.tokenId.toString(),
165
- owned: precondition.owned,
166
- }),
144
+ chainId,
145
+ ownerAddress: precondition.address.toString(),
146
+ tokenAddress: precondition.token.toString(),
147
+ minAmount: 0n,
167
148
  }
168
149
 
169
- if (!CAN_RUN_LIVE) {
170
- // Mock the ownerOf call
171
- ;(provider as any).call.mockResolvedValue(
172
- '0x000000000000000000000000' + testWalletAddress.toString().slice(2).toLowerCase(),
173
- )
174
- }
150
+ vi.mocked(provider.call).mockResolvedValue(
151
+ ('0x000000000000000000000000' + testWalletAddress.toString().slice(2).toLowerCase()) as Hex.Hex,
152
+ )
175
153
 
176
- const isValid = await relayer.checkPrecondition(intentPrecondition)
154
+ const isValid = await relayer.checkPrecondition(transactionPrecondition)
177
155
  expect(isValid).toBe(true)
178
156
  })
179
157
 
180
158
  it('should create and check ERC721 approval precondition', async () => {
181
159
  const { provider, chainId } = await getProvider()
182
- const relayer = new LocalRelayer(provider as any)
183
- await requireContractDeployed(provider, ERC20_IMPLICIT_MINT_CONTRACT)
160
+ const relayer = new LocalRelayer(provider)
161
+ await requireContractDeployed(provider, Address.from(ERC20_IMPLICIT_MINT_CONTRACT))
184
162
 
185
163
  const operator = randomAddress()
186
164
  const precondition = new Erc721ApprovalPrecondition(
187
165
  testWalletAddress,
188
- ERC20_IMPLICIT_MINT_CONTRACT,
166
+ Address.from(ERC20_IMPLICIT_MINT_CONTRACT),
189
167
  1n, // tokenId
190
168
  operator,
191
169
  )
192
170
 
193
- const intentPrecondition = {
171
+ const transactionPrecondition = {
194
172
  type: precondition.type(),
195
- chainId: chainId.toString(),
196
- data: JSON.stringify({
197
- address: precondition.address.toString(),
198
- token: precondition.token.toString(),
199
- tokenId: precondition.tokenId.toString(),
200
- operator: precondition.operator.toString(),
201
- }),
173
+ chainId,
174
+ ownerAddress: precondition.address.toString(),
175
+ tokenAddress: precondition.token.toString(),
176
+ minAmount: 0n,
202
177
  }
203
178
 
204
- if (!CAN_RUN_LIVE) {
205
- // Mock the getApproved call
206
- ;(provider as any).call.mockResolvedValue(
207
- '0x000000000000000000000000' + operator.toString().slice(2).toLowerCase(),
208
- )
209
- }
179
+ // getApproved returns 32-byte word: 12 zero bytes + 20-byte address. Codec uses ownerAddress as operator.
180
+ const approvedHex =
181
+ '0x' + '0'.repeat(24) + testWalletAddress.toString().slice(2).toLowerCase()
182
+ vi.mocked(provider.call).mockResolvedValue(approvedHex as Hex.Hex)
210
183
 
211
- const isValid = await relayer.checkPrecondition(intentPrecondition)
184
+ const isValid = await relayer.checkPrecondition(transactionPrecondition)
212
185
  expect(isValid).toBe(true)
213
186
  })
214
187
 
215
188
  it('should create and check ERC1155 balance precondition', async () => {
216
189
  const { provider, chainId } = await getProvider()
217
- const relayer = new LocalRelayer(provider as any)
218
- await requireContractDeployed(provider, ERC20_IMPLICIT_MINT_CONTRACT)
190
+ const relayer = new LocalRelayer(provider)
191
+ await requireContractDeployed(provider, Address.from(ERC20_IMPLICIT_MINT_CONTRACT))
219
192
 
220
193
  const precondition = new Erc1155BalancePrecondition(
221
194
  testWalletAddress,
222
- ERC20_IMPLICIT_MINT_CONTRACT,
195
+ Address.from(ERC20_IMPLICIT_MINT_CONTRACT),
223
196
  1n, // tokenId
224
197
  1000000n, // 1 token min
225
198
  2000000n, // 2 tokens max
226
199
  )
227
200
 
228
- const intentPrecondition = {
201
+ const transactionPrecondition = {
229
202
  type: precondition.type(),
230
- chainId: chainId.toString(),
231
- data: JSON.stringify({
232
- address: precondition.address.toString(),
233
- token: precondition.token.toString(),
234
- tokenId: precondition.tokenId.toString(),
235
- min: precondition.min?.toString(),
236
- max: precondition.max?.toString(),
237
- }),
203
+ chainId,
204
+ ownerAddress: precondition.address.toString(),
205
+ tokenAddress: precondition.token.toString(),
206
+ minAmount: precondition.min ?? 0n,
238
207
  }
239
208
 
240
- if (!CAN_RUN_LIVE) {
241
- // Mock the balanceOf call
242
- ;(provider as any).call.mockResolvedValue('0x1e8480') // 1.5 tokens in hex
243
- }
209
+ vi.mocked(provider.call).mockResolvedValue('0x1e8480' as Hex.Hex) // 1.5 tokens in hex
244
210
 
245
- const isValid = await relayer.checkPrecondition(intentPrecondition)
211
+ const isValid = await relayer.checkPrecondition(transactionPrecondition)
246
212
  expect(isValid).toBe(true)
247
213
  })
248
214
 
249
215
  it('should create and check ERC1155 approval precondition', async () => {
250
216
  const { provider, chainId } = await getProvider()
251
- const relayer = new LocalRelayer(provider as any)
252
- await requireContractDeployed(provider, ERC20_IMPLICIT_MINT_CONTRACT)
217
+ const relayer = new LocalRelayer(provider)
218
+ await requireContractDeployed(provider, Address.from(ERC20_IMPLICIT_MINT_CONTRACT))
253
219
 
254
220
  const operator = randomAddress()
255
221
  const precondition = new Erc1155ApprovalPrecondition(
256
222
  testWalletAddress,
257
- ERC20_IMPLICIT_MINT_CONTRACT,
223
+ Address.from(ERC20_IMPLICIT_MINT_CONTRACT),
258
224
  1n, // tokenId
259
225
  operator,
260
226
  1000000n, // 1 token min approval
261
227
  )
262
228
 
263
- const intentPrecondition = {
229
+ const transactionPrecondition = {
264
230
  type: precondition.type(),
265
- chainId: chainId.toString(),
266
- data: JSON.stringify({
267
- address: precondition.address.toString(),
268
- token: precondition.token.toString(),
269
- tokenId: precondition.tokenId.toString(),
270
- operator: precondition.operator.toString(),
271
- min: precondition.min.toString(),
272
- }),
231
+ chainId,
232
+ ownerAddress: precondition.address.toString(),
233
+ tokenAddress: precondition.token.toString(),
234
+ minAmount: precondition.min,
273
235
  }
274
236
 
275
- if (!CAN_RUN_LIVE) {
276
- // Mock the isApprovedForAll call
277
- ;(provider as any).call.mockResolvedValue('0x1') // true
278
- }
237
+ vi.mocked(provider.call).mockResolvedValue('0x1' as Hex.Hex) // true
279
238
 
280
- const isValid = await relayer.checkPrecondition(intentPrecondition)
239
+ const isValid = await relayer.checkPrecondition(transactionPrecondition)
281
240
  expect(isValid).toBe(true)
282
241
  })
283
242
  })