@0xsequence/wallet-core 3.0.0 → 3.0.1
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/.turbo/turbo-build.log +1 -1
- package/.turbo/turbo-lint.log +1 -1
- package/.turbo/turbo-test.log +290 -0
- package/.turbo/turbo-typecheck.log +1 -1
- package/CHANGELOG.md +10 -0
- package/dist/signers/session/explicit.d.ts.map +1 -1
- package/dist/signers/session/explicit.js +3 -6
- package/dist/signers/session/session.d.ts +1 -0
- package/dist/signers/session/session.d.ts.map +1 -1
- package/dist/signers/session/session.js +7 -0
- package/dist/signers/session-manager.d.ts +4 -0
- package/dist/signers/session-manager.d.ts.map +1 -1
- package/dist/signers/session-manager.js +65 -22
- package/package.json +4 -4
- package/src/signers/session/explicit.ts +3 -11
- package/src/signers/session/session.ts +10 -2
- package/src/signers/session-manager.ts +82 -25
- package/test/constants.ts +2 -0
- package/test/session-manager.test.ts +345 -3
package/.turbo/turbo-build.log
CHANGED
package/.turbo/turbo-lint.log
CHANGED
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
|
|
2
|
+
> @0xsequence/wallet-core@3.0.0 test /home/taylan/development/sequence/sequence.js/packages/wallet/core
|
|
3
|
+
> vitest run
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
[1m[46m RUN [49m[22m [36mv4.0.18 [39m[90m/home/taylan/development/sequence/sequence.js/packages/wallet/core[39m
|
|
7
|
+
|
|
8
|
+
[32m✓[39m test/signers-pk-encrypted.test.ts [2m([22m[2m19 tests[22m[2m)[22m[32m 29[2mms[22m[39m
|
|
9
|
+
[32m✓[39m test/state/debug.test.ts [2m([22m[2m14 tests[22m[2m)[22m[32m 17[2mms[22m[39m
|
|
10
|
+
[32m✓[39m test/state/local/memory.test.ts [2m([22m[2m16 tests[22m[2m)[22m[32m 7[2mms[22m[39m
|
|
11
|
+
[32m✓[39m test/envelope.test.ts [2m([22m[2m39 tests[22m[2m)[22m[32m 10[2mms[22m[39m
|
|
12
|
+
[32m✓[39m test/signers-passkey.test.ts [2m([22m[2m29 tests[22m[2m)[22m[32m 22[2mms[22m[39m
|
|
13
|
+
[32m✓[39m test/signers-pk.test.ts [2m([22m[2m16 tests[22m[2m)[22m[32m 52[2mms[22m[39m
|
|
14
|
+
[32m✓[39m test/relayer/bundler.test.ts [2m([22m[2m13 tests[22m[2m)[22m[32m 8[2mms[22m[39m
|
|
15
|
+
[32m✓[39m test/signers-index.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 6[2mms[22m[39m
|
|
16
|
+
[32m✓[39m test/state/cached.test.ts [2m([22m[2m32 tests[22m[2m)[22m[32m 32[2mms[22m[39m
|
|
17
|
+
[32m✓[39m test/state/utils.test.ts [2m([22m[2m14 tests[22m[2m)[22m[32m 41[2mms[22m[39m
|
|
18
|
+
[90mstdout[2m | test/utils/session/permission-builder.test.ts[2m > [22m[2mPermissionBuilder[2m > [22m[2mshould build an exact match permission
|
|
19
|
+
[22m[39mrandom calldata 0x13c07e55dfcc1767dc61947cf4e682647766111b1a6eccbb142b129a33561172792fd57005cdccd72748c3712c683432100286ff7ec0350355e3
|
|
20
|
+
random calldata 0x676403f8db056f24887c114919b8d73c
|
|
21
|
+
random calldata 0x1cef0b331be4ab4bcedaf8c60ef55cd08d9f8860cbd690f98f089cc4eb790fb0b7fbda64a4c99af02d01c8af7fc8d1ac24bd49
|
|
22
|
+
random calldata 0x6241c96dc68afea32ed2b8bb7de83e64c5972f8118aaeb3a6f9efb42cba1a3e0a89e283649ce9c40e01fb5fe297265c5cd2f44bcf4775834006f67b3e5
|
|
23
|
+
random calldata 0xfd645629d946efed2d538e40b6236f9a32bbfe7f5d9a911e8d4ae6e3c84aa04db842d8d138644b0748a4eb0da4f2b6099feba18c098306953ee5f61d64dc94d47cfbc6ae4afc5c42fc4c21c8abfe042a410132f8e0b8dadbf969169b6f80ca18
|
|
24
|
+
random calldata 0x413a7b1c2623423d03469e0d1be53bf6c007f178b9a2e08ffdc7ea77192fdf69656783434f350bd5bffd9076364559785805d8e56548efbe122328b23f3a162bcfc7baa248cfa3b336bd12a7e7f50eebb3805b9eef
|
|
25
|
+
random calldata 0x550e368c11c8718b4b555d700a916ba152192b12cf2504deb7
|
|
26
|
+
random calldata 0x9a9f47cadb002c7c9d320bfc3c230521b0f78d9a6ef5c2f90d89b5632e98f7f395af3acc5cf2bee8ff528012a52d7127b6a41acbbbcb3a72278a954b4d81bc3a3b13b8d9d3240b47798ba9790700f58c4216aae2f5a2a10c0145cf6c65
|
|
27
|
+
random calldata 0x
|
|
28
|
+
random calldata 0x34dd00e3b98f155f8e0e984bde
|
|
29
|
+
|
|
30
|
+
[90mstdout[2m | test/wallet.test.ts
|
|
31
|
+
[22m[39m[dotenv@17.3.1] injecting env (0) from .env.test.local -- tip: ⚙️ specify custom .env file path with { path: '/custom/path/.env' }
|
|
32
|
+
|
|
33
|
+
[32m✓[39m test/signers-guard.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 18[2mms[22m[39m
|
|
34
|
+
[90mstdout[2m | test/session-manager.test.ts
|
|
35
|
+
[22m[39m[dotenv@17.3.1] injecting env (0) from .env.test.local -- tip: ⚙️ specify custom .env file path with { path: '/custom/path/.env' }
|
|
36
|
+
|
|
37
|
+
[32m✓[39m test/signers-session-explicit.test.ts [2m([22m[2m25 tests[22m[2m)[22m[32m 18[2mms[22m[39m
|
|
38
|
+
[32m✓[39m test/utils/session/permission-builder.test.ts [2m([22m[2m28 tests[22m[2m)[22m[32m 42[2mms[22m[39m
|
|
39
|
+
[31m❯[39m test/wallet.test.ts [2m([22m[2m8 tests[22m[2m | [22m[31m4 failed[39m[2m)[22m[32m 57[2mms[22m[39m
|
|
40
|
+
[31m [31m×[31m should sign a message[39m[32m 42[2mms[22m[39m
|
|
41
|
+
[31m [31m×[31m should sign a typed data message[39m[32m 3[2mms[22m[39m
|
|
42
|
+
[31m [31m×[31m should sign a message[39m[32m 2[2mms[22m[39m
|
|
43
|
+
[31m [31m×[31m should sign a typed data message[39m[32m 2[2mms[22m[39m
|
|
44
|
+
[32m✓[39m Should reject unsafe wallet creation[32m 2[2mms[22m[39m
|
|
45
|
+
[32m✓[39m Should reject unsafe wallet update[32m 3[2mms[22m[39m
|
|
46
|
+
[32m✓[39m Should accept unsafe wallet creation in unsafe mode[32m 1[2mms[22m[39m
|
|
47
|
+
[32m✓[39m Should accept unsafe wallet update in unsafe mode[32m 1[2mms[22m[39m
|
|
48
|
+
[32m✓[39m test/signers-session-implicit.test.ts [2m([22m[2m28 tests[22m[2m)[22m[32m 88[2mms[22m[39m
|
|
49
|
+
[31m❯[39m test/session-manager.test.ts [2m([22m[2m90 tests[22m[2m | [22m[31m85 failed[39m[2m)[22m[32m 205[2mms[22m[39m
|
|
50
|
+
[31m [31m×[31m should load from state[39m[32m 35[2mms[22m[39m
|
|
51
|
+
[31m [31m×[31m should create and sign with an implicit session[39m[32m 35[2mms[22m[39m
|
|
52
|
+
[31m [31m×[31m should create and sign with a multiple implicit sessions[39m[32m 8[2mms[22m[39m
|
|
53
|
+
[31m [31m×[31m should fail to sign with a multiple implicit sessions with different identity signers[39m[32m 8[2mms[22m[39m
|
|
54
|
+
[31m [31m×[31m should create and sign with an explicit session[39m[32m 2[2mms[22m[39m
|
|
55
|
+
[31m [31m×[31m should create and sign with an explicit session with 0 chainId[39m[32m 2[2mms[22m[39m
|
|
56
|
+
[32m✓[39m should fail to sign with an expired explicit session[32m 4[2mms[22m[39m
|
|
57
|
+
[31m [31m×[31m signs a payload using an implicit session[39m[32m 3[2mms[22m[39m
|
|
58
|
+
[31m [31m×[31m signs a payload using an explicit session with allowAll and value limit[39m[32m 1[2mms[22m[39m
|
|
59
|
+
[31m [31m×[31m signs using explicit session with onlyOnce, consumes usage and rejects second call[39m[32m 1[2mms[22m[39m
|
|
60
|
+
[31m [31m×[31m signs an ERC20 approve using an explicit session[39m[32m 1[2mms[22m[39m
|
|
61
|
+
[31m [31m×[31m signs a payload sending value using an explicit session[39m[32m 1[2mms[22m[39m
|
|
62
|
+
[31m [31m×[31m signs a payload sending two transactions with cumulative rules using an explicit session[39m[32m 1[2mms[22m[39m
|
|
63
|
+
[31m [31m×[31m using explicit session, sends value, then uses a non-incremental permission[39m[32m 1[2mms[22m[39m
|
|
64
|
+
[31m [31m×[31m two explicit sessions with same value limit: exhaust first then second send uses second session (increment from non-increment calls only)[39m[32m 1[2mms[22m[39m
|
|
65
|
+
[31m [31m×[31m prepareIncrement returns null when calls contain only an increment call (no non-increment calls)[39m[32m 1[2mms[22m[39m
|
|
66
|
+
[31m [31m×[31m prepareIncrement([increment, nonIncrementCall]) produces same increment data as prepareIncrement([nonIncrementCall])[39m[32m 1[2mms[22m[39m
|
|
67
|
+
[31m [31m×[31m payload with implicit and explicit: increment built only from explicit non-increment call[39m[32m 1[2mms[22m[39m
|
|
68
|
+
[31m [31m×[31m should load from state[39m[32m 1[2mms[22m[39m
|
|
69
|
+
[31m [31m×[31m should create and sign with an implicit session[39m[32m 3[2mms[22m[39m
|
|
70
|
+
[31m [31m×[31m should create and sign with a multiple implicit sessions[39m[32m 3[2mms[22m[39m
|
|
71
|
+
[31m [31m×[31m should fail to sign with a multiple implicit sessions with different identity signers[39m[32m 3[2mms[22m[39m
|
|
72
|
+
[31m [31m×[31m should create and sign with an explicit session[39m[32m 1[2mms[22m[39m
|
|
73
|
+
[31m [31m×[31m should create and sign with an explicit session with 0 chainId[39m[32m 1[2mms[22m[39m
|
|
74
|
+
[32m✓[39m should fail to sign with an expired explicit session[32m 1[2mms[22m[39m
|
|
75
|
+
[31m [31m×[31m signs a payload using an implicit session[39m[32m 1[2mms[22m[39m
|
|
76
|
+
[31m [31m×[31m signs a payload using an explicit session with allowAll and value limit[39m[32m 1[2mms[22m[39m
|
|
77
|
+
[31m [31m×[31m signs using explicit session with onlyOnce, consumes usage and rejects second call[39m[32m 1[2mms[22m[39m
|
|
78
|
+
[31m [31m×[31m signs an ERC20 approve using an explicit session[39m[32m 1[2mms[22m[39m
|
|
79
|
+
[31m [31m×[31m signs a payload sending value using an explicit session[39m[32m 1[2mms[22m[39m
|
|
80
|
+
[31m [31m×[31m signs a payload sending two transactions with cumulative rules using an explicit session[39m[32m 1[2mms[22m[39m
|
|
81
|
+
[31m [31m×[31m using explicit session, sends value, then uses a non-incremental permission[39m[32m 1[2mms[22m[39m
|
|
82
|
+
[31m [31m×[31m two explicit sessions with same value limit: exhaust first then second send uses second session (increment from non-increment calls only)[39m[32m 1[2mms[22m[39m
|
|
83
|
+
[31m [31m×[31m prepareIncrement returns null when calls contain only an increment call (no non-increment calls)[39m[32m 1[2mms[22m[39m
|
|
84
|
+
[31m [31m×[31m prepareIncrement([increment, nonIncrementCall]) produces same increment data as prepareIncrement([nonIncrementCall])[39m[32m 1[2mms[22m[39m
|
|
85
|
+
[31m [31m×[31m payload with implicit and explicit: increment built only from explicit non-increment call[39m[32m 1[2mms[22m[39m
|
|
86
|
+
[31m [31m×[31m should load from state[39m[32m 2[2mms[22m[39m
|
|
87
|
+
[31m [31m×[31m should create and sign with an implicit session[39m[32m 2[2mms[22m[39m
|
|
88
|
+
[31m [31m×[31m should create and sign with a multiple implicit sessions[39m[32m 3[2mms[22m[39m
|
|
89
|
+
[31m [31m×[31m should fail to sign with a multiple implicit sessions with different identity signers[39m[32m 3[2mms[22m[39m
|
|
90
|
+
[31m [31m×[31m should create and sign with an explicit session[39m[32m 1[2mms[22m[39m
|
|
91
|
+
[31m [31m×[31m should create and sign with an explicit session with 0 chainId[39m[32m 1[2mms[22m[39m
|
|
92
|
+
[32m✓[39m should fail to sign with an expired explicit session[32m 1[2mms[22m[39m
|
|
93
|
+
[31m [31m×[31m signs a payload using an implicit session[39m[32m 1[2mms[22m[39m
|
|
94
|
+
[31m [31m×[31m signs a payload using an explicit session with allowAll and value limit[39m[32m 1[2mms[22m[39m
|
|
95
|
+
[31m [31m×[31m signs using explicit session with onlyOnce, consumes usage and rejects second call[39m[32m 1[2mms[22m[39m
|
|
96
|
+
[31m [31m×[31m signs an ERC20 approve using an explicit session[39m[32m 1[2mms[22m[39m
|
|
97
|
+
[31m [31m×[31m signs a payload sending value using an explicit session[39m[32m 1[2mms[22m[39m
|
|
98
|
+
[31m [31m×[31m signs a payload sending two transactions with cumulative rules using an explicit session[39m[32m 1[2mms[22m[39m
|
|
99
|
+
[31m [31m×[31m using explicit session, sends value, then uses a non-incremental permission[39m[32m 1[2mms[22m[39m
|
|
100
|
+
[31m [31m×[31m two explicit sessions with same value limit: exhaust first then second send uses second session (increment from non-increment calls only)[39m[32m 1[2mms[22m[39m
|
|
101
|
+
[31m [31m×[31m prepareIncrement returns null when calls contain only an increment call (no non-increment calls)[39m[32m 1[2mms[22m[39m
|
|
102
|
+
[31m [31m×[31m prepareIncrement([increment, nonIncrementCall]) produces same increment data as prepareIncrement([nonIncrementCall])[39m[32m 1[2mms[22m[39m
|
|
103
|
+
[31m [31m×[31m payload with implicit and explicit: increment built only from explicit non-increment call[39m[32m 1[2mms[22m[39m
|
|
104
|
+
[31m [31m×[31m should load from state[39m[32m 1[2mms[22m[39m
|
|
105
|
+
[31m [31m×[31m should create and sign with an implicit session[39m[32m 2[2mms[22m[39m
|
|
106
|
+
[31m [31m×[31m should create and sign with a multiple implicit sessions[39m[32m 6[2mms[22m[39m
|
|
107
|
+
[31m [31m×[31m should fail to sign with a multiple implicit sessions with different identity signers[39m[32m 4[2mms[22m[39m
|
|
108
|
+
[31m [31m×[31m should create and sign with an explicit session[39m[32m 1[2mms[22m[39m
|
|
109
|
+
[31m [31m×[31m should create and sign with an explicit session with 0 chainId[39m[32m 1[2mms[22m[39m
|
|
110
|
+
[32m✓[39m should fail to sign with an expired explicit session[32m 1[2mms[22m[39m
|
|
111
|
+
[31m [31m×[31m signs a payload using an implicit session[39m[32m 1[2mms[22m[39m
|
|
112
|
+
[31m [31m×[31m signs a payload using an explicit session with allowAll and value limit[39m[32m 1[2mms[22m[39m
|
|
113
|
+
[31m [31m×[31m signs using explicit session with onlyOnce, consumes usage and rejects second call[39m[32m 1[2mms[22m[39m
|
|
114
|
+
[31m [31m×[31m signs an ERC20 approve using an explicit session[39m[32m 1[2mms[22m[39m
|
|
115
|
+
[31m [31m×[31m signs a payload sending value using an explicit session[39m[32m 1[2mms[22m[39m
|
|
116
|
+
[31m [31m×[31m signs a payload sending two transactions with cumulative rules using an explicit session[39m[32m 1[2mms[22m[39m
|
|
117
|
+
[31m [31m×[31m using explicit session, sends value, then uses a non-incremental permission[39m[32m 1[2mms[22m[39m
|
|
118
|
+
[31m [31m×[31m two explicit sessions with same value limit: exhaust first then second send uses second session (increment from non-increment calls only)[39m[32m 3[2mms[22m[39m
|
|
119
|
+
[31m [31m×[31m prepareIncrement returns null when calls contain only an increment call (no non-increment calls)[39m[32m 1[2mms[22m[39m
|
|
120
|
+
[31m [31m×[31m prepareIncrement([increment, nonIncrementCall]) produces same increment data as prepareIncrement([nonIncrementCall])[39m[32m 1[2mms[22m[39m
|
|
121
|
+
[31m [31m×[31m payload with implicit and explicit: increment built only from explicit non-increment call[39m[32m 1[2mms[22m[39m
|
|
122
|
+
[31m [31m×[31m should load from state[39m[32m 1[2mms[22m[39m
|
|
123
|
+
[31m [31m×[31m should create and sign with an implicit session[39m[32m 3[2mms[22m[39m
|
|
124
|
+
[31m [31m×[31m should create and sign with a multiple implicit sessions[39m[32m 3[2mms[22m[39m
|
|
125
|
+
[31m [31m×[31m should fail to sign with a multiple implicit sessions with different identity signers[39m[32m 3[2mms[22m[39m
|
|
126
|
+
[31m [31m×[31m should create and sign with an explicit session[39m[32m 1[2mms[22m[39m
|
|
127
|
+
[31m [31m×[31m should create and sign with an explicit session with 0 chainId[39m[32m 1[2mms[22m[39m
|
|
128
|
+
[32m✓[39m should fail to sign with an expired explicit session[32m 2[2mms[22m[39m
|
|
129
|
+
[31m [31m×[31m signs a payload using an implicit session[39m[32m 1[2mms[22m[39m
|
|
130
|
+
[31m [31m×[31m signs a payload using an explicit session with allowAll and value limit[39m[32m 1[2mms[22m[39m
|
|
131
|
+
[31m [31m×[31m signs using explicit session with onlyOnce, consumes usage and rejects second call[39m[32m 1[2mms[22m[39m
|
|
132
|
+
[31m [31m×[31m signs an ERC20 approve using an explicit session[39m[32m 1[2mms[22m[39m
|
|
133
|
+
[31m [31m×[31m signs a payload sending value using an explicit session[39m[32m 1[2mms[22m[39m
|
|
134
|
+
[31m [31m×[31m signs a payload sending two transactions with cumulative rules using an explicit session[39m[32m 1[2mms[22m[39m
|
|
135
|
+
[31m [31m×[31m using explicit session, sends value, then uses a non-incremental permission[39m[32m 1[2mms[22m[39m
|
|
136
|
+
[31m [31m×[31m two explicit sessions with same value limit: exhaust first then second send uses second session (increment from non-increment calls only)[39m[32m 2[2mms[22m[39m
|
|
137
|
+
[31m [31m×[31m prepareIncrement returns null when calls contain only an increment call (no non-increment calls)[39m[32m 1[2mms[22m[39m
|
|
138
|
+
[31m [31m×[31m prepareIncrement([increment, nonIncrementCall]) produces same increment data as prepareIncrement([nonIncrementCall])[39m[32m 1[2mms[22m[39m
|
|
139
|
+
[31m [31m×[31m payload with implicit and explicit: increment built only from explicit non-increment call[39m[32m 1[2mms[22m[39m
|
|
140
|
+
|
|
141
|
+
[31m⎯⎯⎯⎯⎯⎯[39m[1m[41m Failed Tests 89 [49m[22m[31m⎯⎯⎯⎯⎯⎯⎯[39m
|
|
142
|
+
|
|
143
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Dev1)[2m > [22mshould load from state
|
|
144
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Dev1)[2m > [22mshould create and sign with an implicit session
|
|
145
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Dev1)[2m > [22mshould create and sign with a multiple implicit sessions
|
|
146
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Dev1)[2m > [22mshould fail to sign with a multiple implicit sessions with different identity signers
|
|
147
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Dev1)[2m > [22mshould create and sign with an explicit session
|
|
148
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Dev1)[2m > [22mshould create and sign with an explicit session with 0 chainId
|
|
149
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Dev1)[2m > [22msigns a payload using an implicit session
|
|
150
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Dev1)[2m > [22msigns a payload using an explicit session with allowAll and value limit
|
|
151
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Dev1)[2m > [22msigns using explicit session with onlyOnce, consumes usage and rejects second call
|
|
152
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Dev1)[2m > [22msigns an ERC20 approve using an explicit session
|
|
153
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Dev1)[2m > [22msigns a payload sending value using an explicit session
|
|
154
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Dev1)[2m > [22msigns a payload sending two transactions with cumulative rules using an explicit session
|
|
155
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Dev1)[2m > [22musing explicit session, sends value, then uses a non-incremental permission
|
|
156
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Dev1)[2m > [22mtwo explicit sessions with same value limit: exhaust first then second send uses second session (increment from non-increment calls only)
|
|
157
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Dev1)[2m > [22mincrement built from non-increment calls only[2m > [22mprepareIncrement returns null when calls contain only an increment call (no non-increment calls)
|
|
158
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Dev1)[2m > [22mincrement built from non-increment calls only[2m > [22mprepareIncrement([increment, nonIncrementCall]) produces same increment data as prepareIncrement([nonIncrementCall])
|
|
159
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Dev1)[2m > [22mincrement built from non-increment calls only[2m > [22mpayload with implicit and explicit: increment built only from explicit non-increment call
|
|
160
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Dev2)[2m > [22mshould load from state
|
|
161
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Dev2)[2m > [22mshould create and sign with an implicit session
|
|
162
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Dev2)[2m > [22mshould create and sign with a multiple implicit sessions
|
|
163
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Dev2)[2m > [22mshould fail to sign with a multiple implicit sessions with different identity signers
|
|
164
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Dev2)[2m > [22mshould create and sign with an explicit session
|
|
165
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Dev2)[2m > [22mshould create and sign with an explicit session with 0 chainId
|
|
166
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Dev2)[2m > [22msigns a payload using an implicit session
|
|
167
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Dev2)[2m > [22msigns a payload using an explicit session with allowAll and value limit
|
|
168
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Dev2)[2m > [22msigns using explicit session with onlyOnce, consumes usage and rejects second call
|
|
169
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Dev2)[2m > [22msigns an ERC20 approve using an explicit session
|
|
170
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Dev2)[2m > [22msigns a payload sending value using an explicit session
|
|
171
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Dev2)[2m > [22msigns a payload sending two transactions with cumulative rules using an explicit session
|
|
172
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Dev2)[2m > [22musing explicit session, sends value, then uses a non-incremental permission
|
|
173
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Dev2)[2m > [22mtwo explicit sessions with same value limit: exhaust first then second send uses second session (increment from non-increment calls only)
|
|
174
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Dev2)[2m > [22mincrement built from non-increment calls only[2m > [22mprepareIncrement returns null when calls contain only an increment call (no non-increment calls)
|
|
175
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Dev2)[2m > [22mincrement built from non-increment calls only[2m > [22mprepareIncrement([increment, nonIncrementCall]) produces same increment data as prepareIncrement([nonIncrementCall])
|
|
176
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Dev2)[2m > [22mincrement built from non-increment calls only[2m > [22mpayload with implicit and explicit: increment built only from explicit non-increment call
|
|
177
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Rc3)[2m > [22mshould load from state
|
|
178
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Rc3)[2m > [22mshould create and sign with an implicit session
|
|
179
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Rc3)[2m > [22mshould create and sign with a multiple implicit sessions
|
|
180
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Rc3)[2m > [22mshould fail to sign with a multiple implicit sessions with different identity signers
|
|
181
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Rc3)[2m > [22mshould create and sign with an explicit session
|
|
182
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Rc3)[2m > [22mshould create and sign with an explicit session with 0 chainId
|
|
183
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Rc3)[2m > [22msigns a payload using an implicit session
|
|
184
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Rc3)[2m > [22msigns a payload using an explicit session with allowAll and value limit
|
|
185
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Rc3)[2m > [22msigns using explicit session with onlyOnce, consumes usage and rejects second call
|
|
186
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Rc3)[2m > [22msigns an ERC20 approve using an explicit session
|
|
187
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Rc3)[2m > [22msigns a payload sending value using an explicit session
|
|
188
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Rc3)[2m > [22msigns a payload sending two transactions with cumulative rules using an explicit session
|
|
189
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Rc3)[2m > [22musing explicit session, sends value, then uses a non-incremental permission
|
|
190
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Rc3)[2m > [22mtwo explicit sessions with same value limit: exhaust first then second send uses second session (increment from non-increment calls only)
|
|
191
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Rc3)[2m > [22mincrement built from non-increment calls only[2m > [22mprepareIncrement returns null when calls contain only an increment call (no non-increment calls)
|
|
192
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Rc3)[2m > [22mincrement built from non-increment calls only[2m > [22mprepareIncrement([increment, nonIncrementCall]) produces same increment data as prepareIncrement([nonIncrementCall])
|
|
193
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Rc3)[2m > [22mincrement built from non-increment calls only[2m > [22mpayload with implicit and explicit: increment built only from explicit non-increment call
|
|
194
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Rc4)[2m > [22mshould load from state
|
|
195
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Rc4)[2m > [22mshould create and sign with an implicit session
|
|
196
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Rc4)[2m > [22mshould create and sign with a multiple implicit sessions
|
|
197
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Rc4)[2m > [22mshould fail to sign with a multiple implicit sessions with different identity signers
|
|
198
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Rc4)[2m > [22mshould create and sign with an explicit session
|
|
199
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Rc4)[2m > [22mshould create and sign with an explicit session with 0 chainId
|
|
200
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Rc4)[2m > [22msigns a payload using an implicit session
|
|
201
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Rc4)[2m > [22msigns a payload using an explicit session with allowAll and value limit
|
|
202
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Rc4)[2m > [22msigns using explicit session with onlyOnce, consumes usage and rejects second call
|
|
203
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Rc4)[2m > [22msigns an ERC20 approve using an explicit session
|
|
204
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Rc4)[2m > [22msigns a payload sending value using an explicit session
|
|
205
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Rc4)[2m > [22msigns a payload sending two transactions with cumulative rules using an explicit session
|
|
206
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Rc4)[2m > [22musing explicit session, sends value, then uses a non-incremental permission
|
|
207
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Rc4)[2m > [22mtwo explicit sessions with same value limit: exhaust first then second send uses second session (increment from non-increment calls only)
|
|
208
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Rc4)[2m > [22mincrement built from non-increment calls only[2m > [22mprepareIncrement returns null when calls contain only an increment call (no non-increment calls)
|
|
209
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Rc4)[2m > [22mincrement built from non-increment calls only[2m > [22mprepareIncrement([increment, nonIncrementCall]) produces same increment data as prepareIncrement([nonIncrementCall])
|
|
210
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Rc4)[2m > [22mincrement built from non-increment calls only[2m > [22mpayload with implicit and explicit: increment built only from explicit non-increment call
|
|
211
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Rc5)[2m > [22mshould load from state
|
|
212
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Rc5)[2m > [22mshould create and sign with an implicit session
|
|
213
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Rc5)[2m > [22mshould create and sign with a multiple implicit sessions
|
|
214
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Rc5)[2m > [22mshould fail to sign with a multiple implicit sessions with different identity signers
|
|
215
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Rc5)[2m > [22mshould create and sign with an explicit session
|
|
216
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Rc5)[2m > [22mshould create and sign with an explicit session with 0 chainId
|
|
217
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Rc5)[2m > [22msigns a payload using an implicit session
|
|
218
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Rc5)[2m > [22msigns a payload using an explicit session with allowAll and value limit
|
|
219
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Rc5)[2m > [22msigns using explicit session with onlyOnce, consumes usage and rejects second call
|
|
220
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Rc5)[2m > [22msigns an ERC20 approve using an explicit session
|
|
221
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Rc5)[2m > [22msigns a payload sending value using an explicit session
|
|
222
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Rc5)[2m > [22msigns a payload sending two transactions with cumulative rules using an explicit session
|
|
223
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Rc5)[2m > [22musing explicit session, sends value, then uses a non-incremental permission
|
|
224
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Rc5)[2m > [22mtwo explicit sessions with same value limit: exhaust first then second send uses second session (increment from non-increment calls only)
|
|
225
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Rc5)[2m > [22mincrement built from non-increment calls only[2m > [22mprepareIncrement returns null when calls contain only an increment call (no non-increment calls)
|
|
226
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Rc5)[2m > [22mincrement built from non-increment calls only[2m > [22mprepareIncrement([increment, nonIncrementCall]) produces same increment data as prepareIncrement([nonIncrementCall])
|
|
227
|
+
[41m[1m FAIL [22m[49m test/session-manager.test.ts[2m > [22mSessionManager (Rc5)[2m > [22mincrement built from non-increment calls only[2m > [22mpayload with implicit and explicit: increment built only from explicit non-increment call
|
|
228
|
+
[41m[1m FAIL [22m[49m test/wallet.test.ts[2m > [22mWallet[2m > [22mdeployed[2m > [22mshould sign a message
|
|
229
|
+
[41m[1m FAIL [22m[49m test/wallet.test.ts[2m > [22mWallet[2m > [22mdeployed[2m > [22mshould sign a typed data message
|
|
230
|
+
[41m[1m FAIL [22m[49m test/wallet.test.ts[2m > [22mWallet[2m > [22mnot-deployed[2m > [22mshould sign a message
|
|
231
|
+
[41m[1m FAIL [22m[49m test/wallet.test.ts[2m > [22mWallet[2m > [22mnot-deployed[2m > [22mshould sign a typed data message
|
|
232
|
+
[31m[1mRpcResponse.InternalError[22m: fetch failed[39m
|
|
233
|
+
[90m [2m❯[22m ../../../node_modules/.pnpm/ox@0.9.17_typescript@5.9.3_zod@4.2.0/node_modules/ox/_esm/core/internal/promise.js:[2m20:25[22m[39m
|
|
234
|
+
|
|
235
|
+
[31m[1mCaused by: TypeError[22m: fetch failed[39m
|
|
236
|
+
[90m [2m❯[22m ../../../node_modules/.pnpm/ox@0.9.17_typescript@5.9.3_zod@4.2.0/node_modules/ox/_esm/core/internal/promise.js:[2m20:25[22m[39m
|
|
237
|
+
|
|
238
|
+
{
|
|
239
|
+
stack: 'AggregateError: \n' +
|
|
240
|
+
' at internalConnectMultiple (node:net:1134:18)\n' +
|
|
241
|
+
' at internalConnectMultiple (node:net:1210:5)\n' +
|
|
242
|
+
' at afterConnectMultiple (node:net:1715:7)',
|
|
243
|
+
errors: [
|
|
244
|
+
{
|
|
245
|
+
stack: 'Error: connect ECONNREFUSED 127.0.0.1:8545\n' +
|
|
246
|
+
' at createConnectionError (node:net:1678:14)\n' +
|
|
247
|
+
' at afterConnectMultiple (node:net:1708:16)',
|
|
248
|
+
message: 'connect ECONNREFUSED 127.0.0.1:8545',
|
|
249
|
+
errno: -111,
|
|
250
|
+
code: 'ECONNREFUSED',
|
|
251
|
+
syscall: 'connect',
|
|
252
|
+
address: '127.0.0.1',
|
|
253
|
+
port: 8545,
|
|
254
|
+
constructor: 'Function<Error>',
|
|
255
|
+
name: 'Error',
|
|
256
|
+
toString: 'Function<toString>'
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
stack: 'Error: connect ENETUNREACH ::1:8545 - Local (:::0)\n' +
|
|
260
|
+
' at internalConnectMultiple (node:net:1206:16)\n' +
|
|
261
|
+
' at afterConnectMultiple (node:net:1715:7)',
|
|
262
|
+
message: 'connect ENETUNREACH ::1:8545 - Local (:::0)',
|
|
263
|
+
errno: -101,
|
|
264
|
+
code: 'ENETUNREACH',
|
|
265
|
+
syscall: 'connect',
|
|
266
|
+
address: '::1',
|
|
267
|
+
port: 8545,
|
|
268
|
+
constructor: 'Function<Error>',
|
|
269
|
+
name: 'Error',
|
|
270
|
+
toString: 'Function<toString>'
|
|
271
|
+
}
|
|
272
|
+
],
|
|
273
|
+
code: 'ECONNREFUSED',
|
|
274
|
+
constructor: 'Function<AggregateError>',
|
|
275
|
+
name: 'Caused by: AggregateError',
|
|
276
|
+
message: '',
|
|
277
|
+
toString: 'Function<toString>',
|
|
278
|
+
stacks: []
|
|
279
|
+
}
|
|
280
|
+
[31m[2m⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[22m[39m
|
|
281
|
+
[31m[1mSerialized Error:[22m[39m [90m{ errors: [ { stack: 'Error: connect ECONNREFUSED 127.0.0.1:8545\n at createConnectionError (node:net:1678:14)\n at afterConnectMultiple (node:net:1708:16)', message: 'connect ECONNREFUSED 127.0.0.1:8545', errno: -111, code: 'ECONNREFUSED', syscall: 'connect', address: '127.0.0.1', port: 8545, constructor: 'Function<Error>', name: 'Error', toString: 'Function<toString>' }, { stack: 'Error: connect ENETUNREACH ::1:8545 - Local (:::0)\n at internalConnectMultiple (node:net:1206:16)\n at afterConnectMultiple (node:net:1715:7)', message: 'connect ENETUNREACH ::1:8545 - Local (:::0)', errno: -101, code: 'ENETUNREACH', syscall: 'connect', address: '::1', port: 8545, constructor: 'Function<Error>', name: 'Error', toString: 'Function<toString>' } ], code: 'ECONNREFUSED' }[39m
|
|
282
|
+
[31m[2m⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/89]⎯[22m[39m
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
[2m Test Files [22m [1m[31m2 failed[39m[22m[2m | [22m[1m[32m14 passed[39m[22m[90m (16)[39m
|
|
286
|
+
[2m Tests [22m [1m[31m89 failed[39m[22m[2m | [22m[1m[32m293 passed[39m[22m[90m (382)[39m
|
|
287
|
+
[2m Start at [22m 12:35:18
|
|
288
|
+
[2m Duration [22m 1.36s[2m (transform 3.62s, setup 0ms, import 12.03s, tests 651ms, environment 2ms)[22m
|
|
289
|
+
|
|
290
|
+
ELIFECYCLE Test failed. See above for more details.
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# @0xsequence/wallet-core
|
|
2
2
|
|
|
3
|
+
## 3.0.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Network and session fixes
|
|
8
|
+
- Updated dependencies
|
|
9
|
+
- @0xsequence/guard@3.0.1
|
|
10
|
+
- @0xsequence/relayer@3.0.1
|
|
11
|
+
- @0xsequence/wallet-primitives@3.0.1
|
|
12
|
+
|
|
3
13
|
## 3.0.0
|
|
4
14
|
|
|
5
15
|
### Patch Changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"explicit.d.ts","sourceRoot":"","sources":["../../../src/signers/session/explicit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAA;AAC/G,OAAO,EAA8B,OAAO,EAAe,GAAG,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAA;AACpF,OAAO,EAAiB,OAAO,EAAE,MAAM,gBAAgB,CAAA;AACvD,OAAO,EAAE,qBAAqB,
|
|
1
|
+
{"version":3,"file":"explicit.d.ts","sourceRoot":"","sources":["../../../src/signers/session/explicit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAA;AAC/G,OAAO,EAA8B,OAAO,EAAe,GAAG,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAA;AACpF,OAAO,EAAiB,OAAO,EAAE,MAAM,gBAAgB,CAAA;AACvD,OAAO,EAAE,qBAAqB,EAAmB,qBAAqB,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAExG,MAAM,MAAM,cAAc,GAAG,IAAI,CAAC,UAAU,CAAC,kBAAkB,EAAE,QAAQ,CAAC,CAAA;AAI1E,qBAAa,QAAS,YAAW,qBAAqB;IACpD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IAErC,SAAgB,OAAO,EAAE,OAAO,CAAC,OAAO,CAAA;IACxC,SAAgB,kBAAkB,EAAE,UAAU,CAAC,kBAAkB,CAAA;gBAErD,UAAU,EAAE,GAAG,CAAC,GAAG,GAAG,OAAO,EAAE,kBAAkB,EAAE,cAAc;IAS7E,OAAO,CAAC,eAAe,EAAE,aAAa,CAAC,gBAAgB,EAAE,OAAO,EAAE,MAAM,GAAG,qBAAqB;IA+C1F,uBAAuB,CAC3B,MAAM,EAAE,OAAO,CAAC,OAAO,EACvB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,OAAO,CAAC,IAAI,EAClB,qBAAqB,EAAE,OAAO,CAAC,OAAO,EACtC,QAAQ,CAAC,EAAE,QAAQ,CAAC,QAAQ,GAC3B,OAAO,CAAC,UAAU,CAAC,UAAU,GAAG,SAAS,CAAC;IAmC7C,OAAO,CAAC,sBAAsB;IAmB9B,OAAO,CAAC,iBAAiB;IAYnB,kBAAkB,CACtB,UAAU,EAAE,UAAU,CAAC,UAAU,EACjC,IAAI,EAAE,OAAO,CAAC,IAAI,EAClB,MAAM,EAAE,OAAO,CAAC,OAAO,EACvB,qBAAqB,EAAE,OAAO,CAAC,OAAO,EACtC,QAAQ,CAAC,EAAE,QAAQ,CAAC,QAAQ,GAC3B,OAAO,CAAC,OAAO,CAAC;IAsDb,aAAa,CACjB,MAAM,EAAE,OAAO,CAAC,OAAO,EACvB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,OAAO,CAAC,IAAI,EAClB,qBAAqB,EAAE,OAAO,CAAC,OAAO,EACtC,QAAQ,CAAC,EAAE,QAAQ,CAAC,QAAQ,GAC3B,OAAO,CAAC,OAAO,CAAC;IAab,QAAQ,CACZ,MAAM,EAAE,OAAO,CAAC,OAAO,EACvB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,OAAO,CAAC,KAAK,EACtB,OAAO,EAAE,MAAM,EACf,qBAAqB,EAAE,OAAO,CAAC,OAAO,EACtC,QAAQ,CAAC,EAAE,QAAQ,CAAC,QAAQ,GAC3B,OAAO,CAAC,gBAAgB,CAAC,oBAAoB,CAAC;YA6BnC,qBAAqB;IAwB7B,iBAAiB,CACrB,MAAM,EAAE,OAAO,CAAC,OAAO,EACvB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,OAAO,CAAC,IAAI,EAAE,EACrB,qBAAqB,EAAE,OAAO,CAAC,OAAO,EACtC,QAAQ,EAAE,QAAQ,CAAC,QAAQ,GAC1B,OAAO,CAAC,UAAU,EAAE,CAAC;CA8EzB"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Constants, Permission, SessionConfig, SessionSignature } from '@0xsequence/wallet-primitives';
|
|
2
2
|
import { AbiFunction, AbiParameters, Address, Bytes, Hash, Hex } from 'ox';
|
|
3
3
|
import { MemoryPkStore } from '../pk/index.js';
|
|
4
|
+
import { isIncrementCall } from './session.js';
|
|
4
5
|
const VALUE_TRACKING_ADDRESS = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE';
|
|
5
6
|
export class Explicit {
|
|
6
7
|
_privateKey;
|
|
@@ -143,9 +144,7 @@ export class Explicit {
|
|
|
143
144
|
return true;
|
|
144
145
|
}
|
|
145
146
|
async supportedCall(wallet, chainId, call, sessionManagerAddress, provider) {
|
|
146
|
-
if (
|
|
147
|
-
Hex.size(call.data) > 4 &&
|
|
148
|
-
Hex.isEqual(Hex.slice(call.data, 0, 4), AbiFunction.getSelector(Constants.INCREMENT_USAGE_LIMIT))) {
|
|
147
|
+
if (isIncrementCall(call, sessionManagerAddress)) {
|
|
149
148
|
// Can sign increment usage calls
|
|
150
149
|
return true;
|
|
151
150
|
}
|
|
@@ -158,9 +157,7 @@ export class Explicit {
|
|
|
158
157
|
async signCall(wallet, chainId, payload, callIdx, sessionManagerAddress, provider) {
|
|
159
158
|
const call = payload.calls[callIdx];
|
|
160
159
|
let permissionIndex;
|
|
161
|
-
if (
|
|
162
|
-
Hex.size(call.data) > 4 &&
|
|
163
|
-
Hex.isEqual(Hex.slice(call.data, 0, 4), AbiFunction.getSelector(Constants.INCREMENT_USAGE_LIMIT))) {
|
|
160
|
+
if (isIncrementCall(call, sessionManagerAddress)) {
|
|
164
161
|
// Permission check not required. Use the first permission
|
|
165
162
|
permissionIndex = 0;
|
|
166
163
|
}
|
|
@@ -23,4 +23,5 @@ export interface ImplicitSessionSigner extends SessionSigner {
|
|
|
23
23
|
}
|
|
24
24
|
export declare function isExplicitSessionSigner(signer: SessionSigner): signer is ExplicitSessionSigner;
|
|
25
25
|
export declare function isImplicitSessionSigner(signer: SessionSigner): signer is ImplicitSessionSigner;
|
|
26
|
+
export declare function isIncrementCall(call: Payload.Call, sessionManagerAddress: Address.Address): boolean;
|
|
26
27
|
//# sourceMappingURL=session.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/signers/session/session.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/signers/session/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAA;AACnG,OAAO,EAAe,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAA;AAExD,MAAM,MAAM,0BAA0B,GAClC,SAAS,GACT,mBAAmB,GACnB,sBAAsB,GACtB,qBAAqB,GACrB,0BAA0B,GAC1B,2BAA2B,GAC3B,0BAA0B,GAC1B,aAAa,CAAA;AAEjB,MAAM,MAAM,qBAAqB,GAAG;IAClC,OAAO,EAAE,OAAO,CAAA;IAChB,aAAa,CAAC,EAAE,0BAA0B,CAAA;CAC3C,CAAA;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;IAGnD,OAAO,EAAE,CAAC,eAAe,EAAE,aAAa,CAAC,gBAAgB,EAAE,OAAO,EAAE,MAAM,KAAK,qBAAqB,CAAA;IAGpG,aAAa,EAAE,CACb,MAAM,EAAE,OAAO,CAAC,OAAO,EACvB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,OAAO,CAAC,IAAI,EAClB,qBAAqB,EAAE,OAAO,CAAC,OAAO,EACtC,QAAQ,CAAC,EAAE,QAAQ,CAAC,QAAQ,KACzB,OAAO,CAAC,OAAO,CAAC,CAAA;IAGrB,QAAQ,EAAE,CACR,MAAM,EAAE,OAAO,CAAC,OAAO,EACvB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,OAAO,CAAC,KAAK,EACtB,OAAO,EAAE,MAAM,EACf,qBAAqB,EAAE,OAAO,CAAC,OAAO,EACtC,QAAQ,CAAC,EAAE,QAAQ,CAAC,QAAQ,KACzB,OAAO,CAAC,gBAAgB,CAAC,oBAAoB,CAAC,CAAA;CACpD;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,SAAS,EAAE,GAAG,CAAC,GAAG,CAAA;IAClB,WAAW,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,MAAM,WAAW,qBAAsB,SAAQ,aAAa;IAC1D,iBAAiB,EAAE,CACjB,MAAM,EAAE,OAAO,CAAC,OAAO,EACvB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,OAAO,CAAC,IAAI,EAAE,EACrB,qBAAqB,EAAE,OAAO,CAAC,OAAO,EACtC,QAAQ,EAAE,QAAQ,CAAC,QAAQ,KACxB,OAAO,CAAC,UAAU,EAAE,CAAC,CAAA;CAC3B;AAED,MAAM,WAAW,qBAAsB,SAAQ,aAAa;IAC1D,cAAc,EAAE,OAAO,CAAC,OAAO,CAAA;CAChC;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,IAAI,qBAAqB,CAE9F;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,IAAI,qBAAqB,CAE9F;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,qBAAqB,EAAE,OAAO,CAAC,OAAO,GAAG,OAAO,CAMnG"}
|
|
@@ -1,6 +1,13 @@
|
|
|
1
|
+
import { Constants } from '@0xsequence/wallet-primitives';
|
|
2
|
+
import { AbiFunction, Address, Hex } from 'ox';
|
|
1
3
|
export function isExplicitSessionSigner(signer) {
|
|
2
4
|
return 'prepareIncrements' in signer;
|
|
3
5
|
}
|
|
4
6
|
export function isImplicitSessionSigner(signer) {
|
|
5
7
|
return 'identitySigner' in signer;
|
|
6
8
|
}
|
|
9
|
+
export function isIncrementCall(call, sessionManagerAddress) {
|
|
10
|
+
return (Address.isEqual(call.to, sessionManagerAddress) &&
|
|
11
|
+
Hex.size(call.data) >= 4 &&
|
|
12
|
+
Hex.isEqual(Hex.slice(call.data, 0, 4), AbiFunction.getSelector(Constants.INCREMENT_USAGE_LIMIT)));
|
|
13
|
+
}
|
|
@@ -31,6 +31,10 @@ export declare class SessionManager implements SapientSigner {
|
|
|
31
31
|
isValid: boolean;
|
|
32
32
|
invalidReason?: SessionSignerInvalidReason;
|
|
33
33
|
}[]>;
|
|
34
|
+
/**
|
|
35
|
+
* Find one signer per call from the given candidate list (first that supports each call).
|
|
36
|
+
*/
|
|
37
|
+
private findSignersForCallsWithCandidates;
|
|
34
38
|
findSignersForCalls(wallet: Address.Address, chainId: number, calls: Payload.Call[]): Promise<SessionSigner[]>;
|
|
35
39
|
prepareIncrement(wallet: Address.Address, chainId: number, calls: Payload.Call[]): Promise<Payload.Call | null>;
|
|
36
40
|
signSapient(wallet: Address.Address, chainId: number, payload: Payload.Parented, imageHash: Hex.Hex): Promise<SignatureTypes.SignatureOfSapientSignerLeaf>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-manager.d.ts","sourceRoot":"","sources":["../../src/signers/session-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,OAAO,EACP,aAAa,EAEb,SAAS,IAAI,cAAc,EAC5B,MAAM,+BAA+B,CAAA;AACtC,OAAO,EAAe,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAA;AACxD,OAAO,KAAK,KAAK,MAAM,mBAAmB,CAAA;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAC1C,OAAO,EACL,QAAQ,EACR,QAAQ,EAER,aAAa,EACb,0BAA0B,
|
|
1
|
+
{"version":3,"file":"session-manager.d.ts","sourceRoot":"","sources":["../../src/signers/session-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,OAAO,EACP,aAAa,EAEb,SAAS,IAAI,cAAc,EAC5B,MAAM,+BAA+B,CAAA;AACtC,OAAO,EAAe,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAA;AACxD,OAAO,KAAK,KAAK,MAAM,mBAAmB,CAAA;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAC1C,OAAO,EACL,QAAQ,EACR,QAAQ,EAER,aAAa,EACb,0BAA0B,EAI3B,MAAM,oBAAoB,CAAA;AAE3B,MAAM,MAAM,qBAAqB,GAAG;IAClC,qBAAqB,EAAE,OAAO,CAAC,OAAO,CAAA;IACtC,aAAa,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAA;IAC9B,eAAe,CAAC,EAAE,QAAQ,EAAE,CAAA;IAC5B,eAAe,CAAC,EAAE,QAAQ,EAAE,CAAA;IAC5B,QAAQ,CAAC,EAAE,QAAQ,CAAC,QAAQ,CAAA;CAC7B,CAAA;AAID,qBAAa,cAAe,YAAW,aAAa;IAShD,QAAQ,CAAC,MAAM,EAAE,MAAM;IARzB,SAAgB,aAAa,EAAE,KAAK,CAAC,QAAQ,CAAA;IAC7C,SAAgB,OAAO,EAAE,OAAO,CAAC,OAAO,CAAA;IAExC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAY;IAC7C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAY;IAC7C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAmB;gBAGnC,MAAM,EAAE,MAAM,EACvB,OAAO,EAAE,qBAAqB;IAShC,IAAI,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,SAAS,CAAC,CAE5C;IAEK,YAAY,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,SAAS,CAAC;IASlD,IAAI,QAAQ,IAAI,OAAO,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAEtD;IAEK,WAAW,IAAI,OAAO,CAAC,aAAa,CAAC,gBAAgB,CAAC;IAY5D,YAAY,CAAC,QAAQ,EAAE,QAAQ,CAAC,QAAQ,GAAG,cAAc;IAUzD,kBAAkB,CAAC,MAAM,EAAE,QAAQ,GAAG,cAAc;IAWpD,kBAAkB,CAAC,MAAM,EAAE,QAAQ,GAAG,cAAc;IAY9C,kBAAkB,CACtB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC;QAAE,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC;QAAC,OAAO,EAAE,OAAO,CAAC;QAAC,aAAa,CAAC,EAAE,0BAA0B,CAAA;KAAE,EAAE,CAAC;IAgBvG;;OAEG;YACW,iCAAiC;IAyCzC,mBAAmB,CAAC,MAAM,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,IAAI,EAAE,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IA4D9G,gBAAgB,CACpB,MAAM,EAAE,OAAO,CAAC,OAAO,EACvB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,OAAO,CAAC,IAAI,EAAE,GACpB,OAAO,CAAC,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAsDzB,WAAW,CACf,MAAM,EAAE,OAAO,CAAC,OAAO,EACvB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,OAAO,CAAC,QAAQ,EACzB,SAAS,EAAE,GAAG,CAAC,GAAG,GACjB,OAAO,CAAC,cAAc,CAAC,4BAA4B,CAAC;IAgHjD,uBAAuB,CAC3B,MAAM,EAAE,OAAO,CAAC,OAAO,EACvB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,OAAO,CAAC,QAAQ,EACzB,SAAS,EAAE,cAAc,CAAC,4BAA4B,GACrD,OAAO,CAAC,OAAO,CAAC;CAsCpB"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Config, Constants, Extensions, Payload, SessionConfig, SessionSignature, } from '@0xsequence/wallet-primitives';
|
|
2
2
|
import { AbiFunction, Address, Hex } from 'ox';
|
|
3
|
-
import { isExplicitSessionSigner, isImplicitSessionSigner, } from './session/index.js';
|
|
3
|
+
import { isExplicitSessionSigner, isImplicitSessionSigner, isIncrementCall, } from './session/index.js';
|
|
4
4
|
const MAX_SPACE = 2n ** 80n - 1n;
|
|
5
5
|
export class SessionManager {
|
|
6
6
|
wallet;
|
|
@@ -86,19 +86,10 @@ export class SessionManager {
|
|
|
86
86
|
invalidReason,
|
|
87
87
|
}));
|
|
88
88
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
if (identitySigners.length === 0) {
|
|
94
|
-
throw new Error('Identity signers not found');
|
|
95
|
-
}
|
|
96
|
-
// Prioritize implicit signers
|
|
97
|
-
const availableSigners = [...this._implicitSigners, ...this._explicitSigners];
|
|
98
|
-
if (availableSigners.length === 0) {
|
|
99
|
-
throw new Error('No signers match the topology');
|
|
100
|
-
}
|
|
101
|
-
// Find supported signers for each call
|
|
89
|
+
/**
|
|
90
|
+
* Find one signer per call from the given candidate list (first that supports each call).
|
|
91
|
+
*/
|
|
92
|
+
async findSignersForCallsWithCandidates(wallet, chainId, calls, topology, availableSigners) {
|
|
102
93
|
const signers = [];
|
|
103
94
|
for (const call of calls) {
|
|
104
95
|
let supported = false;
|
|
@@ -128,7 +119,56 @@ export class SessionManager {
|
|
|
128
119
|
if (expiredSupportedSigner) {
|
|
129
120
|
throw new Error(`Signer supporting call is expired: ${expiredSupportedSigner.address}`);
|
|
130
121
|
}
|
|
131
|
-
throw new Error(`No signer supported for call.
|
|
122
|
+
throw new Error(`No signer supported for call. Call: to=${call.to}, data=${call.data}, value=${call.value}, `);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return signers;
|
|
126
|
+
}
|
|
127
|
+
async findSignersForCalls(wallet, chainId, calls) {
|
|
128
|
+
const topology = await this.topology;
|
|
129
|
+
const identitySigners = SessionConfig.getIdentitySigners(topology);
|
|
130
|
+
if (identitySigners.length === 0) {
|
|
131
|
+
throw new Error('Identity signers not found');
|
|
132
|
+
}
|
|
133
|
+
const availableSigners = [...this._implicitSigners, ...this._explicitSigners];
|
|
134
|
+
if (availableSigners.length === 0) {
|
|
135
|
+
throw new Error('No signers match the topology');
|
|
136
|
+
}
|
|
137
|
+
const nonIncrementCalls = [];
|
|
138
|
+
const incrementCalls = [];
|
|
139
|
+
for (const call of calls) {
|
|
140
|
+
if (isIncrementCall(call, this.address)) {
|
|
141
|
+
incrementCalls.push(call);
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
nonIncrementCalls.push(call);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
// Find signers for non-increment calls
|
|
148
|
+
const nonIncrementSigners = nonIncrementCalls.length > 0
|
|
149
|
+
? await this.findSignersForCallsWithCandidates(wallet, chainId, nonIncrementCalls, topology, availableSigners)
|
|
150
|
+
: [];
|
|
151
|
+
let incrementSigners = [];
|
|
152
|
+
if (incrementCalls.length > 0) {
|
|
153
|
+
// Find signers for increment calls, preferring signers that signed non-increment calls
|
|
154
|
+
const incrementCandidates = [
|
|
155
|
+
...nonIncrementSigners,
|
|
156
|
+
...availableSigners.filter((s) => !nonIncrementSigners.includes(s)),
|
|
157
|
+
];
|
|
158
|
+
incrementSigners = await this.findSignersForCallsWithCandidates(wallet, chainId, incrementCalls, topology, incrementCandidates);
|
|
159
|
+
}
|
|
160
|
+
// Merge back in original call order
|
|
161
|
+
const signers = [];
|
|
162
|
+
let nonIncrementIndex = 0;
|
|
163
|
+
let incrementIndex = 0;
|
|
164
|
+
for (const call of calls) {
|
|
165
|
+
if (isIncrementCall(call, this.address)) {
|
|
166
|
+
signers.push(incrementSigners[incrementIndex]);
|
|
167
|
+
incrementIndex++;
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
signers.push(nonIncrementSigners[nonIncrementIndex]);
|
|
171
|
+
nonIncrementIndex++;
|
|
132
172
|
}
|
|
133
173
|
}
|
|
134
174
|
return signers;
|
|
@@ -138,17 +178,20 @@ export class SessionManager {
|
|
|
138
178
|
throw new Error('No calls provided');
|
|
139
179
|
}
|
|
140
180
|
const signers = await this.findSignersForCalls(wallet, chainId, calls);
|
|
141
|
-
//
|
|
142
|
-
const
|
|
181
|
+
// Map each signer to only their non-increment calls
|
|
182
|
+
const signerToNonIncrementCalls = new Map();
|
|
143
183
|
signers.forEach((signer, index) => {
|
|
144
184
|
const call = calls[index];
|
|
145
|
-
|
|
146
|
-
|
|
185
|
+
if (isIncrementCall(call, this.address)) {
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
const existing = signerToNonIncrementCalls.get(signer) || [];
|
|
189
|
+
signerToNonIncrementCalls.set(signer, [...existing, call]);
|
|
147
190
|
});
|
|
148
|
-
// Prepare increments for each explicit signer
|
|
149
|
-
const increments = (await Promise.all(Array.from(
|
|
191
|
+
// Prepare increments for each explicit signer from their non-increment calls only
|
|
192
|
+
const increments = (await Promise.all(Array.from(signerToNonIncrementCalls.entries()).map(async ([signer, nonIncrementCalls]) => {
|
|
150
193
|
if (isExplicitSessionSigner(signer)) {
|
|
151
|
-
return signer.prepareIncrements(wallet, chainId,
|
|
194
|
+
return signer.prepareIncrements(wallet, chainId, nonIncrementCalls, this.address, this._provider);
|
|
152
195
|
}
|
|
153
196
|
return [];
|
|
154
197
|
}))).flat();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@0xsequence/wallet-core",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.1",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|
|
@@ -27,9 +27,9 @@
|
|
|
27
27
|
"mipd": "^0.0.7",
|
|
28
28
|
"ox": "^0.9.17",
|
|
29
29
|
"viem": "^2.40.3",
|
|
30
|
-
"@0xsequence/
|
|
31
|
-
"@0xsequence/wallet-primitives": "^3.0.
|
|
32
|
-
"@0xsequence/
|
|
30
|
+
"@0xsequence/relayer": "^3.0.1",
|
|
31
|
+
"@0xsequence/wallet-primitives": "^3.0.1",
|
|
32
|
+
"@0xsequence/guard": "^3.0.1"
|
|
33
33
|
},
|
|
34
34
|
"scripts": {
|
|
35
35
|
"build": "tsc",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Constants, Payload, Permission, SessionConfig, SessionSignature } from '@0xsequence/wallet-primitives'
|
|
2
2
|
import { AbiFunction, AbiParameters, Address, Bytes, Hash, Hex, Provider } from 'ox'
|
|
3
3
|
import { MemoryPkStore, PkStore } from '../pk/index.js'
|
|
4
|
-
import { ExplicitSessionSigner, SessionSignerValidity, UsageLimit } from './session.js'
|
|
4
|
+
import { ExplicitSessionSigner, isIncrementCall, SessionSignerValidity, UsageLimit } from './session.js'
|
|
5
5
|
|
|
6
6
|
export type ExplicitParams = Omit<Permission.SessionPermissions, 'signer'>
|
|
7
7
|
|
|
@@ -208,11 +208,7 @@ export class Explicit implements ExplicitSessionSigner {
|
|
|
208
208
|
sessionManagerAddress: Address.Address,
|
|
209
209
|
provider?: Provider.Provider,
|
|
210
210
|
): Promise<boolean> {
|
|
211
|
-
if (
|
|
212
|
-
Address.isEqual(call.to, sessionManagerAddress) &&
|
|
213
|
-
Hex.size(call.data) > 4 &&
|
|
214
|
-
Hex.isEqual(Hex.slice(call.data, 0, 4), AbiFunction.getSelector(Constants.INCREMENT_USAGE_LIMIT))
|
|
215
|
-
) {
|
|
211
|
+
if (isIncrementCall(call, sessionManagerAddress)) {
|
|
216
212
|
// Can sign increment usage calls
|
|
217
213
|
return true
|
|
218
214
|
}
|
|
@@ -234,11 +230,7 @@ export class Explicit implements ExplicitSessionSigner {
|
|
|
234
230
|
): Promise<SessionSignature.SessionCallSignature> {
|
|
235
231
|
const call = payload.calls[callIdx]!
|
|
236
232
|
let permissionIndex: number
|
|
237
|
-
if (
|
|
238
|
-
Address.isEqual(call.to, sessionManagerAddress) &&
|
|
239
|
-
Hex.size(call.data) > 4 &&
|
|
240
|
-
Hex.isEqual(Hex.slice(call.data, 0, 4), AbiFunction.getSelector(Constants.INCREMENT_USAGE_LIMIT))
|
|
241
|
-
) {
|
|
233
|
+
if (isIncrementCall(call, sessionManagerAddress)) {
|
|
242
234
|
// Permission check not required. Use the first permission
|
|
243
235
|
permissionIndex = 0
|
|
244
236
|
} else {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Payload, SessionConfig, SessionSignature } from '@0xsequence/wallet-primitives'
|
|
2
|
-
import { Address, Hex, Provider } from 'ox'
|
|
1
|
+
import { Constants, Payload, SessionConfig, SessionSignature } from '@0xsequence/wallet-primitives'
|
|
2
|
+
import { AbiFunction, Address, Hex, Provider } from 'ox'
|
|
3
3
|
|
|
4
4
|
export type SessionSignerInvalidReason =
|
|
5
5
|
| 'Expired'
|
|
@@ -68,3 +68,11 @@ export function isExplicitSessionSigner(signer: SessionSigner): signer is Explic
|
|
|
68
68
|
export function isImplicitSessionSigner(signer: SessionSigner): signer is ImplicitSessionSigner {
|
|
69
69
|
return 'identitySigner' in signer
|
|
70
70
|
}
|
|
71
|
+
|
|
72
|
+
export function isIncrementCall(call: Payload.Call, sessionManagerAddress: Address.Address): boolean {
|
|
73
|
+
return (
|
|
74
|
+
Address.isEqual(call.to, sessionManagerAddress) &&
|
|
75
|
+
Hex.size(call.data) >= 4 &&
|
|
76
|
+
Hex.isEqual(Hex.slice(call.data, 0, 4), AbiFunction.getSelector(Constants.INCREMENT_USAGE_LIMIT))
|
|
77
|
+
)
|
|
78
|
+
}
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
SessionSigner,
|
|
19
19
|
SessionSignerInvalidReason,
|
|
20
20
|
isImplicitSessionSigner,
|
|
21
|
+
isIncrementCall,
|
|
21
22
|
UsageLimit,
|
|
22
23
|
} from './session/index.js'
|
|
23
24
|
|
|
@@ -130,21 +131,16 @@ export class SessionManager implements SapientSigner {
|
|
|
130
131
|
}))
|
|
131
132
|
}
|
|
132
133
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
if (availableSigners.length === 0) {
|
|
144
|
-
throw new Error('No signers match the topology')
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
// Find supported signers for each call
|
|
134
|
+
/**
|
|
135
|
+
* Find one signer per call from the given candidate list (first that supports each call).
|
|
136
|
+
*/
|
|
137
|
+
private async findSignersForCallsWithCandidates(
|
|
138
|
+
wallet: Address.Address,
|
|
139
|
+
chainId: number,
|
|
140
|
+
calls: Payload.Call[],
|
|
141
|
+
topology: SessionConfig.SessionsTopology,
|
|
142
|
+
availableSigners: SessionSigner[],
|
|
143
|
+
): Promise<SessionSigner[]> {
|
|
148
144
|
const signers: SessionSigner[] = []
|
|
149
145
|
for (const call of calls) {
|
|
150
146
|
let supported = false
|
|
@@ -173,9 +169,67 @@ export class SessionManager implements SapientSigner {
|
|
|
173
169
|
if (expiredSupportedSigner) {
|
|
174
170
|
throw new Error(`Signer supporting call is expired: ${expiredSupportedSigner.address}`)
|
|
175
171
|
}
|
|
176
|
-
throw new Error(
|
|
177
|
-
|
|
178
|
-
|
|
172
|
+
throw new Error(`No signer supported for call. Call: to=${call.to}, data=${call.data}, value=${call.value}, `)
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return signers
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
async findSignersForCalls(wallet: Address.Address, chainId: number, calls: Payload.Call[]): Promise<SessionSigner[]> {
|
|
179
|
+
const topology = await this.topology
|
|
180
|
+
const identitySigners = SessionConfig.getIdentitySigners(topology)
|
|
181
|
+
if (identitySigners.length === 0) {
|
|
182
|
+
throw new Error('Identity signers not found')
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
const availableSigners = [...this._implicitSigners, ...this._explicitSigners]
|
|
186
|
+
if (availableSigners.length === 0) {
|
|
187
|
+
throw new Error('No signers match the topology')
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const nonIncrementCalls: Payload.Call[] = []
|
|
191
|
+
const incrementCalls: Payload.Call[] = []
|
|
192
|
+
for (const call of calls) {
|
|
193
|
+
if (isIncrementCall(call, this.address)) {
|
|
194
|
+
incrementCalls.push(call)
|
|
195
|
+
} else {
|
|
196
|
+
nonIncrementCalls.push(call)
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Find signers for non-increment calls
|
|
201
|
+
const nonIncrementSigners =
|
|
202
|
+
nonIncrementCalls.length > 0
|
|
203
|
+
? await this.findSignersForCallsWithCandidates(wallet, chainId, nonIncrementCalls, topology, availableSigners)
|
|
204
|
+
: []
|
|
205
|
+
|
|
206
|
+
let incrementSigners: SessionSigner[] = []
|
|
207
|
+
if (incrementCalls.length > 0) {
|
|
208
|
+
// Find signers for increment calls, preferring signers that signed non-increment calls
|
|
209
|
+
const incrementCandidates = [
|
|
210
|
+
...nonIncrementSigners,
|
|
211
|
+
...availableSigners.filter((s) => !nonIncrementSigners.includes(s)),
|
|
212
|
+
]
|
|
213
|
+
incrementSigners = await this.findSignersForCallsWithCandidates(
|
|
214
|
+
wallet,
|
|
215
|
+
chainId,
|
|
216
|
+
incrementCalls,
|
|
217
|
+
topology,
|
|
218
|
+
incrementCandidates,
|
|
219
|
+
)
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// Merge back in original call order
|
|
223
|
+
const signers: SessionSigner[] = []
|
|
224
|
+
let nonIncrementIndex = 0
|
|
225
|
+
let incrementIndex = 0
|
|
226
|
+
for (const call of calls) {
|
|
227
|
+
if (isIncrementCall(call, this.address)) {
|
|
228
|
+
signers.push(incrementSigners[incrementIndex]!)
|
|
229
|
+
incrementIndex++
|
|
230
|
+
} else {
|
|
231
|
+
signers.push(nonIncrementSigners[nonIncrementIndex]!)
|
|
232
|
+
nonIncrementIndex++
|
|
179
233
|
}
|
|
180
234
|
}
|
|
181
235
|
return signers
|
|
@@ -191,20 +245,23 @@ export class SessionManager implements SapientSigner {
|
|
|
191
245
|
}
|
|
192
246
|
const signers = await this.findSignersForCalls(wallet, chainId, calls)
|
|
193
247
|
|
|
194
|
-
//
|
|
195
|
-
const
|
|
248
|
+
// Map each signer to only their non-increment calls
|
|
249
|
+
const signerToNonIncrementCalls = new Map<SessionSigner, Payload.Call[]>()
|
|
196
250
|
signers.forEach((signer, index) => {
|
|
197
251
|
const call = calls[index]!
|
|
198
|
-
|
|
199
|
-
|
|
252
|
+
if (isIncrementCall(call, this.address)) {
|
|
253
|
+
return
|
|
254
|
+
}
|
|
255
|
+
const existing = signerToNonIncrementCalls.get(signer) || []
|
|
256
|
+
signerToNonIncrementCalls.set(signer, [...existing, call])
|
|
200
257
|
})
|
|
201
258
|
|
|
202
|
-
// Prepare increments for each explicit signer
|
|
259
|
+
// Prepare increments for each explicit signer from their non-increment calls only
|
|
203
260
|
const increments: UsageLimit[] = (
|
|
204
261
|
await Promise.all(
|
|
205
|
-
Array.from(
|
|
262
|
+
Array.from(signerToNonIncrementCalls.entries()).map(async ([signer, nonIncrementCalls]) => {
|
|
206
263
|
if (isExplicitSessionSigner(signer)) {
|
|
207
|
-
return signer.prepareIncrements(wallet, chainId,
|
|
264
|
+
return signer.prepareIncrements(wallet, chainId, nonIncrementCalls, this.address, this._provider!)
|
|
208
265
|
}
|
|
209
266
|
return []
|
|
210
267
|
}),
|
package/test/constants.ts
CHANGED
|
@@ -5,6 +5,8 @@ import { Abi, AbiEvent, Address } from 'ox'
|
|
|
5
5
|
const envFile = process.env.CI ? '.env.test' : '.env.test.local'
|
|
6
6
|
dotenvConfig({ path: envFile })
|
|
7
7
|
|
|
8
|
+
// Contracts are deployed on Arbitrum
|
|
9
|
+
|
|
8
10
|
// Requires https://example.com redirectUrl
|
|
9
11
|
export const EMITTER_ADDRESS1: Address.Address = '0xad90eB52BC180Bd9f66f50981E196f3E996278D3'
|
|
10
12
|
// Requires https://another-example.com redirectUrl
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Extensions } from '@0xsequence/wallet-primitives'
|
|
1
|
+
import { Constants, Extensions } from '@0xsequence/wallet-primitives'
|
|
2
2
|
import { AbiEvent, AbiFunction, Address, Bytes, Hex, Provider, RpcTransport, Secp256k1 } from 'ox'
|
|
3
3
|
import { describe, expect, it } from 'vitest'
|
|
4
4
|
import { Attestation, GenericTree, Payload, Permission, SessionConfig } from '../../primitives/src/index.js'
|
|
@@ -731,7 +731,7 @@ for (const extension of ALL_EXTENSIONS) {
|
|
|
731
731
|
)
|
|
732
732
|
|
|
733
733
|
it(
|
|
734
|
-
'signs a payload using an explicit session',
|
|
734
|
+
'signs a payload using an explicit session with allowAll and value limit',
|
|
735
735
|
async () => {
|
|
736
736
|
const provider = Provider.from(RpcTransport.fromHttp(LOCAL_RPC_URL))
|
|
737
737
|
const chainId = Number(await provider.request({ method: 'eth_chainId' }))
|
|
@@ -804,7 +804,7 @@ for (const extension of ALL_EXTENSIONS) {
|
|
|
804
804
|
)
|
|
805
805
|
|
|
806
806
|
it(
|
|
807
|
-
'signs
|
|
807
|
+
'signs using explicit session with onlyOnce, consumes usage and rejects second call',
|
|
808
808
|
async () => {
|
|
809
809
|
const provider = Provider.from(RpcTransport.fromHttp(LOCAL_RPC_URL))
|
|
810
810
|
const chainId = Number(await provider.request({ method: 'eth_chainId' }))
|
|
@@ -1357,5 +1357,347 @@ for (const extension of ALL_EXTENSIONS) {
|
|
|
1357
1357
|
},
|
|
1358
1358
|
timeout,
|
|
1359
1359
|
)
|
|
1360
|
+
|
|
1361
|
+
it(
|
|
1362
|
+
'two explicit sessions with same value limit: exhaust first then second send uses second session (increment from non-increment calls only)',
|
|
1363
|
+
async () => {
|
|
1364
|
+
const provider = Provider.from(RpcTransport.fromHttp(LOCAL_RPC_URL))
|
|
1365
|
+
const chainId = Number(await provider.request({ method: 'eth_chainId' }))
|
|
1366
|
+
|
|
1367
|
+
const identityPrivateKey = Secp256k1.randomPrivateKey()
|
|
1368
|
+
const identityAddress = Address.fromPublicKey(Secp256k1.getPublicKey({ privateKey: identityPrivateKey }))
|
|
1369
|
+
const stateProvider = new State.Local.Provider()
|
|
1370
|
+
|
|
1371
|
+
const targetAddress = randomAddress()
|
|
1372
|
+
const valueLimit = 500000000000000000n // 0.5 ETH per session
|
|
1373
|
+
|
|
1374
|
+
const sessionPermission: ExplicitSessionConfig = {
|
|
1375
|
+
chainId,
|
|
1376
|
+
valueLimit,
|
|
1377
|
+
deadline: BigInt(Math.floor(Date.now() / 1000) + 3600),
|
|
1378
|
+
permissions: [PermissionBuilder.for(targetAddress).allowAll().build()],
|
|
1379
|
+
}
|
|
1380
|
+
|
|
1381
|
+
const explicitPrivateKey1 = Secp256k1.randomPrivateKey()
|
|
1382
|
+
const explicitSigner1 = new Signers.Session.Explicit(explicitPrivateKey1, {
|
|
1383
|
+
...sessionPermission,
|
|
1384
|
+
})
|
|
1385
|
+
|
|
1386
|
+
const explicitPrivateKey2 = Secp256k1.randomPrivateKey()
|
|
1387
|
+
const explicitSigner2 = new Signers.Session.Explicit(explicitPrivateKey2, {
|
|
1388
|
+
...sessionPermission,
|
|
1389
|
+
})
|
|
1390
|
+
|
|
1391
|
+
let sessionTopology = SessionConfig.addExplicitSession(SessionConfig.emptySessionsTopology(identityAddress), {
|
|
1392
|
+
...sessionPermission,
|
|
1393
|
+
signer: explicitSigner1.address,
|
|
1394
|
+
})
|
|
1395
|
+
sessionTopology = SessionConfig.addExplicitSession(sessionTopology, {
|
|
1396
|
+
...sessionPermission,
|
|
1397
|
+
signer: explicitSigner2.address,
|
|
1398
|
+
})
|
|
1399
|
+
await stateProvider.saveTree(SessionConfig.sessionsTopologyToConfigurationTree(sessionTopology))
|
|
1400
|
+
const imageHash = GenericTree.hash(SessionConfig.sessionsTopologyToConfigurationTree(sessionTopology))
|
|
1401
|
+
|
|
1402
|
+
const wallet = await Wallet.fromConfiguration(
|
|
1403
|
+
{
|
|
1404
|
+
threshold: 1n,
|
|
1405
|
+
checkpoint: 0n,
|
|
1406
|
+
topology: [{ type: 'sapient-signer', address: extension.sessions, weight: 1n, imageHash }, Hex.random(32)],
|
|
1407
|
+
},
|
|
1408
|
+
{ stateProvider },
|
|
1409
|
+
)
|
|
1410
|
+
// Fund wallet with 2 ETH so we can send 0.5 ETH twice (each tx needs value + gas)
|
|
1411
|
+
await provider.request({
|
|
1412
|
+
method: 'anvil_setBalance',
|
|
1413
|
+
params: [wallet.address, Hex.fromNumber(2n * 1000000000000000000n)],
|
|
1414
|
+
})
|
|
1415
|
+
|
|
1416
|
+
const sessionManager = new Signers.SessionManager(wallet, {
|
|
1417
|
+
provider,
|
|
1418
|
+
sessionManagerAddress: extension.sessions,
|
|
1419
|
+
explicitSigners: [explicitSigner1, explicitSigner2],
|
|
1420
|
+
})
|
|
1421
|
+
|
|
1422
|
+
const call: Payload.Call = {
|
|
1423
|
+
to: targetAddress,
|
|
1424
|
+
value: valueLimit, // one full limit
|
|
1425
|
+
data: '0x' as Hex.Hex,
|
|
1426
|
+
gasLimit: 0n,
|
|
1427
|
+
delegateCall: false,
|
|
1428
|
+
onlyFallback: false,
|
|
1429
|
+
behaviorOnError: 'revert',
|
|
1430
|
+
}
|
|
1431
|
+
|
|
1432
|
+
// First send: uses first session (exhausts it)
|
|
1433
|
+
const increment1 = await sessionManager.prepareIncrement(wallet.address, chainId, [call])
|
|
1434
|
+
expect(increment1).not.toBeNull()
|
|
1435
|
+
const calls1 = includeIncrement([call], increment1!, extension.sessions)
|
|
1436
|
+
const tx1 = await buildAndSignCall(wallet, sessionManager, calls1, provider, chainId)
|
|
1437
|
+
await simulateTransaction(provider, tx1)
|
|
1438
|
+
|
|
1439
|
+
// Second send: same call. First session is exhausted so findSignersForCalls picks second session.
|
|
1440
|
+
// Payload is [call, increment] (or [increment, call]). signSapient must derive expectedIncrement
|
|
1441
|
+
// from non-increment calls only so it matches the increment we built for the second session.
|
|
1442
|
+
const increment2 = await sessionManager.prepareIncrement(wallet.address, chainId, [call])
|
|
1443
|
+
expect(increment2).not.toBeNull()
|
|
1444
|
+
const calls2 = includeIncrement([call], increment2!, extension.sessions)
|
|
1445
|
+
const tx2 = await buildAndSignCall(wallet, sessionManager, calls2, provider, chainId)
|
|
1446
|
+
await simulateTransaction(provider, tx2)
|
|
1447
|
+
},
|
|
1448
|
+
timeout,
|
|
1449
|
+
)
|
|
1450
|
+
|
|
1451
|
+
describe('increment built from non-increment calls only', () => {
|
|
1452
|
+
it(
|
|
1453
|
+
'prepareIncrement returns null when calls contain only an increment call (no non-increment calls)',
|
|
1454
|
+
async () => {
|
|
1455
|
+
const provider = Provider.from(RpcTransport.fromHttp(LOCAL_RPC_URL))
|
|
1456
|
+
const chainId = Number(await provider.request({ method: 'eth_chainId' }))
|
|
1457
|
+
|
|
1458
|
+
const identityPrivateKey = Secp256k1.randomPrivateKey()
|
|
1459
|
+
const identityAddress = Address.fromPublicKey(Secp256k1.getPublicKey({ privateKey: identityPrivateKey }))
|
|
1460
|
+
const stateProvider = new State.Local.Provider()
|
|
1461
|
+
|
|
1462
|
+
const sessionPermission: ExplicitSessionConfig = {
|
|
1463
|
+
chainId,
|
|
1464
|
+
valueLimit: 0n,
|
|
1465
|
+
deadline: BigInt(Math.floor(Date.now() / 1000) + 3600),
|
|
1466
|
+
permissions: [PermissionBuilder.for(EMITTER_ADDRESS1).allowAll().build()],
|
|
1467
|
+
}
|
|
1468
|
+
const explicitSigner = new Signers.Session.Explicit(Secp256k1.randomPrivateKey(), sessionPermission)
|
|
1469
|
+
const sessionTopology = SessionConfig.addExplicitSession(
|
|
1470
|
+
SessionConfig.emptySessionsTopology(identityAddress),
|
|
1471
|
+
{
|
|
1472
|
+
...sessionPermission,
|
|
1473
|
+
signer: explicitSigner.address,
|
|
1474
|
+
},
|
|
1475
|
+
)
|
|
1476
|
+
await stateProvider.saveTree(SessionConfig.sessionsTopologyToConfigurationTree(sessionTopology))
|
|
1477
|
+
const imageHash = GenericTree.hash(SessionConfig.sessionsTopologyToConfigurationTree(sessionTopology))
|
|
1478
|
+
|
|
1479
|
+
const wallet = await Wallet.fromConfiguration(
|
|
1480
|
+
{
|
|
1481
|
+
threshold: 1n,
|
|
1482
|
+
checkpoint: 0n,
|
|
1483
|
+
topology: [
|
|
1484
|
+
{ type: 'sapient-signer', address: extension.sessions, weight: 1n, imageHash },
|
|
1485
|
+
Hex.random(32),
|
|
1486
|
+
],
|
|
1487
|
+
},
|
|
1488
|
+
{ stateProvider },
|
|
1489
|
+
)
|
|
1490
|
+
const sessionManager = new Signers.SessionManager(wallet, {
|
|
1491
|
+
provider,
|
|
1492
|
+
sessionManagerAddress: extension.sessions,
|
|
1493
|
+
explicitSigners: [explicitSigner],
|
|
1494
|
+
})
|
|
1495
|
+
|
|
1496
|
+
// Only an increment call (no non-increment calls). Contract would reject payload with only self-call; we return null.
|
|
1497
|
+
const incrementOnlyCall: Payload.Call = {
|
|
1498
|
+
to: extension.sessions,
|
|
1499
|
+
data: AbiFunction.encodeData(Constants.INCREMENT_USAGE_LIMIT, [[]]),
|
|
1500
|
+
value: 0n,
|
|
1501
|
+
gasLimit: 0n,
|
|
1502
|
+
delegateCall: false,
|
|
1503
|
+
onlyFallback: false,
|
|
1504
|
+
behaviorOnError: 'revert',
|
|
1505
|
+
}
|
|
1506
|
+
const result = await sessionManager.prepareIncrement(wallet.address, chainId, [incrementOnlyCall])
|
|
1507
|
+
expect(result).toBeNull()
|
|
1508
|
+
},
|
|
1509
|
+
timeout,
|
|
1510
|
+
)
|
|
1511
|
+
|
|
1512
|
+
it(
|
|
1513
|
+
'prepareIncrement([increment, nonIncrementCall]) produces same increment data as prepareIncrement([nonIncrementCall])',
|
|
1514
|
+
async () => {
|
|
1515
|
+
const provider = Provider.from(RpcTransport.fromHttp(LOCAL_RPC_URL))
|
|
1516
|
+
const chainId = Number(await provider.request({ method: 'eth_chainId' }))
|
|
1517
|
+
|
|
1518
|
+
const identityPrivateKey = Secp256k1.randomPrivateKey()
|
|
1519
|
+
const identityAddress = Address.fromPublicKey(Secp256k1.getPublicKey({ privateKey: identityPrivateKey }))
|
|
1520
|
+
const stateProvider = new State.Local.Provider()
|
|
1521
|
+
|
|
1522
|
+
const sessionPermission: ExplicitSessionConfig = {
|
|
1523
|
+
chainId,
|
|
1524
|
+
valueLimit: 0n,
|
|
1525
|
+
deadline: BigInt(Math.floor(Date.now() / 1000) + 3600),
|
|
1526
|
+
permissions: [PermissionBuilder.for(EMITTER_ADDRESS1).forFunction(EMITTER_FUNCTIONS[0]).onlyOnce().build()],
|
|
1527
|
+
}
|
|
1528
|
+
const explicitSigner = new Signers.Session.Explicit(Secp256k1.randomPrivateKey(), sessionPermission)
|
|
1529
|
+
const sessionTopology = SessionConfig.addExplicitSession(
|
|
1530
|
+
SessionConfig.emptySessionsTopology(identityAddress),
|
|
1531
|
+
{
|
|
1532
|
+
...sessionPermission,
|
|
1533
|
+
signer: explicitSigner.address,
|
|
1534
|
+
},
|
|
1535
|
+
)
|
|
1536
|
+
await stateProvider.saveTree(SessionConfig.sessionsTopologyToConfigurationTree(sessionTopology))
|
|
1537
|
+
const imageHash = GenericTree.hash(SessionConfig.sessionsTopologyToConfigurationTree(sessionTopology))
|
|
1538
|
+
|
|
1539
|
+
const wallet = await Wallet.fromConfiguration(
|
|
1540
|
+
{
|
|
1541
|
+
threshold: 1n,
|
|
1542
|
+
checkpoint: 0n,
|
|
1543
|
+
topology: [
|
|
1544
|
+
{ type: 'sapient-signer', address: extension.sessions, weight: 1n, imageHash },
|
|
1545
|
+
Hex.random(32),
|
|
1546
|
+
],
|
|
1547
|
+
},
|
|
1548
|
+
{ stateProvider },
|
|
1549
|
+
)
|
|
1550
|
+
const sessionManager = new Signers.SessionManager(wallet, {
|
|
1551
|
+
provider,
|
|
1552
|
+
sessionManagerAddress: extension.sessions,
|
|
1553
|
+
explicitSigners: [explicitSigner],
|
|
1554
|
+
})
|
|
1555
|
+
|
|
1556
|
+
const nonIncrementCall: Payload.Call = {
|
|
1557
|
+
to: EMITTER_ADDRESS1,
|
|
1558
|
+
value: 0n,
|
|
1559
|
+
data: AbiFunction.encodeData(EMITTER_FUNCTIONS[0]),
|
|
1560
|
+
gasLimit: 0n,
|
|
1561
|
+
delegateCall: false,
|
|
1562
|
+
onlyFallback: false,
|
|
1563
|
+
behaviorOnError: 'revert',
|
|
1564
|
+
}
|
|
1565
|
+
|
|
1566
|
+
const fromNonIncrementOnly = await sessionManager.prepareIncrement(wallet.address, chainId, [
|
|
1567
|
+
nonIncrementCall,
|
|
1568
|
+
])
|
|
1569
|
+
expect(fromNonIncrementOnly).not.toBeNull()
|
|
1570
|
+
|
|
1571
|
+
// Pass [staleIncrement, nonIncrementCall] — increment is ignored when building; result should match
|
|
1572
|
+
const withStaleIncrement = await sessionManager.prepareIncrement(wallet.address, chainId, [
|
|
1573
|
+
fromNonIncrementOnly!,
|
|
1574
|
+
nonIncrementCall,
|
|
1575
|
+
])
|
|
1576
|
+
expect(withStaleIncrement).not.toBeNull()
|
|
1577
|
+
expect(withStaleIncrement!.data).toEqual(fromNonIncrementOnly!.data)
|
|
1578
|
+
},
|
|
1579
|
+
timeout,
|
|
1580
|
+
)
|
|
1581
|
+
|
|
1582
|
+
it(
|
|
1583
|
+
'payload with implicit and explicit: increment built only from explicit non-increment call',
|
|
1584
|
+
async () => {
|
|
1585
|
+
const provider = Provider.from(RpcTransport.fromHttp(LOCAL_RPC_URL))
|
|
1586
|
+
const chainId = Number(await provider.request({ method: 'eth_chainId' }))
|
|
1587
|
+
|
|
1588
|
+
const identityPrivateKey = Secp256k1.randomPrivateKey()
|
|
1589
|
+
const identityAddress = Address.fromPublicKey(Secp256k1.getPublicKey({ privateKey: identityPrivateKey }))
|
|
1590
|
+
const stateProvider = new State.Local.Provider()
|
|
1591
|
+
|
|
1592
|
+
const redirectUrl = 'https://example.com'
|
|
1593
|
+
const implicitSigner = await createImplicitSigner(redirectUrl, identityPrivateKey)
|
|
1594
|
+
const sessionPermission: ExplicitSessionConfig = {
|
|
1595
|
+
chainId,
|
|
1596
|
+
valueLimit: 0n,
|
|
1597
|
+
deadline: BigInt(Math.floor(Date.now() / 1000) + 3600),
|
|
1598
|
+
permissions: [PermissionBuilder.for(EMITTER_ADDRESS1).forFunction(EMITTER_FUNCTIONS[0]).onlyOnce().build()],
|
|
1599
|
+
}
|
|
1600
|
+
const explicitSigner = new Signers.Session.Explicit(Secp256k1.randomPrivateKey(), sessionPermission)
|
|
1601
|
+
|
|
1602
|
+
// Topology: identity + blacklist (implicit) + explicit session
|
|
1603
|
+
let sessionTopology = SessionConfig.emptySessionsTopology(identityAddress)
|
|
1604
|
+
sessionTopology = SessionConfig.addExplicitSession(sessionTopology, {
|
|
1605
|
+
...sessionPermission,
|
|
1606
|
+
signer: explicitSigner.address,
|
|
1607
|
+
})
|
|
1608
|
+
await stateProvider.saveTree(SessionConfig.sessionsTopologyToConfigurationTree(sessionTopology))
|
|
1609
|
+
const imageHash = GenericTree.hash(SessionConfig.sessionsTopologyToConfigurationTree(sessionTopology))
|
|
1610
|
+
|
|
1611
|
+
const wallet = await Wallet.fromConfiguration(
|
|
1612
|
+
{
|
|
1613
|
+
threshold: 1n,
|
|
1614
|
+
checkpoint: 0n,
|
|
1615
|
+
topology: [
|
|
1616
|
+
{ type: 'sapient-signer', address: extension.sessions, weight: 1n, imageHash },
|
|
1617
|
+
Hex.random(32),
|
|
1618
|
+
],
|
|
1619
|
+
},
|
|
1620
|
+
{ stateProvider },
|
|
1621
|
+
)
|
|
1622
|
+
const sessionManager = new Signers.SessionManager(wallet, {
|
|
1623
|
+
provider,
|
|
1624
|
+
sessionManagerAddress: extension.sessions,
|
|
1625
|
+
implicitSigners: [implicitSigner],
|
|
1626
|
+
explicitSigners: [explicitSigner],
|
|
1627
|
+
})
|
|
1628
|
+
|
|
1629
|
+
// Explicit call only (onlyOnce produces an increment; implicit does not match this target)
|
|
1630
|
+
const call: Payload.Call = {
|
|
1631
|
+
to: EMITTER_ADDRESS1,
|
|
1632
|
+
value: 0n,
|
|
1633
|
+
data: AbiFunction.encodeData(EMITTER_FUNCTIONS[0]),
|
|
1634
|
+
gasLimit: 0n,
|
|
1635
|
+
delegateCall: false,
|
|
1636
|
+
onlyFallback: false,
|
|
1637
|
+
behaviorOnError: 'revert',
|
|
1638
|
+
}
|
|
1639
|
+
const increment = await sessionManager.prepareIncrement(wallet.address, chainId, [call])
|
|
1640
|
+
expect(increment).not.toBeNull()
|
|
1641
|
+
const calls = includeIncrement([call], increment!, extension.sessions)
|
|
1642
|
+
const transaction = await buildAndSignCall(wallet, sessionManager, calls, provider, chainId)
|
|
1643
|
+
await simulateTransaction(provider, transaction, EMITTER_EVENT_TOPICS[0])
|
|
1644
|
+
},
|
|
1645
|
+
timeout,
|
|
1646
|
+
)
|
|
1647
|
+
|
|
1648
|
+
it('signSapient handles selector-only self increment call consistently', async () => {
|
|
1649
|
+
const identityPrivateKey = Secp256k1.randomPrivateKey()
|
|
1650
|
+
const identityAddress = Address.fromPublicKey(Secp256k1.getPublicKey({ privateKey: identityPrivateKey }))
|
|
1651
|
+
const stateProvider = new State.Local.Provider()
|
|
1652
|
+
|
|
1653
|
+
const explicitSigner = new Signers.Session.Explicit(Secp256k1.randomPrivateKey(), {
|
|
1654
|
+
chainId: 0,
|
|
1655
|
+
valueLimit: 0n,
|
|
1656
|
+
deadline: BigInt(Math.floor(Date.now() / 1000) + 3600),
|
|
1657
|
+
permissions: [PermissionBuilder.for(EMITTER_ADDRESS1).allowAll().build()],
|
|
1658
|
+
})
|
|
1659
|
+
|
|
1660
|
+
const sessionTopology = SessionConfig.addExplicitSession(SessionConfig.emptySessionsTopology(identityAddress), {
|
|
1661
|
+
...explicitSigner.sessionPermissions,
|
|
1662
|
+
signer: explicitSigner.address,
|
|
1663
|
+
})
|
|
1664
|
+
await stateProvider.saveTree(SessionConfig.sessionsTopologyToConfigurationTree(sessionTopology))
|
|
1665
|
+
const imageHash = GenericTree.hash(SessionConfig.sessionsTopologyToConfigurationTree(sessionTopology))
|
|
1666
|
+
|
|
1667
|
+
const wallet = await Wallet.fromConfiguration(
|
|
1668
|
+
{
|
|
1669
|
+
threshold: 1n,
|
|
1670
|
+
checkpoint: 0n,
|
|
1671
|
+
topology: [{ type: 'sapient-signer', address: extension.sessions, weight: 1n, imageHash }, Hex.random(32)],
|
|
1672
|
+
},
|
|
1673
|
+
{ stateProvider },
|
|
1674
|
+
)
|
|
1675
|
+
const sessionManager = new Signers.SessionManager(wallet, {
|
|
1676
|
+
sessionManagerAddress: extension.sessions,
|
|
1677
|
+
explicitSigners: [explicitSigner],
|
|
1678
|
+
})
|
|
1679
|
+
|
|
1680
|
+
const payload: Payload.Parented = {
|
|
1681
|
+
type: 'call',
|
|
1682
|
+
nonce: 0n,
|
|
1683
|
+
space: 0n,
|
|
1684
|
+
calls: [
|
|
1685
|
+
{
|
|
1686
|
+
to: extension.sessions,
|
|
1687
|
+
data: AbiFunction.getSelector(Constants.INCREMENT_USAGE_LIMIT),
|
|
1688
|
+
value: 0n,
|
|
1689
|
+
gasLimit: 0n,
|
|
1690
|
+
delegateCall: false,
|
|
1691
|
+
onlyFallback: false,
|
|
1692
|
+
behaviorOnError: 'revert',
|
|
1693
|
+
},
|
|
1694
|
+
],
|
|
1695
|
+
parentWallets: [wallet.address],
|
|
1696
|
+
}
|
|
1697
|
+
|
|
1698
|
+
const signature = await sessionManager.signSapient(wallet.address, 0, payload, imageHash)
|
|
1699
|
+
expect(signature.type).toBe('sapient')
|
|
1700
|
+
})
|
|
1701
|
+
})
|
|
1360
1702
|
})
|
|
1361
1703
|
}
|