@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.
- package/dist/src/clients/orchestrator/client.js +1 -1
- package/dist/src/modules/validators/smart-sessions/settlement/eco.d.ts +16 -2
- package/dist/src/modules/validators/smart-sessions/settlement/eco.d.ts.map +1 -1
- package/dist/src/modules/validators/smart-sessions/settlement/eco.js +45 -15
- package/package.json +1 -1
|
@@ -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-
|
|
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
|
|
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,
|
|
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
|
|
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
|
-
|
|
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:
|
|
240
|
+
expression: allOfExpressions(expression),
|
|
211
241
|
},
|
|
212
242
|
...ctx.timeFrame,
|
|
213
243
|
],
|