@charterlabs/rhinestone-sdk 0.1.0 → 0.1.2

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 (194) hide show
  1. package/README.md +74 -181
  2. package/dist/src/accounts/error.d.ts +69 -0
  3. package/dist/src/accounts/error.d.ts.map +1 -0
  4. package/dist/src/accounts/error.js +109 -0
  5. package/dist/{accounts → src/accounts}/index.d.ts +14 -21
  6. package/dist/src/accounts/index.d.ts.map +1 -0
  7. package/dist/src/accounts/index.js +469 -0
  8. package/dist/src/accounts/index.test.d.ts +2 -0
  9. package/dist/src/accounts/index.test.d.ts.map +1 -0
  10. package/dist/src/accounts/index.test.js +36 -0
  11. package/dist/{accounts → src/accounts}/kernel.d.ts +7 -9
  12. package/dist/src/accounts/kernel.d.ts.map +1 -0
  13. package/dist/{accounts → src/accounts}/kernel.js +0 -8
  14. package/dist/src/accounts/kernel.test.d.ts +2 -0
  15. package/dist/src/accounts/kernel.test.d.ts.map +1 -0
  16. package/dist/src/accounts/kernel.test.js +105 -0
  17. package/dist/{accounts → src/accounts}/nexus.d.ts +14 -13
  18. package/dist/src/accounts/nexus.d.ts.map +1 -0
  19. package/dist/{accounts → src/accounts}/nexus.js +92 -88
  20. package/dist/src/accounts/nexus.test.d.ts +2 -0
  21. package/dist/src/accounts/nexus.test.d.ts.map +1 -0
  22. package/dist/src/accounts/nexus.test.js +87 -0
  23. package/dist/{accounts → src/accounts}/safe.d.ts +4 -6
  24. package/dist/src/accounts/safe.d.ts.map +1 -0
  25. package/dist/{accounts → src/accounts}/safe.js +20 -29
  26. package/dist/src/accounts/safe.test.d.ts +2 -0
  27. package/dist/src/accounts/safe.test.d.ts.map +1 -0
  28. package/dist/src/accounts/safe.test.js +87 -0
  29. package/dist/src/accounts/startale.d.ts +20 -0
  30. package/dist/src/accounts/startale.d.ts.map +1 -0
  31. package/dist/src/accounts/startale.js +100 -0
  32. package/dist/src/accounts/startale.test.d.ts +2 -0
  33. package/dist/src/accounts/startale.test.d.ts.map +1 -0
  34. package/dist/src/accounts/startale.test.js +99 -0
  35. package/dist/{accounts → src/accounts}/utils.d.ts +4 -3
  36. package/dist/src/accounts/utils.d.ts.map +1 -0
  37. package/dist/{accounts → src/accounts}/utils.js +44 -0
  38. package/dist/src/accounts/utils.test.d.ts +2 -0
  39. package/dist/src/accounts/utils.test.d.ts.map +1 -0
  40. package/dist/src/accounts/utils.test.js +49 -0
  41. package/dist/src/actions/index.d.ts +39 -0
  42. package/dist/src/actions/index.d.ts.map +1 -0
  43. package/dist/{actions → src/actions}/index.js +108 -15
  44. package/dist/src/actions/index.test.d.ts +2 -0
  45. package/dist/src/actions/index.test.d.ts.map +1 -0
  46. package/dist/src/actions/index.test.js +302 -0
  47. package/dist/{actions → src/actions}/smart-session.d.ts +2 -2
  48. package/dist/src/actions/smart-session.d.ts.map +1 -0
  49. package/dist/src/execution/compact.d.ts +8 -0
  50. package/dist/src/execution/compact.d.ts.map +1 -0
  51. package/dist/src/execution/compact.js +105 -0
  52. package/dist/src/execution/error.d.ts +54 -0
  53. package/dist/src/execution/error.d.ts.map +1 -0
  54. package/dist/src/execution/error.js +78 -0
  55. package/dist/{execution → src/execution}/index.d.ts +7 -6
  56. package/dist/src/execution/index.d.ts.map +1 -0
  57. package/dist/src/execution/index.js +150 -0
  58. package/dist/src/execution/smart-session.d.ts +15 -0
  59. package/dist/src/execution/smart-session.d.ts.map +1 -0
  60. package/dist/{execution → src/execution}/smart-session.js +16 -77
  61. package/dist/src/execution/smart-session.test.d.ts +2 -0
  62. package/dist/src/execution/smart-session.test.d.ts.map +1 -0
  63. package/dist/src/execution/smart-session.test.js +34 -0
  64. package/dist/src/execution/utils.d.ts +45 -0
  65. package/dist/src/execution/utils.d.ts.map +1 -0
  66. package/dist/src/execution/utils.js +433 -0
  67. package/dist/src/index.d.ts +41 -0
  68. package/dist/src/index.d.ts.map +1 -0
  69. package/dist/src/index.js +154 -0
  70. package/dist/src/modules/abi/smart-sessions.d.ts.map +1 -0
  71. package/dist/src/modules/common.d.ts.map +1 -0
  72. package/dist/{modules → src/modules}/index.d.ts +3 -11
  73. package/dist/src/modules/index.d.ts.map +1 -0
  74. package/dist/{modules → src/modules}/index.js +3 -45
  75. package/dist/src/modules/index.test.d.ts +2 -0
  76. package/dist/src/modules/index.test.d.ts.map +1 -0
  77. package/dist/src/modules/index.test.js +107 -0
  78. package/dist/src/modules/omni-account.d.ts +7 -0
  79. package/dist/src/modules/omni-account.d.ts.map +1 -0
  80. package/dist/src/modules/omni-account.js +11 -0
  81. package/dist/src/modules/read.d.ts +9 -0
  82. package/dist/src/modules/read.d.ts.map +1 -0
  83. package/dist/{modules → src/modules}/read.js +6 -37
  84. package/dist/{modules → src/modules}/validators/core.d.ts +6 -7
  85. package/dist/src/modules/validators/core.d.ts.map +1 -0
  86. package/dist/{modules → src/modules}/validators/core.js +83 -8
  87. package/dist/src/modules/validators/core.test.d.ts +2 -0
  88. package/dist/src/modules/validators/core.test.d.ts.map +1 -0
  89. package/dist/src/modules/validators/core.test.js +108 -0
  90. package/dist/src/modules/validators/index.d.ts +4 -0
  91. package/dist/src/modules/validators/index.d.ts.map +1 -0
  92. package/dist/{modules → src/modules}/validators/index.js +1 -3
  93. package/dist/{modules → src/modules}/validators/smart-sessions.d.ts +4 -15
  94. package/dist/src/modules/validators/smart-sessions.d.ts.map +1 -0
  95. package/dist/{modules → src/modules}/validators/smart-sessions.js +7 -61
  96. package/dist/src/modules/validators/smart-sessions.test.d.ts +2 -0
  97. package/dist/src/modules/validators/smart-sessions.test.d.ts.map +1 -0
  98. package/dist/src/modules/validators/smart-sessions.test.js +226 -0
  99. package/dist/src/orchestrator/client.d.ts +21 -0
  100. package/dist/src/orchestrator/client.d.ts.map +1 -0
  101. package/dist/src/orchestrator/client.js +284 -0
  102. package/dist/src/orchestrator/consts.d.ts +5 -0
  103. package/dist/src/orchestrator/consts.d.ts.map +1 -0
  104. package/dist/src/orchestrator/consts.js +9 -0
  105. package/dist/src/orchestrator/error.d.ts +96 -0
  106. package/dist/src/orchestrator/error.d.ts.map +1 -0
  107. package/dist/src/orchestrator/error.js +132 -0
  108. package/dist/src/orchestrator/index.d.ts +11 -0
  109. package/dist/src/orchestrator/index.d.ts.map +1 -0
  110. package/dist/src/orchestrator/index.js +42 -0
  111. package/dist/src/orchestrator/registry.d.ts +39 -0
  112. package/dist/src/orchestrator/registry.d.ts.map +1 -0
  113. package/dist/src/orchestrator/registry.js +121 -0
  114. package/dist/src/orchestrator/registry.json +365 -0
  115. package/dist/src/orchestrator/registry.test.d.ts +2 -0
  116. package/dist/src/orchestrator/registry.test.d.ts.map +1 -0
  117. package/dist/src/orchestrator/registry.test.js +137 -0
  118. package/dist/src/orchestrator/types.d.ts +275 -0
  119. package/dist/src/orchestrator/types.d.ts.map +1 -0
  120. package/dist/src/orchestrator/types.js +19 -0
  121. package/dist/src/orchestrator/utils.d.ts +5 -0
  122. package/dist/src/orchestrator/utils.d.ts.map +1 -0
  123. package/dist/src/orchestrator/utils.js +126 -0
  124. package/dist/{types.d.ts → src/types.d.ts} +42 -21
  125. package/dist/src/types.d.ts.map +1 -0
  126. package/dist/test/consts.d.ts +10 -0
  127. package/dist/test/consts.d.ts.map +1 -0
  128. package/dist/test/consts.js +22 -0
  129. package/package.json +11 -20
  130. package/dist/accounts/index.d.ts.map +0 -1
  131. package/dist/accounts/index.js +0 -419
  132. package/dist/accounts/kernel.d.ts.map +0 -1
  133. package/dist/accounts/nexus.d.ts.map +0 -1
  134. package/dist/accounts/safe.d.ts.map +0 -1
  135. package/dist/accounts/utils.d.ts.map +0 -1
  136. package/dist/actions/index.d.ts +0 -29
  137. package/dist/actions/index.d.ts.map +0 -1
  138. package/dist/actions/registry.d.ts +0 -7
  139. package/dist/actions/registry.d.ts.map +0 -1
  140. package/dist/actions/registry.js +0 -7
  141. package/dist/actions/smart-session.d.ts.map +0 -1
  142. package/dist/execution/index.d.ts.map +0 -1
  143. package/dist/execution/index.js +0 -149
  144. package/dist/execution/smart-session.d.ts +0 -23
  145. package/dist/execution/smart-session.d.ts.map +0 -1
  146. package/dist/execution/utils.d.ts +0 -68
  147. package/dist/execution/utils.d.ts.map +0 -1
  148. package/dist/execution/utils.js +0 -482
  149. package/dist/index.d.ts +0 -38
  150. package/dist/index.d.ts.map +0 -1
  151. package/dist/index.js +0 -119
  152. package/dist/modules/abi/smart-sessions.d.ts.map +0 -1
  153. package/dist/modules/common.d.ts.map +0 -1
  154. package/dist/modules/index.d.ts.map +0 -1
  155. package/dist/modules/omni-account.d.ts +0 -9
  156. package/dist/modules/omni-account.d.ts.map +0 -1
  157. package/dist/modules/omni-account.js +0 -15
  158. package/dist/modules/read.d.ts +0 -10
  159. package/dist/modules/read.d.ts.map +0 -1
  160. package/dist/modules/registry.d.ts +0 -9
  161. package/dist/modules/registry.d.ts.map +0 -1
  162. package/dist/modules/registry.js +0 -60
  163. package/dist/modules/validators/core.d.ts.map +0 -1
  164. package/dist/modules/validators/index.d.ts +0 -4
  165. package/dist/modules/validators/index.d.ts.map +0 -1
  166. package/dist/modules/validators/smart-sessions.d.ts.map +0 -1
  167. package/dist/orchestrator/client.d.ts +0 -29
  168. package/dist/orchestrator/client.d.ts.map +0 -1
  169. package/dist/orchestrator/client.js +0 -250
  170. package/dist/orchestrator/consts.d.ts +0 -5
  171. package/dist/orchestrator/consts.d.ts.map +0 -1
  172. package/dist/orchestrator/consts.js +0 -9
  173. package/dist/orchestrator/error.d.ts +0 -18
  174. package/dist/orchestrator/error.d.ts.map +0 -1
  175. package/dist/orchestrator/error.js +0 -33
  176. package/dist/orchestrator/index.d.ts +0 -11
  177. package/dist/orchestrator/index.d.ts.map +0 -1
  178. package/dist/orchestrator/index.js +0 -40
  179. package/dist/orchestrator/registry.d.ts +0 -20
  180. package/dist/orchestrator/registry.d.ts.map +0 -1
  181. package/dist/orchestrator/registry.js +0 -444
  182. package/dist/orchestrator/types.d.ts +0 -242
  183. package/dist/orchestrator/types.d.ts.map +0 -1
  184. package/dist/orchestrator/types.js +0 -19
  185. package/dist/orchestrator/utils.d.ts +0 -29
  186. package/dist/orchestrator/utils.d.ts.map +0 -1
  187. package/dist/orchestrator/utils.js +0 -319
  188. package/dist/types.d.ts.map +0 -1
  189. /package/dist/{actions → src/actions}/smart-session.js +0 -0
  190. /package/dist/{modules → src/modules}/abi/smart-sessions.d.ts +0 -0
  191. /package/dist/{modules → src/modules}/abi/smart-sessions.js +0 -0
  192. /package/dist/{modules → src/modules}/common.d.ts +0 -0
  193. /package/dist/{modules → src/modules}/common.js +0 -0
  194. /package/dist/{types.js → src/types.js} +0 -0
@@ -0,0 +1,226 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const viem_1 = require("viem");
4
+ const chains_1 = require("viem/chains");
5
+ const vitest_1 = require("vitest");
6
+ const consts_1 = require("../../../test/consts");
7
+ const smart_sessions_1 = require("../abi/smart-sessions");
8
+ const common_1 = require("../common");
9
+ const smart_sessions_2 = require("./smart-sessions");
10
+ (0, vitest_1.describe)('Smart Sessions', () => {
11
+ (0, vitest_1.describe)('Permission ID', () => {
12
+ (0, vitest_1.test)('default', () => {
13
+ (0, vitest_1.expect)((0, smart_sessions_2.getPermissionId)({
14
+ owners: {
15
+ type: 'ecdsa',
16
+ accounts: [consts_1.accountA, consts_1.accountB],
17
+ },
18
+ })).toBe('0x4ad46f8661acf29090a7635877ff94953e0ea05b0583d32de3839acc49739182');
19
+ });
20
+ (0, vitest_1.test)('with salt', () => {
21
+ (0, vitest_1.expect)((0, smart_sessions_2.getPermissionId)({
22
+ owners: {
23
+ type: 'ecdsa',
24
+ accounts: [consts_1.accountA, consts_1.accountB],
25
+ },
26
+ salt: '0x97340e1cfff3319c76ef22b2bc9d3231071d550125d68c9d4a8972823f166320',
27
+ })).toBe('0xb1adc169088099c6830120c63cde8d2c7e1b9a82857b35c0527dc2e37ce3e7bd');
28
+ });
29
+ });
30
+ (0, vitest_1.describe)('Smart Session Validator', () => {
31
+ (0, vitest_1.test)('no session', () => {
32
+ (0, vitest_1.expect)((0, smart_sessions_2.getSmartSessionValidator)({
33
+ owners: {
34
+ type: 'ecdsa',
35
+ accounts: [consts_1.accountA],
36
+ },
37
+ rhinestoneApiKey: consts_1.MOCK_API_KEY,
38
+ })).toBeNull();
39
+ });
40
+ (0, vitest_1.test)('empty session list', () => {
41
+ (0, vitest_1.expect)((0, smart_sessions_2.getSmartSessionValidator)({
42
+ owners: {
43
+ type: 'ecdsa',
44
+ accounts: [consts_1.accountA],
45
+ },
46
+ rhinestoneApiKey: consts_1.MOCK_API_KEY,
47
+ sessions: [],
48
+ })).not.toBeNull();
49
+ });
50
+ (0, vitest_1.test)('single session', () => {
51
+ const validator = (0, smart_sessions_2.getSmartSessionValidator)({
52
+ owners: {
53
+ type: 'ecdsa',
54
+ accounts: [consts_1.accountA],
55
+ },
56
+ rhinestoneApiKey: consts_1.MOCK_API_KEY,
57
+ sessions: [
58
+ {
59
+ owners: {
60
+ type: 'ecdsa',
61
+ accounts: [consts_1.accountA],
62
+ },
63
+ },
64
+ ],
65
+ });
66
+ (0, vitest_1.expect)(validator).not.toBeNull();
67
+ (0, vitest_1.expect)(validator?.type).toEqual(common_1.MODULE_TYPE_ID_VALIDATOR);
68
+ (0, vitest_1.expect)(validator && (0, viem_1.isAddress)(validator.address)).toEqual(true);
69
+ });
70
+ });
71
+ (0, vitest_1.describe)('Enable Session Call', () => {
72
+ vitest_1.vi.mock('viem', async (importOriginal) => {
73
+ const actual = await importOriginal();
74
+ return {
75
+ // @ts-ignore
76
+ ...actual,
77
+ createPublicClient: vitest_1.vi.fn().mockReturnValue({
78
+ readContract: vitest_1.vi.fn(),
79
+ }),
80
+ };
81
+ });
82
+ const client = viem_1.createPublicClient;
83
+ client.mockImplementation((_) => {
84
+ return {
85
+ readContract: (params) => {
86
+ if (params.functionName === 'DOMAIN_SEPARATOR') {
87
+ return '0xf5f6dfa751763cc5278cba45d03ea9797c1660b2cb7f5ffd188fa3e8523abdca';
88
+ }
89
+ throw new Error('Unknown function call');
90
+ },
91
+ };
92
+ });
93
+ const TARGET = '0x063DFbDb1610EC7BbfA1fFBE603Ac5aA1B67a935';
94
+ const SELECTOR = '0x12345678';
95
+ const FALLBACK_TARGET = '0x0000000000000000000000000000000000000001';
96
+ const FALLBACK_SELECTOR = '0x00000001';
97
+ (0, vitest_1.test)('default', async () => {
98
+ const call = await (0, smart_sessions_2.getEnableSessionCall)(chains_1.mainnet, {
99
+ owners: {
100
+ type: 'ecdsa',
101
+ accounts: [consts_1.accountA],
102
+ },
103
+ });
104
+ const sessionData = toSessionData(call);
105
+ // Should have a fallback action
106
+ (0, vitest_1.expect)(sessionData.actions.some((action) => action.actionTarget === FALLBACK_TARGET &&
107
+ action.actionTargetSelector === FALLBACK_SELECTOR)).toEqual(true);
108
+ });
109
+ (0, vitest_1.test)('with action', async () => {
110
+ const call = await (0, smart_sessions_2.getEnableSessionCall)(chains_1.mainnet, {
111
+ owners: {
112
+ type: 'ecdsa',
113
+ accounts: [consts_1.accountA],
114
+ },
115
+ actions: [
116
+ {
117
+ target: TARGET,
118
+ selector: SELECTOR,
119
+ },
120
+ ],
121
+ });
122
+ const sessionData = toSessionData(call);
123
+ // Should have the action
124
+ (0, vitest_1.expect)(sessionData.actions.some((action) => action.actionTarget === TARGET &&
125
+ action.actionTargetSelector === SELECTOR)).toEqual(true);
126
+ // Should not have the fallback action
127
+ (0, vitest_1.expect)(sessionData.actions.some((action) => action.actionTarget === FALLBACK_TARGET &&
128
+ action.actionTargetSelector === FALLBACK_SELECTOR)).toEqual(false);
129
+ });
130
+ (0, vitest_1.test)('with policy', async () => {
131
+ const call = await (0, smart_sessions_2.getEnableSessionCall)(chains_1.mainnet, {
132
+ owners: {
133
+ type: 'ecdsa',
134
+ accounts: [consts_1.accountA],
135
+ },
136
+ policies: [
137
+ {
138
+ type: 'sudo',
139
+ },
140
+ {
141
+ type: 'universal-action',
142
+ rules: [
143
+ {
144
+ condition: 'equal',
145
+ calldataOffset: 0n,
146
+ referenceValue: '0xd8da6bf26964af9d7eed9e03e53415d37aa96045',
147
+ },
148
+ ],
149
+ },
150
+ ],
151
+ });
152
+ const sessionData = toSessionData(call);
153
+ // Should have two policies
154
+ (0, vitest_1.expect)(sessionData.userOpPolicies.length).toEqual(2);
155
+ (0, vitest_1.expect)((0, viem_1.isAddress)(sessionData.userOpPolicies[0].policy)).toEqual(true);
156
+ (0, vitest_1.expect)((0, viem_1.isHex)(sessionData.userOpPolicies[0].initData)).toEqual(true);
157
+ (0, vitest_1.expect)((0, viem_1.isAddress)(sessionData.userOpPolicies[1].policy)).toEqual(true);
158
+ (0, vitest_1.expect)((0, viem_1.isHex)(sessionData.userOpPolicies[1].initData)).toEqual(true);
159
+ });
160
+ (0, vitest_1.test)('with action policy', async () => {
161
+ const call = await (0, smart_sessions_2.getEnableSessionCall)(chains_1.mainnet, {
162
+ owners: {
163
+ type: 'ecdsa',
164
+ accounts: [consts_1.accountA],
165
+ },
166
+ actions: [
167
+ {
168
+ target: TARGET,
169
+ selector: SELECTOR,
170
+ policies: [
171
+ {
172
+ type: 'sudo',
173
+ },
174
+ {
175
+ type: 'universal-action',
176
+ rules: [
177
+ {
178
+ condition: 'equal',
179
+ calldataOffset: 0n,
180
+ referenceValue: '0xd8da6bf26964af9d7eed9e03e53415d37aa96045',
181
+ },
182
+ ],
183
+ },
184
+ ],
185
+ },
186
+ ],
187
+ });
188
+ const sessionData = toSessionData(call);
189
+ // Should have the action
190
+ const action = sessionData.actions.find((action) => action.actionTarget === TARGET &&
191
+ action.actionTargetSelector === SELECTOR);
192
+ (0, vitest_1.expect)(action).toBeDefined();
193
+ if (!action) {
194
+ throw new Error('No action');
195
+ }
196
+ // Should have 2 policies
197
+ const actionPolicies = action.actionPolicies;
198
+ (0, vitest_1.expect)(actionPolicies.length).toEqual(2);
199
+ (0, vitest_1.expect)((0, viem_1.isAddress)(actionPolicies[0].policy)).toEqual(true);
200
+ (0, vitest_1.expect)((0, viem_1.isHex)(actionPolicies[0].initData)).toEqual(true);
201
+ (0, vitest_1.expect)((0, viem_1.isAddress)(actionPolicies[1].policy)).toEqual(true);
202
+ (0, vitest_1.expect)((0, viem_1.isHex)(actionPolicies[1].initData)).toEqual(true);
203
+ });
204
+ function toSessionData(call) {
205
+ (0, vitest_1.expect)((0, viem_1.isHex)(call.data)).toEqual(true);
206
+ (0, vitest_1.expect)((0, viem_1.isAddress)(call.to)).toEqual(true);
207
+ const decoded = (0, viem_1.decodeFunctionData)({
208
+ abi: smart_sessions_1.enableSessionsAbi,
209
+ data: call.data,
210
+ });
211
+ (0, vitest_1.expect)(decoded.functionName).toEqual('enableSessions');
212
+ (0, vitest_1.expect)(decoded.args.length).toEqual(1);
213
+ (0, vitest_1.expect)(decoded.args[0].length).toEqual(1);
214
+ const session = decoded.args[0][0];
215
+ return session;
216
+ }
217
+ });
218
+ (0, vitest_1.describe)('Encode Smart Session Signature', () => {
219
+ (0, vitest_1.test)('use mode', () => {
220
+ const permissionId = '0x4ad46f8661acf29090a7635877ff94953e0ea05b0583d32de3839acc49739182';
221
+ const signature = '0xabcdef';
222
+ const sessionSignature = (0, smart_sessions_2.encodeSmartSessionSignature)(smart_sessions_2.SMART_SESSION_MODE_USE, permissionId, signature);
223
+ (0, vitest_1.expect)(sessionSignature).toEqual('0x004ad46f8661acf29090a7635877ff94953e0ea05b0583d32de3839acc49739182abcdef');
224
+ });
225
+ });
226
+ });
@@ -0,0 +1,21 @@
1
+ import { type Address } from 'viem';
2
+ import type { IntentCost, IntentInput, IntentOpStatus, IntentResult, IntentRoute, Portfolio, SignedIntentOp } from './types';
3
+ export declare class Orchestrator {
4
+ private serverUrl;
5
+ private apiKey;
6
+ constructor(serverUrl: string, apiKey: string);
7
+ getPortfolio(userAddress: Address, filter?: {
8
+ chainIds?: number[];
9
+ tokens?: {
10
+ [chainId: number]: Address[];
11
+ };
12
+ }): Promise<Portfolio>;
13
+ getMaxTokenAmount(userAddress: Address, destinationChainId: number, destinationTokenAddress: Address, destinationGasUnits: bigint): Promise<bigint>;
14
+ getIntentCost(input: IntentInput): Promise<IntentCost>;
15
+ getIntentRoute(input: IntentInput): Promise<IntentRoute>;
16
+ submitIntent(signedIntentOp: SignedIntentOp): Promise<IntentResult>;
17
+ getIntentOpStatus(intentId: bigint): Promise<IntentOpStatus>;
18
+ private parseError;
19
+ private parseErrorMessage;
20
+ }
21
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../orchestrator/client.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,OAAO,EAAuB,MAAM,MAAM,CAAA;AAexD,OAAO,KAAK,EACV,UAAU,EACV,WAAW,EACX,cAAc,EACd,YAAY,EACZ,WAAW,EACX,SAAS,EAET,cAAc,EACf,MAAM,SAAS,CAAA;AAGhB,qBAAa,YAAY;IACvB,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,MAAM,CAAQ;gBAEV,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAKvC,YAAY,CAChB,WAAW,EAAE,OAAO,EACpB,MAAM,CAAC,EAAE;QACP,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;QACnB,MAAM,CAAC,EAAE;YACP,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,EAAE,CAAA;SAC7B,CAAA;KACF,GACA,OAAO,CAAC,SAAS,CAAC;IAmDf,iBAAiB,CACrB,WAAW,EAAE,OAAO,EACpB,kBAAkB,EAAE,MAAM,EAC1B,uBAAuB,EAAE,OAAO,EAChC,mBAAmB,EAAE,MAAM,GAC1B,OAAO,CAAC,MAAM,CAAC;IA0CZ,aAAa,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;IA0BtD,cAAc,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IAqBxD,YAAY,CAAC,cAAc,EAAE,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC;IAqBnE,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAkBlE,OAAO,CAAC,UAAU;IA0ElB,OAAO,CAAC,iBAAiB;CAmD1B"}
@@ -0,0 +1,284 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Orchestrator = void 0;
7
+ const axios_1 = __importDefault(require("axios"));
8
+ const viem_1 = require("viem");
9
+ const error_1 = require("./error");
10
+ const utils_1 = require("./utils");
11
+ class Orchestrator {
12
+ serverUrl;
13
+ apiKey;
14
+ constructor(serverUrl, apiKey) {
15
+ this.serverUrl = serverUrl;
16
+ this.apiKey = apiKey;
17
+ }
18
+ async getPortfolio(userAddress, filter) {
19
+ try {
20
+ const response = await axios_1.default.get(`${this.serverUrl}/accounts/${userAddress}/portfolio`, {
21
+ params: {
22
+ chainIds: filter?.chainIds?.join(','),
23
+ tokens: filter?.tokens
24
+ ? Object.entries(filter.tokens)
25
+ .map(([chainId, tokens]) => tokens.map((token) => `${chainId}:${token}`))
26
+ .reduce(viem_1.concat, [])
27
+ : undefined,
28
+ },
29
+ headers: {
30
+ 'x-api-key': this.apiKey,
31
+ },
32
+ });
33
+ const portfolioResponse = response.data.portfolio;
34
+ const portfolio = portfolioResponse.map((tokenResponse) => ({
35
+ symbol: tokenResponse.tokenName,
36
+ decimals: tokenResponse.tokenDecimals,
37
+ balances: {
38
+ locked: BigInt(tokenResponse.balance.locked),
39
+ unlocked: BigInt(tokenResponse.balance.unlocked),
40
+ },
41
+ chains: tokenResponse.tokenChainBalance.map((chainBalance) => ({
42
+ chain: chainBalance.chainId,
43
+ address: chainBalance.tokenAddress,
44
+ locked: BigInt(chainBalance.balance.locked),
45
+ unlocked: BigInt(chainBalance.balance.unlocked),
46
+ })),
47
+ }));
48
+ return portfolio;
49
+ }
50
+ catch (error) {
51
+ this.parseError(error);
52
+ throw new Error('Failed to get portfolio');
53
+ }
54
+ }
55
+ async getMaxTokenAmount(userAddress, destinationChainId, destinationTokenAddress, destinationGasUnits) {
56
+ const intentCost = await this.getIntentCost({
57
+ account: {
58
+ address: userAddress,
59
+ accountType: 'ERC7579',
60
+ setupOps: [
61
+ {
62
+ to: viem_1.zeroAddress,
63
+ data: '0x',
64
+ },
65
+ ],
66
+ delegations: {},
67
+ },
68
+ destinationExecutions: [],
69
+ destinationChainId,
70
+ destinationGasUnits,
71
+ tokenTransfers: [
72
+ {
73
+ tokenAddress: destinationTokenAddress,
74
+ },
75
+ ],
76
+ });
77
+ if (!intentCost.hasFulfilledAll) {
78
+ return 0n;
79
+ }
80
+ const tokenReceived = intentCost.tokensReceived.find((token) => token.tokenAddress.toLowerCase() ===
81
+ destinationTokenAddress.toLowerCase());
82
+ if (!tokenReceived) {
83
+ return 0n;
84
+ }
85
+ const tokenAmount = tokenReceived.destinationAmount;
86
+ if (tokenAmount < 0n) {
87
+ throw new Error(`Balance not available. Make sure the account is deployed`);
88
+ }
89
+ return tokenReceived.destinationAmount;
90
+ }
91
+ async getIntentCost(input) {
92
+ try {
93
+ const response = await axios_1.default.post(`${this.serverUrl}/intents/cost`, {
94
+ ...(0, utils_1.convertBigIntFields)({
95
+ ...input,
96
+ tokenTransfers: input.tokenTransfers.map((transfer) => ({
97
+ tokenAddress: transfer.tokenAddress,
98
+ })),
99
+ }),
100
+ }, {
101
+ headers: {
102
+ 'x-api-key': this.apiKey,
103
+ },
104
+ });
105
+ return response.data;
106
+ }
107
+ catch (error) {
108
+ this.parseError(error);
109
+ throw new Error('Failed to get intent cost');
110
+ }
111
+ }
112
+ async getIntentRoute(input) {
113
+ try {
114
+ const response = await axios_1.default.post(`${this.serverUrl}/intents/route`, {
115
+ ...(0, utils_1.convertBigIntFields)(input),
116
+ }, {
117
+ headers: {
118
+ 'x-api-key': this.apiKey,
119
+ },
120
+ });
121
+ return response.data;
122
+ }
123
+ catch (error) {
124
+ this.parseError(error);
125
+ throw new Error('Failed to get intent route');
126
+ }
127
+ }
128
+ async submitIntent(signedIntentOp) {
129
+ try {
130
+ const response = await axios_1.default.post(`${this.serverUrl}/intent-operations`, {
131
+ signedIntentOp: (0, utils_1.convertBigIntFields)(signedIntentOp),
132
+ }, {
133
+ headers: {
134
+ 'x-api-key': this.apiKey,
135
+ },
136
+ });
137
+ return response.data;
138
+ }
139
+ catch (error) {
140
+ this.parseError(error);
141
+ throw new Error('Failed to submit intent');
142
+ }
143
+ }
144
+ async getIntentOpStatus(intentId) {
145
+ try {
146
+ const response = await axios_1.default.get(`${this.serverUrl}/intent-operation/${intentId.toString()}/status`, {
147
+ headers: {
148
+ 'x-api-key': this.apiKey,
149
+ },
150
+ });
151
+ return response.data;
152
+ }
153
+ catch (error) {
154
+ this.parseError(error);
155
+ throw new Error('Failed to get intent op status');
156
+ }
157
+ }
158
+ parseError(error) {
159
+ if (error.response) {
160
+ let errorType;
161
+ if (error.response.status) {
162
+ switch (error.response.status) {
163
+ case 400:
164
+ errorType = 'Bad Request';
165
+ break;
166
+ case 401:
167
+ errorType = 'Unauthorized';
168
+ break;
169
+ case 403:
170
+ errorType = 'Forbidden';
171
+ break;
172
+ case 404:
173
+ errorType = 'Not Found';
174
+ break;
175
+ case 409:
176
+ errorType = 'Conflict';
177
+ break;
178
+ case 422:
179
+ errorType = 'Unprocessable Entity';
180
+ break;
181
+ case 500:
182
+ errorType = 'Internal Server Error';
183
+ break;
184
+ default:
185
+ errorType = 'Unknown';
186
+ }
187
+ }
188
+ let context = {};
189
+ if (error.response.data) {
190
+ const { errors, traceId, message } = error.response.data;
191
+ if (message) {
192
+ const mainErrorParams = {
193
+ context: { traceId },
194
+ errorType,
195
+ traceId,
196
+ };
197
+ this.parseErrorMessage(message, mainErrorParams);
198
+ }
199
+ for (const err of errors) {
200
+ let errorMessage = `Rhinestone Error: ${err.message}`;
201
+ if (errorType) {
202
+ errorMessage += ` (${errorType})`;
203
+ }
204
+ if (traceId) {
205
+ errorMessage += ` [Trace ID: ${traceId}]`;
206
+ context.traceId = traceId;
207
+ }
208
+ console.error(errorMessage);
209
+ if (err.context) {
210
+ console.error(`Context: ${JSON.stringify(err.context, undefined, 4)}`);
211
+ }
212
+ context = { ...context, ...err.context };
213
+ const message = err.message;
214
+ const finalErrorParams = {
215
+ context: { ...context, traceId },
216
+ errorType,
217
+ traceId,
218
+ };
219
+ this.parseErrorMessage(message, finalErrorParams);
220
+ }
221
+ }
222
+ else {
223
+ console.error(error);
224
+ }
225
+ }
226
+ }
227
+ parseErrorMessage(message, errorParams) {
228
+ if (message === 'Insufficient balance') {
229
+ throw new error_1.InsufficientBalanceError(errorParams);
230
+ }
231
+ else if (message === 'Unsupported chain id') {
232
+ throw new error_1.UnsupportedChainIdError(errorParams);
233
+ }
234
+ else if (message.startsWith('Unsupported chain ')) {
235
+ const chainIdMatch = message.match(/Unsupported chain (\d+)/);
236
+ if (chainIdMatch) {
237
+ const chainId = parseInt(chainIdMatch[1], 10);
238
+ throw new error_1.UnsupportedChainError(chainId, errorParams);
239
+ }
240
+ throw new error_1.UnsupportedChainIdError(errorParams);
241
+ }
242
+ else if (message.includes('Unsupported token') &&
243
+ message.includes('for chain')) {
244
+ const tokenMatch = message.match(/Unsupported token (\w+) for chain (\d+)/);
245
+ if (tokenMatch) {
246
+ const tokenSymbol = tokenMatch[1];
247
+ const chainId = parseInt(tokenMatch[2], 10);
248
+ throw new error_1.UnsupportedTokenError(tokenSymbol, chainId, errorParams);
249
+ }
250
+ throw new error_1.OrchestratorError({ message, ...errorParams });
251
+ }
252
+ else if (message.includes('not supported on chain')) {
253
+ const tokenMatch = message.match(/Token (.+) not supported on chain (\d+)/);
254
+ if (tokenMatch) {
255
+ const tokenAddress = tokenMatch[1];
256
+ const chainId = parseInt(tokenMatch[2], 10);
257
+ throw new error_1.TokenNotSupportedError(tokenAddress, chainId, errorParams);
258
+ }
259
+ throw new error_1.OrchestratorError({ message, ...errorParams });
260
+ }
261
+ else if (message === 'Authentication is required') {
262
+ throw new error_1.AuthenticationRequiredError(errorParams);
263
+ }
264
+ else if (message === 'Invalid API key') {
265
+ throw new error_1.InvalidApiKeyError(errorParams);
266
+ }
267
+ else if (message === 'Invalid bundle signature') {
268
+ throw new error_1.InvalidIntentSignatureError(errorParams);
269
+ }
270
+ else if (message === 'Only one target token amount can be unset') {
271
+ throw new error_1.OnlyOneTargetTokenAmountCanBeUnsetError(errorParams);
272
+ }
273
+ else if (message === 'No Path Found') {
274
+ throw new error_1.NoPathFoundError(errorParams);
275
+ }
276
+ else if (message === 'Order bundle not found') {
277
+ throw new error_1.IntentNotFoundError(errorParams);
278
+ }
279
+ else {
280
+ throw new error_1.OrchestratorError({ message, ...errorParams });
281
+ }
282
+ }
283
+ }
284
+ exports.Orchestrator = Orchestrator;
@@ -0,0 +1,5 @@
1
+ declare const PROD_ORCHESTRATOR_URL = "https://v1.orchestrator.rhinestone.dev";
2
+ declare const STAGING_ORCHESTRATOR_URL = "https://staging.v1.orchestrator.rhinestone.dev";
3
+ declare const RHINESTONE_SPOKE_POOL_ADDRESS = "0x000000000060f6e853447881951574cdd0663530";
4
+ export { PROD_ORCHESTRATOR_URL, STAGING_ORCHESTRATOR_URL, RHINESTONE_SPOKE_POOL_ADDRESS, };
5
+ //# sourceMappingURL=consts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consts.d.ts","sourceRoot":"","sources":["../../../orchestrator/consts.ts"],"names":[],"mappings":"AAAA,QAAA,MAAM,qBAAqB,2CAA2C,CAAA;AACtE,QAAA,MAAM,wBAAwB,mDACoB,CAAA;AAClD,QAAA,MAAM,6BAA6B,+CACW,CAAA;AAE9C,OAAO,EACL,qBAAqB,EACrB,wBAAwB,EACxB,6BAA6B,GAC9B,CAAA"}
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RHINESTONE_SPOKE_POOL_ADDRESS = exports.STAGING_ORCHESTRATOR_URL = exports.PROD_ORCHESTRATOR_URL = void 0;
4
+ const PROD_ORCHESTRATOR_URL = 'https://v1.orchestrator.rhinestone.dev';
5
+ exports.PROD_ORCHESTRATOR_URL = PROD_ORCHESTRATOR_URL;
6
+ const STAGING_ORCHESTRATOR_URL = 'https://staging.v1.orchestrator.rhinestone.dev';
7
+ exports.STAGING_ORCHESTRATOR_URL = STAGING_ORCHESTRATOR_URL;
8
+ const RHINESTONE_SPOKE_POOL_ADDRESS = '0x000000000060f6e853447881951574cdd0663530';
9
+ exports.RHINESTONE_SPOKE_POOL_ADDRESS = RHINESTONE_SPOKE_POOL_ADDRESS;
@@ -0,0 +1,96 @@
1
+ declare class OrchestratorError extends Error {
2
+ private readonly _message;
3
+ private readonly _context;
4
+ private readonly _errorType;
5
+ private readonly _traceId;
6
+ constructor(params?: {
7
+ message?: string;
8
+ context?: any;
9
+ errorType?: string;
10
+ traceId?: string;
11
+ });
12
+ get message(): string;
13
+ get context(): any;
14
+ get errorType(): string;
15
+ get traceId(): string;
16
+ }
17
+ declare class InsufficientBalanceError extends OrchestratorError {
18
+ constructor(params?: {
19
+ context?: any;
20
+ errorType?: string;
21
+ traceId?: string;
22
+ });
23
+ }
24
+ declare class UnsupportedChainIdError extends OrchestratorError {
25
+ constructor(params?: {
26
+ context?: any;
27
+ errorType?: string;
28
+ traceId?: string;
29
+ });
30
+ }
31
+ declare class UnsupportedChainError extends OrchestratorError {
32
+ constructor(chainId: number, params?: {
33
+ context?: any;
34
+ errorType?: string;
35
+ traceId?: string;
36
+ });
37
+ }
38
+ declare class UnsupportedTokenError extends OrchestratorError {
39
+ constructor(tokenSymbol: string, chainId: number, params?: {
40
+ context?: any;
41
+ errorType?: string;
42
+ traceId?: string;
43
+ });
44
+ }
45
+ declare class TokenNotSupportedError extends OrchestratorError {
46
+ constructor(tokenAddress: string, chainId: number, params?: {
47
+ context?: any;
48
+ errorType?: string;
49
+ traceId?: string;
50
+ });
51
+ }
52
+ declare class AuthenticationRequiredError extends OrchestratorError {
53
+ constructor(params?: {
54
+ context?: any;
55
+ errorType?: string;
56
+ traceId?: string;
57
+ });
58
+ }
59
+ declare class InvalidApiKeyError extends OrchestratorError {
60
+ constructor(params?: {
61
+ context?: any;
62
+ errorType?: string;
63
+ traceId?: string;
64
+ });
65
+ }
66
+ declare class InvalidIntentSignatureError extends OrchestratorError {
67
+ constructor(params?: {
68
+ context?: any;
69
+ errorType?: string;
70
+ traceId?: string;
71
+ });
72
+ }
73
+ declare class OnlyOneTargetTokenAmountCanBeUnsetError extends OrchestratorError {
74
+ constructor(params?: {
75
+ context?: any;
76
+ errorType?: string;
77
+ traceId?: string;
78
+ });
79
+ }
80
+ declare class NoPathFoundError extends OrchestratorError {
81
+ constructor(params?: {
82
+ context?: any;
83
+ errorType?: string;
84
+ traceId?: string;
85
+ });
86
+ }
87
+ declare class IntentNotFoundError extends OrchestratorError {
88
+ constructor(params?: {
89
+ context?: any;
90
+ errorType?: string;
91
+ traceId?: string;
92
+ });
93
+ }
94
+ declare function isOrchestratorError(error: Error): error is OrchestratorError;
95
+ export { isOrchestratorError, OrchestratorError, InsufficientBalanceError, UnsupportedChainIdError, UnsupportedChainError, UnsupportedTokenError, TokenNotSupportedError, AuthenticationRequiredError, InvalidApiKeyError, InvalidIntentSignatureError, OnlyOneTargetTokenAmountCanBeUnsetError, NoPathFoundError, IntentNotFoundError, };
96
+ //# sourceMappingURL=error.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../../orchestrator/error.ts"],"names":[],"mappings":"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"}