@rhinestone/sdk 0.0.0-dev-20261008124126 → 0.0.0-dev-20261008125543

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.
@@ -3,7 +3,7 @@ import { createOrchestratorAuth } from './auth.js';
3
3
  import { ChainCatalog, parseChains } from './chain-catalog.js';
4
4
  import { fetchOrchestratorJson } from './fetch.js';
5
5
  import { mapIntentRequestToWire, mapIntentStatusFromWire, mapPortfolioFromWire, mapQuoteResponseFromWire, mapSignedIntentToWire, mapSplitRequestToWire, mapSplitResultFromWire, } from './mappers.js';
6
- const SDK_VERSION = '0.0.0-dev-20261008124126';
6
+ const SDK_VERSION = '0.0.0-dev-20261008125543';
7
7
  const API_VERSION = '2026-04.blanc';
8
8
  // Bounds how long a killed layer or pulled settlement address stays pinnable.
9
9
  const CHAIN_CATALOG_TTL_MS = 10 * 60 * 1000;
@@ -1,5 +1,5 @@
1
1
  import { type Address } from 'viem';
2
- import type { ScopedAction } from '../types.js';
2
+ import type { ScopedAction, UniversalActionPolicyParamRule } from '../types.js';
3
3
  import type { SettlementCatalog, SettlementContext } from './types.js';
4
4
  /**
5
5
  * ECO — Eco Routes, `Portal.publishAndFund` with Eco's quoted route bytes
@@ -8,7 +8,16 @@ import type { SettlementCatalog, SettlementContext } from './types.js';
8
8
  * The recipient lives inside the vendor route, and the reward's offsets move
9
9
  * with the route's length, so the session pins the one shape the orchestrator
10
10
  * accepts end to end: an ERC-20 reward and a single `transfer` delivery.
11
- * Every pointer and length word is pinned so no field can alias another.
11
+ * Every calldata pointer, the reward's tokens pointer and every count is pinned
12
+ * so no field can alias another. The route's own pointers and byte length are
13
+ * not: the destination Portal
14
+ * (0xEC000769A73b70e16f361a442292500b3BCf4A85, verified source on Base
15
+ * Blockscout) checks every fill and cancel in `_validateRoute`, which hashes
16
+ * `abi.encode(route)` and reverts `InvalidHash`, so only canonical bytes are
17
+ * fillable, and canonical bytes with these counts have exactly the layout the
18
+ * offsets assume. Any other layout is never filled and refunds to the pinned
19
+ * creator after the pinned deadline. This assumes EVM destinations and a Portal
20
+ * that keeps re-encoding.
12
21
  */
13
22
  export declare const ecoPortalAbi: readonly [{
14
23
  readonly name: "publishAndFund";
@@ -108,6 +117,11 @@ export declare const ECO_MIN_VALIDITY_SECONDS: bigint;
108
117
  * `refund` revert and locks the reward.
109
118
  */
110
119
  export declare function proversBetween(settlement: SettlementCatalog, source: number, destination: number): Address[];
120
+ /**
121
+ * The same check on the same word; a usage-limited rule is never the same, as
122
+ * hoisted out of the leg OR it would count calls its branch never admits.
123
+ */
124
+ export declare const sameRule: (a: UniversalActionPolicyParamRule, b: UniversalActionPolicyParamRule) => boolean;
111
125
  /** The publish call, pinned to the permit's destinations, provers and prices. */
112
126
  export declare function scopeEco(ctx: SettlementContext): ScopedAction;
113
127
  //# sourceMappingURL=eco.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"eco.d.ts","sourceRoot":"","sources":["../../../../../../modules/validators/smart-sessions/settlement/eco.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,EAQb,MAAM,MAAM,CAAA;AAGb,OAAO,KAAK,EAEV,YAAY,EAEb,MAAM,UAAU,CAAA;AAEjB,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAA;AAEnE;;;;;;;;GAQG;AAEH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAEvB,CAAA;AAEF,eAAO,MAAM,yBAAyB,eAAsC,CAAA;AAI5E;;;GAGG;AACH,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;IAqBlB,4EAA4E;;;;;;;;;;;;CAYpE,CAAA;AAMV;;;GAGG;AACH,eAAO,MAAM,wBAAwB,QAAuB,CAAA;AAgC5D;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,UAAU,EAAE,iBAAiB,EAC7B,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,GAClB,OAAO,EAAE,CAOX;AAeD,iFAAiF;AACjF,wBAAgB,QAAQ,CAAC,GAAG,EAAE,iBAAiB,GAAG,YAAY,CA2I7D"}
1
+ {"version":3,"file":"eco.d.ts","sourceRoot":"","sources":["../../../../../../modules/validators/smart-sessions/settlement/eco.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,EAQb,MAAM,MAAM,CAAA;AAGb,OAAO,KAAK,EAEV,YAAY,EACZ,8BAA8B,EAC/B,MAAM,UAAU,CAAA;AAEjB,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAA;AAEnE;;;;;;;;;;;;;;;;;GAiBG;AAEH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAEvB,CAAA;AAEF,eAAO,MAAM,yBAAyB,eAAsC,CAAA;AAI5E;;;GAGG;AACH,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;IAqBlB,4EAA4E;;;;;;;;;;;;CAYpE,CAAA;AAMV;;;GAGG;AACH,eAAO,MAAM,wBAAwB,QAAuB,CAAA;AAgC5D;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,UAAU,EAAE,iBAAiB,EAC7B,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,GAClB,OAAO,EAAE,CAOX;AAkBD;;;GAGG;AACH,eAAO,MAAM,QAAQ,GACnB,GAAG,8BAA8B,EACjC,GAAG,8BAA8B,YAMoB,CAAA;AAEvD,iFAAiF;AACjF,wBAAgB,QAAQ,CAAC,GAAG,EAAE,iBAAiB,GAAG,YAAY,CA4J7D"}
@@ -9,7 +9,16 @@ import { SettlementLayerRefusal, served } from './served.js';
9
9
  * The recipient lives inside the vendor route, and the reward's offsets move
10
10
  * with the route's length, so the session pins the one shape the orchestrator
11
11
  * accepts end to end: an ERC-20 reward and a single `transfer` delivery.
12
- * Every pointer and length word is pinned so no field can alias another.
12
+ * Every calldata pointer, the reward's tokens pointer and every count is pinned
13
+ * so no field can alias another. The route's own pointers and byte length are
14
+ * not: the destination Portal
15
+ * (0xEC000769A73b70e16f361a442292500b3BCf4A85, verified source on Base
16
+ * Blockscout) checks every fill and cancel in `_validateRoute`, which hashes
17
+ * `abi.encode(route)` and reverts `InvalidHash`, so only canonical bytes are
18
+ * fillable, and canonical bytes with these counts have exactly the layout the
19
+ * offsets assume. Any other layout is never filled and refunds to the pinned
20
+ * creator after the pinned deadline. This assumes EVM destinations and a Portal
21
+ * that keeps re-encoding.
13
22
  */
14
23
  export const ecoPortalAbi = parseAbi([
15
24
  'function publishAndFund(uint64 destination, bytes route, (uint64 deadline,address creator,address prover,uint256 nativeAmount,(address token,uint256 amount)[] tokens) reward, bool allowPartial) payable returns (bytes32 intentHash, address vault)',
@@ -96,6 +105,16 @@ const allOf = (rules) => rules
96
105
  .map((rule) => ({ type: 'rule', rule }))
97
106
  .reduceRight((right, left) => ({ type: 'and', left, right }));
98
107
  const anyOf = (branches) => branches.reduce((left, right) => ({ type: 'or', left, right }));
108
+ const allOfExpressions = (parts) => parts.reduceRight((right, left) => ({ type: 'and', left, right }));
109
+ /**
110
+ * The same check on the same word; a usage-limited rule is never the same, as
111
+ * hoisted out of the leg OR it would count calls its branch never admits.
112
+ */
113
+ export const sameRule = (a, b) => a.usageLimit === undefined &&
114
+ b.usageLimit === undefined &&
115
+ a.condition === b.condition &&
116
+ a.calldataOffset === b.calldataOffset &&
117
+ BigInt(a.referenceValue) === BigInt(b.referenceValue);
99
118
  /** The publish call, pinned to the permit's destinations, provers and prices. */
100
119
  export function scopeEco(ctx) {
101
120
  if (ctx.sourceTokens.length !== 1) {
@@ -135,15 +154,9 @@ export function scopeEco(ctx) {
135
154
  pinValue(PUBLISH.routePointer, 0x80n),
136
155
  pinValue(PUBLISH.rewardPointer, 0x300n),
137
156
  pinValue(PUBLISH.allowPartial, 0n),
138
- pinValue(PUBLISH.routeLength, 0x260n),
139
- pinValue(PUBLISH.routeTuplePointer, 0x20n),
140
157
  pinValue(PUBLISH.routeNativeAmount, 0n),
141
- pinValue(PUBLISH.routeTokensPointer, 0xc0n),
142
- pinValue(PUBLISH.routeCallsPointer, 0x120n),
143
158
  pinValue(PUBLISH.routeTokensLength, 1n),
144
159
  pinValue(PUBLISH.callsLength, 1n),
145
- pinValue(PUBLISH.callPointer, 0x20n),
146
- pinValue(PUBLISH.callDataPointer, 0x60n),
147
160
  pinValue(PUBLISH.callValue, 0n),
148
161
  pinValue(PUBLISH.callDataLength, 0x44n),
149
162
  pin(PUBLISH.rewardCreator, ctx.account),
@@ -192,14 +205,31 @@ export function scopeEco(ctx) {
192
205
  referenceValue: floor,
193
206
  },
194
207
  ];
195
- // The prover OR nests inside its leg, so the rule count grows with legs
196
- // plus provers rather than their product.
197
- return {
198
- type: 'and',
199
- left: allOf(legRules),
200
- right: anyOf(provers.map((prover) => allOf([pin(PUBLISH.rewardProver, prover)]))),
201
- };
208
+ return { rules: legRules, provers };
202
209
  });
210
+ // What every leg pins moves out of the OR, stored once instead of per leg:
211
+ // (A and X) or (A and Y) is A and (X or Y).
212
+ const shared = legs[0].rules.filter((rule) => legs.every((leg) => leg.rules.some((other) => sameRule(other, rule))));
213
+ const sharedProvers = legs.every((leg) => leg.provers.length === legs[0].provers.length &&
214
+ leg.provers.every((prover, i) => prover === legs[0].provers[i]));
215
+ // The prover OR nests inside its leg, so the rule count grows with legs
216
+ // plus provers rather than their product.
217
+ const proverOr = (provers) => anyOf(provers.map((prover) => allOf([pin(PUBLISH.rewardProver, prover)])));
218
+ const branches = legs.map((leg) => {
219
+ const own = leg.rules.filter((rule) => !shared.some((other) => sameRule(other, rule)));
220
+ return [
221
+ ...(own.length ? [allOf(own)] : []),
222
+ ...(sharedProvers ? [] : [proverOr(leg.provers)]),
223
+ ];
224
+ });
225
+ const expression = [
226
+ allOf([...rules, ...shared]),
227
+ ...(sharedProvers ? [proverOr(legs[0].provers)] : []),
228
+ // A leg left with nothing of its own admits everything the others do.
229
+ ...(branches.some((branch) => branch.length === 0)
230
+ ? []
231
+ : [anyOf(branches.map(allOfExpressions))]),
232
+ ];
203
233
  return {
204
234
  target: ctx.target,
205
235
  selector: PUBLISH_AND_FUND_SELECTOR,
@@ -207,7 +237,7 @@ export function scopeEco(ctx) {
207
237
  {
208
238
  type: 'arg-policy',
209
239
  valueLimitPerUse: 0n,
210
- expression: { type: 'and', left: allOf(rules), right: anyOf(legs) },
240
+ expression: allOfExpressions(expression),
211
241
  },
212
242
  ...ctx.timeFrame,
213
243
  ],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rhinestone/sdk",
3
- "version": "0.0.0-dev-20261008124126",
3
+ "version": "0.0.0-dev-20261008125543",
4
4
  "description": "Smart wallets and multichain transactions for your application",
5
5
  "author": {
6
6
  "name": "Rhinestone",