@charterlabs/rhinestone-sdk 0.2.7-dev.4 → 0.2.8

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 (63) hide show
  1. package/README.md +46 -8
  2. package/dist/src/accounts/index.d.ts +4 -1
  3. package/dist/src/accounts/index.d.ts.map +1 -1
  4. package/dist/src/accounts/index.js +36 -5
  5. package/dist/src/accounts/passport.d.ts +12 -0
  6. package/dist/src/accounts/passport.d.ts.map +1 -0
  7. package/dist/src/accounts/passport.js +173 -0
  8. package/dist/src/actions/smart-sessions.d.ts +23 -0
  9. package/dist/src/actions/smart-sessions.d.ts.map +1 -0
  10. package/dist/src/actions/{smart-session.js → smart-sessions.js} +13 -0
  11. package/dist/src/errors/index.d.ts +2 -2
  12. package/dist/src/errors/index.d.ts.map +1 -1
  13. package/dist/src/errors/index.js +16 -1
  14. package/dist/src/execution/compact.d.ts +3 -3
  15. package/dist/src/execution/compact.d.ts.map +1 -1
  16. package/dist/src/execution/compact.js +3 -3
  17. package/dist/src/execution/error.d.ts +8 -1
  18. package/dist/src/execution/error.d.ts.map +1 -1
  19. package/dist/src/execution/error.js +10 -1
  20. package/dist/src/execution/index.d.ts +3 -2
  21. package/dist/src/execution/index.d.ts.map +1 -1
  22. package/dist/src/execution/index.js +62 -9
  23. package/dist/src/execution/multiChainOps.d.ts +40 -0
  24. package/dist/src/execution/multiChainOps.d.ts.map +1 -0
  25. package/dist/src/execution/multiChainOps.js +39 -0
  26. package/dist/src/execution/permit2.d.ts +2 -2
  27. package/dist/src/execution/permit2.d.ts.map +1 -1
  28. package/dist/src/execution/permit2.js +28 -19
  29. package/dist/src/execution/smart-session.d.ts.map +1 -1
  30. package/dist/src/execution/smart-session.js +3 -3
  31. package/dist/src/execution/types.d.ts +2 -1
  32. package/dist/src/execution/types.d.ts.map +1 -1
  33. package/dist/src/execution/utils.d.ts +15 -8
  34. package/dist/src/execution/utils.d.ts.map +1 -1
  35. package/dist/src/execution/utils.js +88 -72
  36. package/dist/src/index.d.ts +7 -6
  37. package/dist/src/index.d.ts.map +1 -1
  38. package/dist/src/index.js +9 -21
  39. package/dist/src/modules/index.test.js +1 -1
  40. package/dist/src/modules/read.js +2 -2
  41. package/dist/src/modules/validators/smart-sessions.d.ts +4 -4
  42. package/dist/src/modules/validators/smart-sessions.d.ts.map +1 -1
  43. package/dist/src/modules/validators/smart-sessions.js +10 -72
  44. package/dist/src/modules/validators/smart-sessions.test.js +4 -5
  45. package/dist/src/orchestrator/client.d.ts +3 -2
  46. package/dist/src/orchestrator/client.d.ts.map +1 -1
  47. package/dist/src/orchestrator/client.js +217 -171
  48. package/dist/src/orchestrator/error.d.ts +111 -1
  49. package/dist/src/orchestrator/error.d.ts.map +1 -1
  50. package/dist/src/orchestrator/error.js +128 -1
  51. package/dist/src/orchestrator/index.d.ts +4 -4
  52. package/dist/src/orchestrator/index.d.ts.map +1 -1
  53. package/dist/src/orchestrator/index.js +16 -1
  54. package/dist/src/orchestrator/types.d.ts +30 -24
  55. package/dist/src/orchestrator/types.d.ts.map +1 -1
  56. package/dist/src/types.d.ts +12 -2
  57. package/dist/src/types.d.ts.map +1 -1
  58. package/dist/src/utils/index.d.ts +3 -0
  59. package/dist/src/utils/index.d.ts.map +1 -0
  60. package/dist/src/utils/index.js +5 -0
  61. package/package.json +1 -1
  62. package/dist/src/actions/smart-session.d.ts +0 -11
  63. package/dist/src/actions/smart-session.d.ts.map +0 -1
@@ -9,13 +9,10 @@ exports.getPermissionId = getPermissionId;
9
9
  exports.isSessionEnabled = isSessionEnabled;
10
10
  const solady_1 = require("solady");
11
11
  const viem_1 = require("viem");
12
- const utils_1 = require("../../accounts/utils");
13
- const orchestrator_1 = require("../../orchestrator");
14
12
  const smart_sessions_1 = require("../abi/smart-sessions");
15
13
  const common_1 = require("../common");
16
- const omni_account_1 = require("../omni-account");
17
14
  const core_1 = require("./core");
18
- const SMART_SESSIONS_VALIDATOR_ADDRESS = '0x00000000002b0ecfbd0496ee71e01257da0e37de';
15
+ const SMART_SESSIONS_VALIDATOR_ADDRESS = '0x00000000008bdaba73cd9815d79069c247eb4bda';
19
16
  exports.SMART_SESSIONS_VALIDATOR_ADDRESS = SMART_SESSIONS_VALIDATOR_ADDRESS;
20
17
  const SMART_SESSION_MODE_USE = '0x00';
21
18
  exports.SMART_SESSION_MODE_USE = SMART_SESSION_MODE_USE;
@@ -37,25 +34,11 @@ const ACTION_CONDITION_GREATER_THAN_OR_EQUAL = 3;
37
34
  const ACTION_CONDITION_LESS_THAN_OR_EQUAL = 4;
38
35
  const ACTION_CONDITION_NOT_EQUAL = 5;
39
36
  const ACTION_CONDITION_IN_RANGE = 6;
40
- async function getSessionData(chain, session, provider) {
41
- const { appDomainSeparator, contentsType } = await getSessionAllowedERC7739Content(chain, provider);
42
- const allowedERC7739Content = [
43
- {
44
- appDomainSeparator,
45
- contentName: [contentsType],
46
- },
47
- ];
48
- return getSmartSessionData(chain, session, allowedERC7739Content);
37
+ async function getSessionData(session) {
38
+ return getSmartSessionData(session);
49
39
  }
50
- async function getEnableSessionCall(chain, session, provider) {
51
- const { appDomainSeparator, contentsType } = await getSessionAllowedERC7739Content(chain, provider);
52
- const allowedERC7739Content = [
53
- {
54
- appDomainSeparator,
55
- contentName: [contentsType],
56
- },
57
- ];
58
- const sessionData = getSmartSessionData(chain, session, allowedERC7739Content);
40
+ async function getEnableSessionCall(session) {
41
+ const sessionData = getSmartSessionData(session);
59
42
  return {
60
43
  to: SMART_SESSIONS_VALIDATOR_ADDRESS,
61
44
  data: (0, viem_1.encodeFunctionData)({
@@ -65,50 +48,7 @@ async function getEnableSessionCall(chain, session, provider) {
65
48
  }),
66
49
  };
67
50
  }
68
- function getOmniAccountActions(chain) {
69
- const wethAddress = (0, orchestrator_1.getWethAddress)(chain);
70
- const omniActions = [
71
- {
72
- actionTarget: orchestrator_1.RHINESTONE_SPOKE_POOL_ADDRESS,
73
- actionTargetSelector: '0xa2418864', // injected execution
74
- actionPolicies: [getPolicyData({ type: 'sudo' })],
75
- },
76
- {
77
- actionTarget: omni_account_1.HOOK_ADDRESS,
78
- actionTargetSelector: '0x27c777a9', // injected execution
79
- actionPolicies: [getPolicyData({ type: 'sudo' })],
80
- },
81
- {
82
- actionTarget: wethAddress,
83
- actionTargetSelector: '0xd0e30db0', // deposit
84
- actionPolicies: [getPolicyData({ type: 'sudo' })],
85
- },
86
- {
87
- actionTarget: wethAddress,
88
- actionTargetSelector: '0x2e1a7d4d', // widthdraw
89
- actionPolicies: [getPolicyData({ type: 'sudo' })],
90
- },
91
- ];
92
- return omniActions;
93
- }
94
- async function getSessionAllowedERC7739Content(chain, provider) {
95
- const publicClient = (0, viem_1.createPublicClient)({
96
- chain,
97
- transport: (0, utils_1.createTransport)(chain, provider),
98
- });
99
- const appDomainSeparator = await publicClient.readContract({
100
- address: omni_account_1.HOOK_ADDRESS,
101
- abi: (0, viem_1.parseAbi)(['function DOMAIN_SEPARATOR() view returns (bytes32)']),
102
- functionName: 'DOMAIN_SEPARATOR',
103
- });
104
- const contentsType = 'MultichainCompact(address sponsor,uint256 nonce,uint256 expires,Segment[] segments)Segment(address arbiter,uint256 chainId,uint256[2][] idsAndAmounts,Witness witness)Witness(address recipient,uint256[2][] tokenOut,uint256 depositId,uint256 targetChain,uint32 fillDeadline,XchainExec[] execs,bytes32 userOpHash,uint32 maxFeeBps)XchainExec(address to,uint256 value,bytes data)';
105
- return {
106
- appDomainSeparator,
107
- contentsType,
108
- };
109
- }
110
- function getSmartSessionData(chain, session, allowedERC7739Content) {
111
- const omniActions = getOmniAccountActions(chain);
51
+ function getSmartSessionData(session) {
112
52
  const sessionValidator = (0, core_1.getValidator)(session.owners);
113
53
  const userOpPolicies = (session.policies || [
114
54
  {
@@ -128,8 +68,7 @@ function getSmartSessionData(chain, session, allowedERC7739Content) {
128
68
  target: SMART_SESSIONS_FALLBACK_TARGET_FLAG,
129
69
  selector: SMART_SESSIONS_FALLBACK_TARGET_SELECTOR_FLAG,
130
70
  },
131
- ])
132
- .map((action) => {
71
+ ]).map((action) => {
133
72
  const actionPolicies = (action.policies || [
134
73
  {
135
74
  type: 'sudo',
@@ -142,11 +81,10 @@ function getSmartSessionData(chain, session, allowedERC7739Content) {
142
81
  actionTarget: action.target,
143
82
  actionPolicies,
144
83
  };
145
- })
146
- .concat(omniActions),
84
+ }),
147
85
  erc7739Policies: {
148
- allowedERC7739Content,
149
- erc1271Policies: [getPolicyData({ type: 'sudo' })],
86
+ allowedERC7739Content: [],
87
+ erc1271Policies: [],
150
88
  },
151
89
  permitERC4337Paymaster: true,
152
90
  };
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const viem_1 = require("viem");
4
- const chains_1 = require("viem/chains");
5
4
  const vitest_1 = require("vitest");
6
5
  const consts_1 = require("../../../test/consts");
7
6
  const smart_sessions_1 = require("../abi/smart-sessions");
@@ -92,7 +91,7 @@ const smart_sessions_2 = require("./smart-sessions");
92
91
  const FALLBACK_TARGET = '0x0000000000000000000000000000000000000001';
93
92
  const FALLBACK_SELECTOR = '0x00000001';
94
93
  (0, vitest_1.test)('default', async () => {
95
- const call = await (0, smart_sessions_2.getEnableSessionCall)(chains_1.mainnet, {
94
+ const call = await (0, smart_sessions_2.getEnableSessionCall)({
96
95
  owners: {
97
96
  type: 'ecdsa',
98
97
  accounts: [consts_1.accountA],
@@ -104,7 +103,7 @@ const smart_sessions_2 = require("./smart-sessions");
104
103
  action.actionTargetSelector === FALLBACK_SELECTOR)).toEqual(true);
105
104
  });
106
105
  (0, vitest_1.test)('with action', async () => {
107
- const call = await (0, smart_sessions_2.getEnableSessionCall)(chains_1.mainnet, {
106
+ const call = await (0, smart_sessions_2.getEnableSessionCall)({
108
107
  owners: {
109
108
  type: 'ecdsa',
110
109
  accounts: [consts_1.accountA],
@@ -125,7 +124,7 @@ const smart_sessions_2 = require("./smart-sessions");
125
124
  action.actionTargetSelector === FALLBACK_SELECTOR)).toEqual(false);
126
125
  });
127
126
  (0, vitest_1.test)('with policy', async () => {
128
- const call = await (0, smart_sessions_2.getEnableSessionCall)(chains_1.mainnet, {
127
+ const call = await (0, smart_sessions_2.getEnableSessionCall)({
129
128
  owners: {
130
129
  type: 'ecdsa',
131
130
  accounts: [consts_1.accountA],
@@ -155,7 +154,7 @@ const smart_sessions_2 = require("./smart-sessions");
155
154
  (0, vitest_1.expect)((0, viem_1.isHex)(sessionData.userOpPolicies[1].initData)).toEqual(true);
156
155
  });
157
156
  (0, vitest_1.test)('with action policy', async () => {
158
- const call = await (0, smart_sessions_2.getEnableSessionCall)(chains_1.mainnet, {
157
+ const call = await (0, smart_sessions_2.getEnableSessionCall)({
159
158
  owners: {
160
159
  type: 'ecdsa',
161
160
  accounts: [consts_1.accountA],
@@ -13,9 +13,10 @@ export declare class Orchestrator {
13
13
  getMaxTokenAmount(userAddress: Address, destinationChainId: number, destinationTokenAddress: Address, destinationGasUnits: bigint, sponsored: boolean): Promise<bigint>;
14
14
  getIntentCost(input: IntentInput): Promise<IntentCost>;
15
15
  getIntentRoute(input: IntentInput): Promise<IntentRoute>;
16
- submitIntent(signedIntentOp: SignedIntentOp): Promise<IntentResult>;
17
- simulateIntent(signedIntentOp: SignedIntentOp): Promise<IntentResult>;
16
+ submitIntent(signedIntentOpUnformatted: SignedIntentOp, dryRun: boolean): Promise<IntentResult>;
18
17
  getIntentOpStatus(intentId: bigint): Promise<IntentOpStatus>;
18
+ private getHeaders;
19
+ private fetch;
19
20
  private parseError;
20
21
  private parseErrorMessage;
21
22
  }
@@ -1 +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,CAAC,CAAQ;gBAEX,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM;IAKxC,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,EAC3B,SAAS,EAAE,OAAO,GACjB,OAAO,CAAC,MAAM,CAAC;IAqDZ,aAAa,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;IAqBtD,cAAc,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IAqBxD,YAAY,CAAC,cAAc,EAAE,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC;IAqBnE,cAAc,CAAC,cAAc,EAAE,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC;IAqBrE,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAkBlE,OAAO,CAAC,UAAU;IA0ElB,OAAO,CAAC,iBAAiB;CAmD1B"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../orchestrator/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAe,MAAM,MAAM,CAAA;AAwBhD,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,CAAC,CAAQ;gBAEX,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM;IAKxC,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;IA+Cf,iBAAiB,CACrB,WAAW,EAAE,OAAO,EACpB,kBAAkB,EAAE,MAAM,EAC1B,uBAAuB,EAAE,OAAO,EAChC,mBAAmB,EAAE,MAAM,EAC3B,SAAS,EAAE,OAAO,GACjB,OAAO,CAAC,MAAM,CAAC;IAqDZ,aAAa,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;IAQtD,cAAc,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IAQxD,YAAY,CAChB,yBAAyB,EAAE,cAAc,EACzC,MAAM,EAAE,OAAO,GACd,OAAO,CAAC,YAAY,CAAC;IAgBlB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IASlE,OAAO,CAAC,UAAU;YAUJ,KAAK;IA4BnB,OAAO,CAAC,UAAU;IA6GlB,OAAO,CAAC,iBAAiB;CAwF1B"}
@@ -1,10 +1,6 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.Orchestrator = void 0;
7
- const axios_1 = __importDefault(require("axios"));
8
4
  const viem_1 = require("viem");
9
5
  const error_1 = require("./error");
10
6
  const utils_1 = require("./utils");
@@ -16,41 +12,36 @@ class Orchestrator {
16
12
  this.apiKey = apiKey;
17
13
  }
18
14
  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;
15
+ const params = new URLSearchParams();
16
+ if (filter?.chainIds) {
17
+ params.set('chainIds', filter.chainIds.join(','));
49
18
  }
50
- catch (error) {
51
- this.parseError(error);
52
- throw new error_1.OrchestratorError({ message: 'Failed to get portfolio' });
19
+ if (filter?.tokens) {
20
+ params.set('tokens', Object.entries(filter.tokens)
21
+ .flatMap(([chainId, tokens]) => tokens.map((token) => `${chainId}:${token}`))
22
+ .join(','));
53
23
  }
24
+ const url = new URL(`${this.serverUrl}/accounts/${userAddress}/portfolio`);
25
+ url.search = params.toString();
26
+ const json = await this.fetch(url.toString(), {
27
+ headers: this.getHeaders(),
28
+ });
29
+ const portfolioResponse = json.portfolio;
30
+ const portfolio = portfolioResponse.map((tokenResponse) => ({
31
+ symbol: tokenResponse.tokenName,
32
+ decimals: tokenResponse.tokenDecimals,
33
+ balances: {
34
+ locked: BigInt(tokenResponse.balance.locked),
35
+ unlocked: BigInt(tokenResponse.balance.unlocked),
36
+ },
37
+ chains: tokenResponse.tokenChainBalance.map((chainBalance) => ({
38
+ chain: chainBalance.chainId,
39
+ address: chainBalance.tokenAddress,
40
+ locked: BigInt(chainBalance.balance.locked),
41
+ unlocked: BigInt(chainBalance.balance.unlocked),
42
+ })),
43
+ }));
44
+ return portfolio;
54
45
  }
55
46
  async getMaxTokenAmount(userAddress, destinationChainId, destinationTokenAddress, destinationGasUnits, sponsored) {
56
47
  const intentCost = await this.getIntentCost({
@@ -90,159 +81,184 @@ class Orchestrator {
90
81
  return 0n;
91
82
  }
92
83
  const tokenAmount = tokenReceived.destinationAmount;
93
- if (tokenAmount < 0n) {
84
+ if (BigInt(tokenAmount) < 0n) {
94
85
  throw new Error(`Balance not available. Make sure the account is deployed`);
95
86
  }
96
87
  // `sponsorSettings` is not taken into account in the API response for now
97
88
  // As a workaround, we use the `amountSpent` if the transaction is sponsored
98
89
  return sponsored
99
- ? tokenReceived.amountSpent
100
- : tokenReceived.destinationAmount;
90
+ ? BigInt(tokenReceived.amountSpent)
91
+ : BigInt(tokenReceived.destinationAmount);
101
92
  }
102
93
  async getIntentCost(input) {
103
- try {
104
- const response = await axios_1.default.post(`${this.serverUrl}/intents/cost`, {
105
- ...(0, utils_1.convertBigIntFields)(input),
106
- }, {
107
- headers: {
108
- 'x-api-key': this.apiKey,
109
- },
110
- });
111
- return response.data;
112
- }
113
- catch (error) {
114
- this.parseError(error);
115
- throw new error_1.OrchestratorError({ message: 'Failed to get intent cost' });
116
- }
94
+ return await this.fetch(`${this.serverUrl}/intents/cost`, {
95
+ method: 'POST',
96
+ headers: this.getHeaders(),
97
+ body: JSON.stringify((0, utils_1.convertBigIntFields)(input)),
98
+ });
117
99
  }
118
100
  async getIntentRoute(input) {
119
- try {
120
- const response = await axios_1.default.post(`${this.serverUrl}/intents/route`, {
121
- ...(0, utils_1.convertBigIntFields)(input),
122
- }, {
123
- headers: {
124
- 'x-api-key': this.apiKey,
125
- },
126
- });
127
- return response.data;
128
- }
129
- catch (error) {
130
- this.parseError(error);
131
- throw new error_1.OrchestratorError({ message: 'Failed to get intent route' });
132
- }
101
+ return await this.fetch(`${this.serverUrl}/intents/route`, {
102
+ method: 'POST',
103
+ headers: this.getHeaders(),
104
+ body: JSON.stringify((0, utils_1.convertBigIntFields)(input)),
105
+ });
133
106
  }
134
- async submitIntent(signedIntentOp) {
135
- try {
136
- const response = await axios_1.default.post(`${this.serverUrl}/intent-operations`, {
137
- signedIntentOp: (0, utils_1.convertBigIntFields)(signedIntentOp),
138
- }, {
139
- headers: {
140
- 'x-api-key': this.apiKey,
141
- },
142
- });
143
- return response.data;
144
- }
145
- catch (error) {
146
- this.parseError(error);
147
- throw new error_1.OrchestratorError({ message: 'Failed to submit intent' });
107
+ async submitIntent(signedIntentOpUnformatted, dryRun) {
108
+ const signedIntentOp = (0, utils_1.convertBigIntFields)(signedIntentOpUnformatted);
109
+ if (dryRun) {
110
+ signedIntentOp.options = {
111
+ dryRun: true,
112
+ };
148
113
  }
114
+ return await this.fetch(`${this.serverUrl}/intent-operations`, {
115
+ method: 'POST',
116
+ headers: this.getHeaders(),
117
+ body: JSON.stringify({
118
+ signedIntentOp,
119
+ }),
120
+ });
149
121
  }
150
- async simulateIntent(signedIntentOp) {
151
- try {
152
- const response = await axios_1.default.post(`${this.serverUrl}/intent-operations/simulate`, {
153
- signedIntentOp: (0, utils_1.convertBigIntFields)(signedIntentOp),
154
- }, {
155
- headers: {
156
- 'x-api-key': this.apiKey,
157
- },
158
- });
159
- return response.data;
160
- }
161
- catch (error) {
162
- this.parseError(error);
163
- throw new error_1.OrchestratorError({ message: 'Failed to simulate intent' });
122
+ async getIntentOpStatus(intentId) {
123
+ return await this.fetch(`${this.serverUrl}/intent-operation/${intentId.toString()}`, {
124
+ headers: this.getHeaders(),
125
+ });
126
+ }
127
+ getHeaders() {
128
+ const headers = {
129
+ 'Content-Type': 'application/json',
130
+ };
131
+ if (this.apiKey) {
132
+ headers['x-api-key'] = this.apiKey;
164
133
  }
134
+ return headers;
165
135
  }
166
- async getIntentOpStatus(intentId) {
167
- try {
168
- const response = await axios_1.default.get(`${this.serverUrl}/intent-operation/${intentId.toString()}/status`, {
169
- headers: {
170
- 'x-api-key': this.apiKey,
136
+ async fetch(url, options) {
137
+ const response = await fetch(url, options);
138
+ if (!response.ok) {
139
+ let errorData = {};
140
+ try {
141
+ errorData = await response.json();
142
+ }
143
+ catch {
144
+ try {
145
+ const text = await response.text();
146
+ errorData = { message: text };
147
+ }
148
+ catch { }
149
+ }
150
+ const retryAfterHeader = response.headers?.get?.('retry-after') || undefined;
151
+ this.parseError({
152
+ response: {
153
+ status: response.status,
154
+ data: errorData,
155
+ headers: {
156
+ retryAfter: retryAfterHeader,
157
+ },
171
158
  },
172
159
  });
173
- return response.data;
174
- }
175
- catch (error) {
176
- this.parseError(error);
177
- throw new error_1.OrchestratorError({ message: 'Failed to get intent op status' });
178
160
  }
161
+ return response.json();
179
162
  }
180
163
  parseError(error) {
181
164
  if (error.response) {
182
- let errorType;
183
- if (error.response.status) {
184
- switch (error.response.status) {
185
- case 400:
186
- errorType = 'Bad Request';
187
- break;
188
- case 401:
189
- errorType = 'Unauthorized';
190
- break;
191
- case 403:
192
- errorType = 'Forbidden';
193
- break;
194
- case 404:
195
- errorType = 'Not Found';
196
- break;
197
- case 409:
198
- errorType = 'Conflict';
199
- break;
200
- case 422:
201
- errorType = 'Unprocessable Entity';
202
- break;
203
- case 500:
204
- errorType = 'Internal Server Error';
205
- break;
206
- default:
207
- errorType = 'Unknown';
208
- }
165
+ const status = error.response.status;
166
+ const { headers } = error.response;
167
+ const { errors = [], traceId, message } = error.response.data || {};
168
+ let errorType = 'Unknown';
169
+ switch (status) {
170
+ case 400:
171
+ errorType = 'Bad Request';
172
+ break;
173
+ case 401:
174
+ errorType = 'Unauthorized';
175
+ break;
176
+ case 403:
177
+ errorType = 'Forbidden';
178
+ break;
179
+ case 404:
180
+ errorType = 'Not Found';
181
+ break;
182
+ case 409:
183
+ errorType = 'Conflict';
184
+ break;
185
+ case 422:
186
+ errorType = 'Unprocessable Entity';
187
+ break;
188
+ case 429:
189
+ errorType = 'Too Many Requests';
190
+ break;
191
+ case 500:
192
+ errorType = 'Internal Server Error';
193
+ break;
194
+ case 503:
195
+ errorType = 'Service Unavailable';
196
+ break;
197
+ default:
198
+ errorType = 'Unknown';
209
199
  }
210
- let context = {};
211
- if (error.response.data) {
212
- const { errors, traceId, message } = error.response.data;
213
- if (message) {
214
- const mainErrorParams = {
215
- context: { traceId },
216
- errorType,
217
- traceId,
218
- };
219
- this.parseErrorMessage(message, mainErrorParams);
220
- }
221
- for (const err of errors) {
222
- let errorMessage = `Rhinestone Error: ${err.message}`;
223
- if (errorType) {
224
- errorMessage += ` (${errorType})`;
225
- }
226
- if (traceId) {
227
- errorMessage += ` [Trace ID: ${traceId}]`;
228
- context.traceId = traceId;
200
+ const baseParams = {
201
+ context: { traceId },
202
+ errorType,
203
+ traceId,
204
+ statusCode: status,
205
+ };
206
+ if (status === 429) {
207
+ const retryAfter = headers?.retryAfter;
208
+ const context = { traceId, retryAfter };
209
+ throw new error_1.RateLimitedError({
210
+ ...baseParams,
211
+ context,
212
+ });
213
+ }
214
+ if (status === 503) {
215
+ throw new error_1.ServiceUnavailableError(baseParams);
216
+ }
217
+ if (message) {
218
+ this.parseErrorMessage(message, baseParams);
219
+ }
220
+ for (const err of errors) {
221
+ const mergedParams = {
222
+ ...baseParams,
223
+ context: { ...err.context, traceId },
224
+ };
225
+ this.parseErrorMessage(err.message, mergedParams);
226
+ }
227
+ switch (status) {
228
+ case 400:
229
+ throw new error_1.BadRequestError({
230
+ ...baseParams,
231
+ context: { traceId, errors },
232
+ message: message,
233
+ });
234
+ case 401:
235
+ if (message === 'Authentication is required') {
236
+ throw new error_1.AuthenticationRequiredError(baseParams);
229
237
  }
230
- console.error(errorMessage);
231
- if (err.context) {
232
- console.error(`Context: ${JSON.stringify(err.context, undefined, 4)}`);
238
+ throw new error_1.UnauthorizedError(baseParams);
239
+ case 403:
240
+ throw new error_1.ForbiddenError(baseParams);
241
+ case 404:
242
+ throw new error_1.ResourceNotFoundError(baseParams);
243
+ case 409:
244
+ throw new error_1.ConflictError(baseParams);
245
+ case 500:
246
+ if (errors && errors.length > 0) {
247
+ const mergedParams = {
248
+ ...baseParams,
249
+ context: { ...errors[0].context, traceId },
250
+ };
251
+ throw new error_1.OrchestratorError({
252
+ ...mergedParams,
253
+ message: errors[0].message || 'Internal Server Error',
254
+ });
233
255
  }
234
- context = { ...context, ...err.context };
235
- const message = err.message;
236
- const finalErrorParams = {
237
- context: { ...context, traceId },
238
- errorType,
239
- traceId,
240
- };
241
- this.parseErrorMessage(message, finalErrorParams);
242
- }
243
- }
244
- else {
245
- console.error(error);
256
+ throw new error_1.InternalServerError(baseParams);
257
+ default:
258
+ throw new error_1.OrchestratorError({
259
+ ...baseParams,
260
+ message: message || errorType,
261
+ });
246
262
  }
247
263
  }
248
264
  }
@@ -250,7 +266,8 @@ class Orchestrator {
250
266
  if (message === 'Insufficient balance') {
251
267
  throw new error_1.InsufficientBalanceError(errorParams);
252
268
  }
253
- else if (message === 'Unsupported chain id') {
269
+ else if (message === 'Unsupported chain id' ||
270
+ message === 'Unsupported chain ids') {
254
271
  throw new error_1.UnsupportedChainIdError(errorParams);
255
272
  }
256
273
  else if (message.startsWith('Unsupported chain ')) {
@@ -271,6 +288,10 @@ class Orchestrator {
271
288
  }
272
289
  throw new error_1.OrchestratorError({ message, ...errorParams });
273
290
  }
291
+ else if (message === 'Unsupported token addresses') {
292
+ // generic unsupported tokens without specific symbol/chain context
293
+ throw new error_1.BadRequestError({ message, ...errorParams });
294
+ }
274
295
  else if (message.includes('not supported on chain')) {
275
296
  const tokenMatch = message.match(/Token (.+) not supported on chain (\d+)/);
276
297
  if (tokenMatch) {
@@ -286,18 +307,43 @@ class Orchestrator {
286
307
  else if (message === 'Invalid API key') {
287
308
  throw new error_1.InvalidApiKeyError(errorParams);
288
309
  }
310
+ else if (message === 'Insufficient permissions') {
311
+ throw new error_1.ForbiddenError(errorParams);
312
+ }
289
313
  else if (message === 'Invalid bundle signature') {
290
314
  throw new error_1.InvalidIntentSignatureError(errorParams);
291
315
  }
292
- else if (message === 'Only one target token amount can be unset') {
316
+ else if (message === 'Invalid checksum signature') {
317
+ throw new error_1.InvalidIntentSignatureError(errorParams);
318
+ }
319
+ else if (message === 'Only one target token amount can be unset' ||
320
+ message === 'Only one max-out transfer is allowed') {
293
321
  throw new error_1.OnlyOneTargetTokenAmountCanBeUnsetError(errorParams);
294
322
  }
295
- else if (message === 'No Path Found') {
323
+ else if (message === 'No valid settlement plan found for the given transfers' ||
324
+ message === 'No valid transfers sent for settlement quotes' ||
325
+ message === 'No Path Found') {
296
326
  throw new error_1.NoPathFoundError(errorParams);
297
327
  }
298
- else if (message === 'Order bundle not found') {
328
+ else if (message === 'Emissary is not enabled' ||
329
+ message === 'Emissary is not the expected address') {
330
+ throw new error_1.ForbiddenError(errorParams);
331
+ }
332
+ else if (message.includes('No such intent with nonce') ||
333
+ message === 'Order bundle not found') {
299
334
  throw new error_1.IntentNotFoundError(errorParams);
300
335
  }
336
+ else if (message === 'Could not retrieve a valid quote from any aggregator') {
337
+ throw new error_1.NoPathFoundError(errorParams);
338
+ }
339
+ else if (message === 'No aggregators available for swap') {
340
+ throw new error_1.InternalServerError(errorParams);
341
+ }
342
+ else if (message === 'entity.parse.failed' ||
343
+ message === 'entity.too.large' ||
344
+ message === 'encoding.unsupported') {
345
+ throw new error_1.BodyParserError({ message, ...errorParams });
346
+ }
301
347
  else {
302
348
  throw new error_1.OrchestratorError({ message, ...errorParams });
303
349
  }