@solana-agent-wallet-adapter/cli 0.1.0 → 0.2.0
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/index.js +1122 -221
- package/dist/index.js.map +4 -4
- package/dist/wallet-host/assets/index-BF6JLAtr.js +3215 -0
- package/dist/wallet-host/assets/index-dftlursl.css +1 -0
- package/dist/wallet-host/assets/{mobile-wallet-adapter-CqDJSDZ5.js → mobile-wallet-adapter-B8zYDJwO.js} +1 -1
- package/dist/wallet-host/assets/solana-runtime-CsPLEN69.js +13 -0
- package/dist/wallet-host/assets/{wallet-standard-eoxEevjj.js → wallet-standard-CIBAN9Xp.js} +1 -1
- package/dist/wallet-host/index.html +5 -8
- package/dist/wallet-host/manifest.webmanifest +2 -13
- package/package.json +1 -1
- package/dist/wallet-host/assets/index-D5ySS2CU.js +0 -2143
- package/dist/wallet-host/assets/index-ZynMhs1G.css +0 -1
- package/dist/wallet-host/assets/solana-runtime-BhiDfU5_.js +0 -20
package/dist/index.js
CHANGED
|
@@ -6837,7 +6837,7 @@ var require_utils2 = __commonJS({
|
|
|
6837
6837
|
exports.u32 = u323;
|
|
6838
6838
|
exports.clean = clean3;
|
|
6839
6839
|
exports.createView = createView3;
|
|
6840
|
-
exports.rotr =
|
|
6840
|
+
exports.rotr = rotr3;
|
|
6841
6841
|
exports.rotl = rotl2;
|
|
6842
6842
|
exports.byteSwap = byteSwap2;
|
|
6843
6843
|
exports.byteSwap32 = byteSwap322;
|
|
@@ -6901,7 +6901,7 @@ var require_utils2 = __commonJS({
|
|
|
6901
6901
|
function createView3(arr) {
|
|
6902
6902
|
return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
|
|
6903
6903
|
}
|
|
6904
|
-
function
|
|
6904
|
+
function rotr3(word, shift) {
|
|
6905
6905
|
return word << 32 - shift | word >>> shift;
|
|
6906
6906
|
}
|
|
6907
6907
|
function rotl2(word, shift) {
|
|
@@ -7346,7 +7346,7 @@ var require_sha2 = __commonJS({
|
|
|
7346
7346
|
var _md_ts_1 = require_md();
|
|
7347
7347
|
var u64 = require_u64();
|
|
7348
7348
|
var utils_ts_1 = require_utils2();
|
|
7349
|
-
var
|
|
7349
|
+
var SHA256_K3 = /* @__PURE__ */ Uint32Array.from([
|
|
7350
7350
|
1116352408,
|
|
7351
7351
|
1899447441,
|
|
7352
7352
|
3049323471,
|
|
@@ -7453,7 +7453,7 @@ var require_sha2 = __commonJS({
|
|
|
7453
7453
|
let { A: A4, B: B3, C: C2, D: D3, E: E3, F: F3, G: G3, H: H5 } = this;
|
|
7454
7454
|
for (let i = 0; i < 64; i++) {
|
|
7455
7455
|
const sigma1 = (0, utils_ts_1.rotr)(E3, 6) ^ (0, utils_ts_1.rotr)(E3, 11) ^ (0, utils_ts_1.rotr)(E3, 25);
|
|
7456
|
-
const T1 = H5 + sigma1 + (0, _md_ts_1.Chi)(E3, F3, G3) +
|
|
7456
|
+
const T1 = H5 + sigma1 + (0, _md_ts_1.Chi)(E3, F3, G3) + SHA256_K3[i] + SHA256_W2[i] | 0;
|
|
7457
7457
|
const sigma0 = (0, utils_ts_1.rotr)(A4, 2) ^ (0, utils_ts_1.rotr)(A4, 13) ^ (0, utils_ts_1.rotr)(A4, 22);
|
|
7458
7458
|
const T22 = sigma0 + (0, _md_ts_1.Maj)(A4, B3, C2) | 0;
|
|
7459
7459
|
H5 = G3;
|
|
@@ -17286,7 +17286,7 @@ var require_dist2 = __commonJS({
|
|
|
17286
17286
|
function isNonArrayObject(x4) {
|
|
17287
17287
|
return isObject2(x4) && !Array.isArray(x4);
|
|
17288
17288
|
}
|
|
17289
|
-
function
|
|
17289
|
+
function isPlainObject4(x4) {
|
|
17290
17290
|
if (Object.prototype.toString.call(x4) !== "[object Object]") {
|
|
17291
17291
|
return false;
|
|
17292
17292
|
}
|
|
@@ -17926,7 +17926,7 @@ var require_dist2 = __commonJS({
|
|
|
17926
17926
|
if (x4 === void 0) {
|
|
17927
17927
|
return f;
|
|
17928
17928
|
}
|
|
17929
|
-
if (!options.strict &&
|
|
17929
|
+
if (!options.strict && isPlainObject4(x4) && isPlainObject4(f)) {
|
|
17930
17930
|
const ret = { ...x4 };
|
|
17931
17931
|
let changed = false;
|
|
17932
17932
|
for (const key in f) {
|
|
@@ -63624,6 +63624,901 @@ function sleep(ms) {
|
|
|
63624
63624
|
// ../mcp-server/dist/actionService.js
|
|
63625
63625
|
var import_web3 = __toESM(require_index_cjs(), 1);
|
|
63626
63626
|
|
|
63627
|
+
// ../workflow/dist/cadence.js
|
|
63628
|
+
function exhaustionReason(schedule, now) {
|
|
63629
|
+
if (schedule.maxOccurrences !== void 0 && (schedule.occurrencesCreated ?? 0) >= schedule.maxOccurrences) {
|
|
63630
|
+
return "max_occurrences";
|
|
63631
|
+
}
|
|
63632
|
+
if (schedule.expiresAt) {
|
|
63633
|
+
const expiry = new Date(schedule.expiresAt);
|
|
63634
|
+
if (!Number.isNaN(expiry.getTime()) && now.getTime() >= expiry.getTime()) {
|
|
63635
|
+
return "expired";
|
|
63636
|
+
}
|
|
63637
|
+
}
|
|
63638
|
+
return null;
|
|
63639
|
+
}
|
|
63640
|
+
function nextFutureOccurrence(schedule, now) {
|
|
63641
|
+
const startAt = recurringStartAt(schedule);
|
|
63642
|
+
if (!startAt)
|
|
63643
|
+
return null;
|
|
63644
|
+
const candidate = nextFutureByCadence(schedule, now, startAt);
|
|
63645
|
+
if (!candidate)
|
|
63646
|
+
return null;
|
|
63647
|
+
if (schedule.expiresAt) {
|
|
63648
|
+
const expiry = new Date(schedule.expiresAt);
|
|
63649
|
+
if (!Number.isNaN(expiry.getTime()) && candidate.dueAt.getTime() >= expiry.getTime()) {
|
|
63650
|
+
return null;
|
|
63651
|
+
}
|
|
63652
|
+
}
|
|
63653
|
+
return candidate;
|
|
63654
|
+
}
|
|
63655
|
+
function latestDueOccurrence(schedule, now) {
|
|
63656
|
+
const startAt = recurringStartAt(schedule);
|
|
63657
|
+
if (!startAt)
|
|
63658
|
+
return null;
|
|
63659
|
+
const candidate = latestDueByCadence(schedule, now, startAt);
|
|
63660
|
+
if (!candidate || candidate.dueAt.getTime() < startAt.getTime())
|
|
63661
|
+
return null;
|
|
63662
|
+
if (schedule.expiresAt) {
|
|
63663
|
+
const expiry = new Date(schedule.expiresAt);
|
|
63664
|
+
if (!Number.isNaN(expiry.getTime()) && candidate.dueAt.getTime() >= expiry.getTime()) {
|
|
63665
|
+
return null;
|
|
63666
|
+
}
|
|
63667
|
+
}
|
|
63668
|
+
return candidate;
|
|
63669
|
+
}
|
|
63670
|
+
function previewUpcoming(schedule, now, count) {
|
|
63671
|
+
if (count <= 0)
|
|
63672
|
+
return [];
|
|
63673
|
+
const results = [];
|
|
63674
|
+
let cursorNow = now;
|
|
63675
|
+
let occurrencesCreated = schedule.occurrencesCreated ?? 0;
|
|
63676
|
+
for (let i = 0; i < count; i += 1) {
|
|
63677
|
+
const probe = { ...schedule, occurrencesCreated };
|
|
63678
|
+
if (exhaustionReason(probe, cursorNow))
|
|
63679
|
+
break;
|
|
63680
|
+
const next = nextFutureOccurrence(probe, cursorNow);
|
|
63681
|
+
if (!next)
|
|
63682
|
+
break;
|
|
63683
|
+
results.push(next);
|
|
63684
|
+
occurrencesCreated += 1;
|
|
63685
|
+
cursorNow = new Date(next.dueAt.getTime());
|
|
63686
|
+
}
|
|
63687
|
+
return results;
|
|
63688
|
+
}
|
|
63689
|
+
function recurringStartAt(schedule) {
|
|
63690
|
+
const value = new Date(schedule.startAt ?? schedule.createdAt);
|
|
63691
|
+
return Number.isNaN(value.getTime()) ? null : value;
|
|
63692
|
+
}
|
|
63693
|
+
function parseLocalTime(value) {
|
|
63694
|
+
if (!value)
|
|
63695
|
+
return null;
|
|
63696
|
+
const [hourRaw, minuteRaw] = value.split(":");
|
|
63697
|
+
const hour = Number(hourRaw);
|
|
63698
|
+
const minute = Number(minuteRaw);
|
|
63699
|
+
if (!Number.isInteger(hour) || !Number.isInteger(minute) || hour < 0 || hour > 23 || minute < 0 || minute > 59) {
|
|
63700
|
+
return null;
|
|
63701
|
+
}
|
|
63702
|
+
return { hour, minute };
|
|
63703
|
+
}
|
|
63704
|
+
function clampedMonthlyDate(year, month, dayOfMonth, hour, minute) {
|
|
63705
|
+
const lastDay = new Date(year, month + 1, 0).getDate();
|
|
63706
|
+
return new Date(year, month, Math.min(dayOfMonth, lastDay), hour, minute, 0, 0);
|
|
63707
|
+
}
|
|
63708
|
+
function monthlyKey(date3) {
|
|
63709
|
+
const month = String(date3.getMonth() + 1).padStart(2, "0");
|
|
63710
|
+
const day = String(date3.getDate()).padStart(2, "0");
|
|
63711
|
+
return `${date3.getFullYear()}-${month}-${day}`;
|
|
63712
|
+
}
|
|
63713
|
+
function intervalKey(dueAt, cadence) {
|
|
63714
|
+
if (cadence === "interval_days")
|
|
63715
|
+
return monthlyKey(dueAt);
|
|
63716
|
+
return dueAt.toISOString();
|
|
63717
|
+
}
|
|
63718
|
+
function nextFutureByCadence(schedule, now, startAt) {
|
|
63719
|
+
switch (schedule.cadence) {
|
|
63720
|
+
case "weekly":
|
|
63721
|
+
return nextFutureWeekly(schedule, now, startAt);
|
|
63722
|
+
case "monthly":
|
|
63723
|
+
return nextFutureMonthly(schedule, now, startAt);
|
|
63724
|
+
case "interval_days":
|
|
63725
|
+
return nextFutureInterval(schedule, now, schedule.intervalDays, 24 * 60 * 60 * 1e3);
|
|
63726
|
+
case "interval_hours":
|
|
63727
|
+
return nextFutureInterval(schedule, now, schedule.intervalHours, 60 * 60 * 1e3);
|
|
63728
|
+
case "interval_minutes":
|
|
63729
|
+
return nextFutureInterval(schedule, now, schedule.intervalMinutes, 60 * 1e3);
|
|
63730
|
+
default:
|
|
63731
|
+
return assertNeverCadence(schedule.cadence);
|
|
63732
|
+
}
|
|
63733
|
+
}
|
|
63734
|
+
function latestDueByCadence(schedule, now, startAt) {
|
|
63735
|
+
switch (schedule.cadence) {
|
|
63736
|
+
case "weekly":
|
|
63737
|
+
return latestDueWeekly(schedule, now, startAt);
|
|
63738
|
+
case "monthly":
|
|
63739
|
+
return latestDueMonthly(schedule, now, startAt);
|
|
63740
|
+
case "interval_days":
|
|
63741
|
+
return latestDueInterval(schedule, now, schedule.intervalDays, 24 * 60 * 60 * 1e3);
|
|
63742
|
+
case "interval_hours":
|
|
63743
|
+
return latestDueInterval(schedule, now, schedule.intervalHours, 60 * 60 * 1e3);
|
|
63744
|
+
case "interval_minutes":
|
|
63745
|
+
return latestDueInterval(schedule, now, schedule.intervalMinutes, 60 * 1e3);
|
|
63746
|
+
default:
|
|
63747
|
+
return assertNeverCadence(schedule.cadence);
|
|
63748
|
+
}
|
|
63749
|
+
}
|
|
63750
|
+
function nextFutureWeekly(schedule, now, startAt) {
|
|
63751
|
+
const time3 = parseLocalTime(schedule.localTime);
|
|
63752
|
+
if (!time3)
|
|
63753
|
+
return null;
|
|
63754
|
+
if (!Number.isInteger(schedule.dayOfWeek) || schedule.dayOfWeek === void 0)
|
|
63755
|
+
return null;
|
|
63756
|
+
const candidate = new Date(now.getTime());
|
|
63757
|
+
candidate.setHours(time3.hour, time3.minute, 0, 0);
|
|
63758
|
+
const daysForward = (schedule.dayOfWeek - candidate.getDay() + 7) % 7;
|
|
63759
|
+
candidate.setDate(candidate.getDate() + daysForward);
|
|
63760
|
+
if (candidate.getTime() <= now.getTime()) {
|
|
63761
|
+
candidate.setDate(candidate.getDate() + 7);
|
|
63762
|
+
}
|
|
63763
|
+
while (candidate.getTime() < startAt.getTime()) {
|
|
63764
|
+
candidate.setDate(candidate.getDate() + 7);
|
|
63765
|
+
}
|
|
63766
|
+
return { dueAt: candidate, key: candidate.toISOString().slice(0, 10) };
|
|
63767
|
+
}
|
|
63768
|
+
function nextFutureMonthly(schedule, now, startAt) {
|
|
63769
|
+
const time3 = parseLocalTime(schedule.localTime);
|
|
63770
|
+
if (!time3)
|
|
63771
|
+
return null;
|
|
63772
|
+
if (!Number.isInteger(schedule.dayOfMonth) || schedule.dayOfMonth === void 0)
|
|
63773
|
+
return null;
|
|
63774
|
+
let candidate = clampedMonthlyDate(now.getFullYear(), now.getMonth(), schedule.dayOfMonth, time3.hour, time3.minute);
|
|
63775
|
+
if (candidate.getTime() <= now.getTime()) {
|
|
63776
|
+
candidate = clampedMonthlyDate(candidate.getFullYear(), candidate.getMonth() + 1, schedule.dayOfMonth, time3.hour, time3.minute);
|
|
63777
|
+
}
|
|
63778
|
+
while (candidate.getTime() < startAt.getTime()) {
|
|
63779
|
+
candidate = clampedMonthlyDate(candidate.getFullYear(), candidate.getMonth() + 1, schedule.dayOfMonth, time3.hour, time3.minute);
|
|
63780
|
+
}
|
|
63781
|
+
return { dueAt: candidate, key: monthlyKey(candidate) };
|
|
63782
|
+
}
|
|
63783
|
+
function nextFutureInterval(schedule, now, interval, intervalMs) {
|
|
63784
|
+
if (!Number.isInteger(interval) || interval === void 0 || interval < 1)
|
|
63785
|
+
return null;
|
|
63786
|
+
const anchor = recurringStartAt(schedule);
|
|
63787
|
+
if (!anchor)
|
|
63788
|
+
return null;
|
|
63789
|
+
const time3 = schedule.cadence === "interval_days" ? parseLocalTime(schedule.localTime) : null;
|
|
63790
|
+
const dueAt = new Date(anchor.getTime());
|
|
63791
|
+
if (time3)
|
|
63792
|
+
dueAt.setHours(time3.hour, time3.minute, 0, 0);
|
|
63793
|
+
const totalIntervalMs = interval * intervalMs;
|
|
63794
|
+
if (dueAt.getTime() > now.getTime()) {
|
|
63795
|
+
return { dueAt, key: intervalKey(dueAt, schedule.cadence) };
|
|
63796
|
+
}
|
|
63797
|
+
const elapsedMs = now.getTime() - dueAt.getTime();
|
|
63798
|
+
const intervalsToAdvance = Math.floor(elapsedMs / totalIntervalMs) + 1;
|
|
63799
|
+
dueAt.setTime(dueAt.getTime() + intervalsToAdvance * totalIntervalMs);
|
|
63800
|
+
return { dueAt, key: intervalKey(dueAt, schedule.cadence) };
|
|
63801
|
+
}
|
|
63802
|
+
function latestDueWeekly(schedule, now, startAt) {
|
|
63803
|
+
const time3 = parseLocalTime(schedule.localTime);
|
|
63804
|
+
if (!time3)
|
|
63805
|
+
return null;
|
|
63806
|
+
if (!Number.isInteger(schedule.dayOfWeek) || schedule.dayOfWeek === void 0)
|
|
63807
|
+
return null;
|
|
63808
|
+
const candidate = new Date(now.getTime());
|
|
63809
|
+
candidate.setHours(time3.hour, time3.minute, 0, 0);
|
|
63810
|
+
const daysBack = (candidate.getDay() - schedule.dayOfWeek + 7) % 7;
|
|
63811
|
+
candidate.setDate(candidate.getDate() - daysBack);
|
|
63812
|
+
if (candidate.getTime() < startAt.getTime()) {
|
|
63813
|
+
while (candidate.getTime() < startAt.getTime()) {
|
|
63814
|
+
candidate.setDate(candidate.getDate() + 7);
|
|
63815
|
+
}
|
|
63816
|
+
} else if (candidate.getTime() > now.getTime()) {
|
|
63817
|
+
candidate.setDate(candidate.getDate() - 7);
|
|
63818
|
+
}
|
|
63819
|
+
if (candidate.getTime() < startAt.getTime())
|
|
63820
|
+
return null;
|
|
63821
|
+
return { dueAt: candidate, key: candidate.toISOString().slice(0, 10) };
|
|
63822
|
+
}
|
|
63823
|
+
function latestDueMonthly(schedule, now, startAt) {
|
|
63824
|
+
const time3 = parseLocalTime(schedule.localTime);
|
|
63825
|
+
if (!time3)
|
|
63826
|
+
return null;
|
|
63827
|
+
if (!Number.isInteger(schedule.dayOfMonth) || schedule.dayOfMonth === void 0)
|
|
63828
|
+
return null;
|
|
63829
|
+
let candidate = clampedMonthlyDate(now.getFullYear(), now.getMonth(), schedule.dayOfMonth, time3.hour, time3.minute);
|
|
63830
|
+
if (candidate.getTime() > now.getTime()) {
|
|
63831
|
+
candidate = clampedMonthlyDate(candidate.getFullYear(), candidate.getMonth() - 1, schedule.dayOfMonth, time3.hour, time3.minute);
|
|
63832
|
+
}
|
|
63833
|
+
while (candidate.getTime() < startAt.getTime()) {
|
|
63834
|
+
candidate = clampedMonthlyDate(candidate.getFullYear(), candidate.getMonth() + 1, schedule.dayOfMonth, time3.hour, time3.minute);
|
|
63835
|
+
}
|
|
63836
|
+
return { dueAt: candidate, key: monthlyKey(candidate) };
|
|
63837
|
+
}
|
|
63838
|
+
function latestDueInterval(schedule, now, interval, intervalMs) {
|
|
63839
|
+
if (!Number.isInteger(interval) || interval === void 0 || interval < 1)
|
|
63840
|
+
return null;
|
|
63841
|
+
const anchor = recurringStartAt(schedule);
|
|
63842
|
+
if (!anchor)
|
|
63843
|
+
return null;
|
|
63844
|
+
const time3 = schedule.cadence === "interval_days" ? parseLocalTime(schedule.localTime) : null;
|
|
63845
|
+
const dueAt = new Date(anchor.getTime());
|
|
63846
|
+
if (time3)
|
|
63847
|
+
dueAt.setHours(time3.hour, time3.minute, 0, 0);
|
|
63848
|
+
const totalIntervalMs = interval * intervalMs;
|
|
63849
|
+
if (dueAt.getTime() > now.getTime()) {
|
|
63850
|
+
return { dueAt, key: intervalKey(dueAt, schedule.cadence) };
|
|
63851
|
+
}
|
|
63852
|
+
const elapsedMs = now.getTime() - dueAt.getTime();
|
|
63853
|
+
const intervalsElapsed = Math.floor(elapsedMs / totalIntervalMs);
|
|
63854
|
+
dueAt.setTime(dueAt.getTime() + intervalsElapsed * totalIntervalMs);
|
|
63855
|
+
return { dueAt, key: intervalKey(dueAt, schedule.cadence) };
|
|
63856
|
+
}
|
|
63857
|
+
function assertNeverCadence(cadence) {
|
|
63858
|
+
throw new Error(`Unhandled recurring cadence: ${String(cadence)}`);
|
|
63859
|
+
}
|
|
63860
|
+
var PREVIEW_CAP = 1e4;
|
|
63861
|
+
function lifetimeSpendEstimate(schedule, amount, now) {
|
|
63862
|
+
const isBounded = schedule.maxOccurrences !== void 0 || schedule.expiresAt !== void 0;
|
|
63863
|
+
const perWeek = formatRate(amount, runsPerWeek(schedule));
|
|
63864
|
+
const perMonth = formatRate(amount, runsPerMonth(schedule));
|
|
63865
|
+
if (!isBounded) {
|
|
63866
|
+
return { bounded: false, perWeek, perMonth };
|
|
63867
|
+
}
|
|
63868
|
+
const remaining = previewUpcoming(schedule, now, PREVIEW_CAP).length;
|
|
63869
|
+
const totalAmount = multiplyDecimalString(amount, remaining);
|
|
63870
|
+
return { bounded: true, totalRuns: remaining, totalAmount, perWeek, perMonth };
|
|
63871
|
+
}
|
|
63872
|
+
function runsPerWeek(schedule) {
|
|
63873
|
+
switch (schedule.cadence) {
|
|
63874
|
+
case "weekly":
|
|
63875
|
+
return 1;
|
|
63876
|
+
case "monthly":
|
|
63877
|
+
return 7 / 30.4375;
|
|
63878
|
+
case "interval_days":
|
|
63879
|
+
return schedule.intervalDays && schedule.intervalDays > 0 ? 7 / schedule.intervalDays : 0;
|
|
63880
|
+
case "interval_hours":
|
|
63881
|
+
return schedule.intervalHours && schedule.intervalHours > 0 ? 168 / schedule.intervalHours : 0;
|
|
63882
|
+
case "interval_minutes":
|
|
63883
|
+
return schedule.intervalMinutes && schedule.intervalMinutes > 0 ? 10080 / schedule.intervalMinutes : 0;
|
|
63884
|
+
default:
|
|
63885
|
+
return 0;
|
|
63886
|
+
}
|
|
63887
|
+
}
|
|
63888
|
+
function runsPerMonth(schedule) {
|
|
63889
|
+
switch (schedule.cadence) {
|
|
63890
|
+
case "weekly":
|
|
63891
|
+
return 30.4375 / 7;
|
|
63892
|
+
case "monthly":
|
|
63893
|
+
return 1;
|
|
63894
|
+
case "interval_days":
|
|
63895
|
+
return schedule.intervalDays && schedule.intervalDays > 0 ? 30.4375 / schedule.intervalDays : 0;
|
|
63896
|
+
case "interval_hours":
|
|
63897
|
+
return schedule.intervalHours && schedule.intervalHours > 0 ? 730.5 / schedule.intervalHours : 0;
|
|
63898
|
+
case "interval_minutes":
|
|
63899
|
+
return schedule.intervalMinutes && schedule.intervalMinutes > 0 ? 43830 / schedule.intervalMinutes : 0;
|
|
63900
|
+
default:
|
|
63901
|
+
return 0;
|
|
63902
|
+
}
|
|
63903
|
+
}
|
|
63904
|
+
function formatRate(amount, multiplier) {
|
|
63905
|
+
const value = Number(amount) * multiplier;
|
|
63906
|
+
if (!Number.isFinite(value))
|
|
63907
|
+
return "0";
|
|
63908
|
+
return value.toFixed(6).replace(/\.?0+$/, "");
|
|
63909
|
+
}
|
|
63910
|
+
function multiplyDecimalString(value, factor) {
|
|
63911
|
+
if (!Number.isInteger(factor) || factor < 0)
|
|
63912
|
+
return "0";
|
|
63913
|
+
if (factor === 0)
|
|
63914
|
+
return "0";
|
|
63915
|
+
const trimmed = value.trim();
|
|
63916
|
+
const match = /^(\d+)(?:\.(\d+))?$/.exec(trimmed);
|
|
63917
|
+
if (!match)
|
|
63918
|
+
return "0";
|
|
63919
|
+
const whole = match[1];
|
|
63920
|
+
const fraction = match[2] ?? "";
|
|
63921
|
+
const decimals = fraction.length;
|
|
63922
|
+
if (decimals === 0)
|
|
63923
|
+
return (BigInt(whole) * BigInt(factor)).toString();
|
|
63924
|
+
const raw = BigInt(whole + fraction) * BigInt(factor);
|
|
63925
|
+
const rawStr = raw.toString().padStart(decimals + 1, "0");
|
|
63926
|
+
const head = rawStr.slice(0, -decimals);
|
|
63927
|
+
const tail = rawStr.slice(-decimals).replace(/0+$/, "");
|
|
63928
|
+
return tail ? `${head}.${tail}` : head;
|
|
63929
|
+
}
|
|
63930
|
+
|
|
63931
|
+
// ../workflow/dist/index.js
|
|
63932
|
+
var WorkflowValidationError = class extends Error {
|
|
63933
|
+
code;
|
|
63934
|
+
path;
|
|
63935
|
+
constructor(code2, message, path) {
|
|
63936
|
+
super(message);
|
|
63937
|
+
this.code = code2;
|
|
63938
|
+
this.name = "WorkflowValidationError";
|
|
63939
|
+
this.path = path;
|
|
63940
|
+
}
|
|
63941
|
+
};
|
|
63942
|
+
function evaluatePlanGuardrails(input) {
|
|
63943
|
+
const plan = isPlainRecord(input.plan) ? input.plan : {};
|
|
63944
|
+
const parameters = normalizeStringRecord(input.parameters ?? valueRecord(plan.parameters));
|
|
63945
|
+
const fields = normalizePlanFields(input.fields ?? plan.fields);
|
|
63946
|
+
const source = stringValue(input.source) ?? stringValue(plan.source) ?? "template";
|
|
63947
|
+
const category = stringValue(input.category) ?? stringValue(plan.category) ?? "custom";
|
|
63948
|
+
const actionType = stringValue(input.actionType) ?? stringValue(plan.actionType) ?? "manual_review";
|
|
63949
|
+
const templateId = stringValue(input.templateId) ?? stringValue(plan.templateId) ?? "";
|
|
63950
|
+
const templateTitle = stringValue(input.templateTitle) ?? stringValue(plan.templateTitle) ?? "";
|
|
63951
|
+
const cluster = stringValue(input.cluster) ?? stringValue(plan.cluster) ?? "devnet";
|
|
63952
|
+
const userNotes = stringValue(input.userNotes) ?? stringValue(plan.userNotes) ?? "";
|
|
63953
|
+
const prompt2 = stringValue(input.prompt) ?? stringValue(plan.prompt) ?? "";
|
|
63954
|
+
const violations = [];
|
|
63955
|
+
collectForbiddenGuardrailViolations({
|
|
63956
|
+
value: {
|
|
63957
|
+
...plan,
|
|
63958
|
+
...input.prompt !== void 0 ? { prompt: prompt2 } : {},
|
|
63959
|
+
...input.userNotes !== void 0 ? { userNotes } : {}
|
|
63960
|
+
},
|
|
63961
|
+
path: "$.plan",
|
|
63962
|
+
violations
|
|
63963
|
+
});
|
|
63964
|
+
collectUnsafeAiClaimViolations({
|
|
63965
|
+
value: {
|
|
63966
|
+
intent: plan.intent,
|
|
63967
|
+
route: plan.route,
|
|
63968
|
+
risk: plan.risk,
|
|
63969
|
+
approval: plan.approval,
|
|
63970
|
+
safeguards: plan.safeguards,
|
|
63971
|
+
prompt: prompt2,
|
|
63972
|
+
userNotes,
|
|
63973
|
+
parameters,
|
|
63974
|
+
fields
|
|
63975
|
+
},
|
|
63976
|
+
path: "$.plan",
|
|
63977
|
+
source,
|
|
63978
|
+
violations
|
|
63979
|
+
});
|
|
63980
|
+
if (isQueueableWorkflowAction(actionType)) {
|
|
63981
|
+
collectMissingConstraintViolations(actionType, parameters, violations);
|
|
63982
|
+
}
|
|
63983
|
+
if (source === "ai") {
|
|
63984
|
+
collectAiWarningViolations(plan, actionType, parameters, violations);
|
|
63985
|
+
}
|
|
63986
|
+
const finalizationRequirement = finalizationRequirementForAction(actionType);
|
|
63987
|
+
const constraintSnapshot = planConstraintSnapshot({
|
|
63988
|
+
source,
|
|
63989
|
+
category,
|
|
63990
|
+
actionType,
|
|
63991
|
+
templateId,
|
|
63992
|
+
templateTitle,
|
|
63993
|
+
cluster,
|
|
63994
|
+
parameters,
|
|
63995
|
+
fields,
|
|
63996
|
+
userNotes
|
|
63997
|
+
});
|
|
63998
|
+
const constraintFingerprint = stableWorkflowFingerprint(constraintSnapshot);
|
|
63999
|
+
const constraintHash = stableWorkflowHash(constraintSnapshot);
|
|
64000
|
+
const verdict = violations.some((violation) => violation.severity === "block") ? "block" : violations.some((violation) => violation.severity === "warn") ? "warn" : "pass";
|
|
64001
|
+
return {
|
|
64002
|
+
verdict,
|
|
64003
|
+
source,
|
|
64004
|
+
actionType,
|
|
64005
|
+
finalizationRequirement,
|
|
64006
|
+
constraintFingerprint,
|
|
64007
|
+
constraintHash,
|
|
64008
|
+
violations,
|
|
64009
|
+
summary: guardrailSummary(verdict, finalizationRequirement, violations)
|
|
64010
|
+
};
|
|
64011
|
+
}
|
|
64012
|
+
function assertPlanGuardrails(input) {
|
|
64013
|
+
const report = evaluatePlanGuardrails(input);
|
|
64014
|
+
if (report.verdict === "block") {
|
|
64015
|
+
const first = report.violations.find((violation) => violation.severity === "block");
|
|
64016
|
+
throw new WorkflowValidationError("ai_guardrail_blocked", first?.message ?? "Plan is blocked by Agentic AI guardrails.", first?.path);
|
|
64017
|
+
}
|
|
64018
|
+
return report;
|
|
64019
|
+
}
|
|
64020
|
+
function planConstraintSnapshot(input) {
|
|
64021
|
+
return {
|
|
64022
|
+
source: input.source ?? "template",
|
|
64023
|
+
category: input.category ?? "custom",
|
|
64024
|
+
actionType: input.actionType ?? "manual_review",
|
|
64025
|
+
templateId: input.templateId ?? "",
|
|
64026
|
+
templateTitle: input.templateTitle ?? "",
|
|
64027
|
+
cluster: input.cluster ?? "devnet",
|
|
64028
|
+
parameters: normalizeStringRecord(input.parameters),
|
|
64029
|
+
fields: normalizePlanFields(input.fields),
|
|
64030
|
+
...input.userNotes ? { userNotes: input.userNotes } : {}
|
|
64031
|
+
};
|
|
64032
|
+
}
|
|
64033
|
+
function stableWorkflowFingerprint(value) {
|
|
64034
|
+
const serialized = stableJson(value);
|
|
64035
|
+
let hash = 2166136261;
|
|
64036
|
+
for (let index = 0; index < serialized.length; index += 1) {
|
|
64037
|
+
hash ^= serialized.charCodeAt(index);
|
|
64038
|
+
hash = Math.imul(hash, 16777619);
|
|
64039
|
+
}
|
|
64040
|
+
return `wf_${(hash >>> 0).toString(16).padStart(8, "0")}`;
|
|
64041
|
+
}
|
|
64042
|
+
function stableWorkflowHash(value) {
|
|
64043
|
+
return sha256Hex(stableJson(value));
|
|
64044
|
+
}
|
|
64045
|
+
function isQueueableWorkflowAction(actionType) {
|
|
64046
|
+
return actionType === "transfer_sol" || actionType === "transfer_spl" || actionType === "swap" || actionType === "recurring_payment";
|
|
64047
|
+
}
|
|
64048
|
+
function finalizationRequirementForAction(actionType) {
|
|
64049
|
+
if (actionType === "transfer_sol" || actionType === "transfer_spl" || actionType === "swap" || actionType === "custom_transaction") {
|
|
64050
|
+
return "transaction_preview";
|
|
64051
|
+
}
|
|
64052
|
+
if (actionType === "recurring_payment") {
|
|
64053
|
+
return "wallet_decision_proof";
|
|
64054
|
+
}
|
|
64055
|
+
if (actionType === "manual_review") {
|
|
64056
|
+
return "wallet_decision_proof";
|
|
64057
|
+
}
|
|
64058
|
+
return "none";
|
|
64059
|
+
}
|
|
64060
|
+
var FORBIDDEN_EXACT_KEYS = /* @__PURE__ */ new Set([
|
|
64061
|
+
"seedphrase",
|
|
64062
|
+
"recoveryphrase",
|
|
64063
|
+
"mnemonic",
|
|
64064
|
+
"privatekey",
|
|
64065
|
+
"secretkey",
|
|
64066
|
+
"delegatedsigner",
|
|
64067
|
+
"delegatesigner",
|
|
64068
|
+
"unlimitedapproval"
|
|
64069
|
+
]);
|
|
64070
|
+
function collectForbiddenGuardrailViolations(input) {
|
|
64071
|
+
if (!input.value || typeof input.value !== "object") {
|
|
64072
|
+
if (typeof input.value === "string") {
|
|
64073
|
+
collectForbiddenTextViolations(input.value, input.path, input.violations);
|
|
64074
|
+
}
|
|
64075
|
+
return;
|
|
64076
|
+
}
|
|
64077
|
+
if (Array.isArray(input.value)) {
|
|
64078
|
+
input.value.forEach((entry, index) => collectForbiddenGuardrailViolations({
|
|
64079
|
+
value: entry,
|
|
64080
|
+
path: `${input.path}[${index}]`,
|
|
64081
|
+
violations: input.violations
|
|
64082
|
+
}));
|
|
64083
|
+
return;
|
|
64084
|
+
}
|
|
64085
|
+
for (const [key, entry] of Object.entries(input.value)) {
|
|
64086
|
+
const normalized = key.replace(/[^a-z0-9]/gi, "").toLowerCase();
|
|
64087
|
+
const path = `${input.path}.${key}`;
|
|
64088
|
+
if (FORBIDDEN_EXACT_KEYS.has(normalized) || normalized.includes("privatekey") || normalized.includes("secretkey")) {
|
|
64089
|
+
input.violations.push({
|
|
64090
|
+
code: "forbidden_secret",
|
|
64091
|
+
severity: "block",
|
|
64092
|
+
message: `${path} is not accepted by Agentic workflow guardrails.`,
|
|
64093
|
+
path
|
|
64094
|
+
});
|
|
64095
|
+
}
|
|
64096
|
+
if ((normalized.includes("approvalauthority") || normalized.includes("signingauthority") || normalized.includes("authority")) && indicatesUnlimitedAuthority(entry)) {
|
|
64097
|
+
input.violations.push({
|
|
64098
|
+
code: "forbidden_authority",
|
|
64099
|
+
severity: "block",
|
|
64100
|
+
message: `${path} cannot grant unlimited approval authority.`,
|
|
64101
|
+
path
|
|
64102
|
+
});
|
|
64103
|
+
}
|
|
64104
|
+
collectForbiddenGuardrailViolations({ value: entry, path, violations: input.violations });
|
|
64105
|
+
}
|
|
64106
|
+
}
|
|
64107
|
+
function collectForbiddenTextViolations(text, path, violations) {
|
|
64108
|
+
const normalized = normalizeGuardrailText(text);
|
|
64109
|
+
const secretRequest = /\b(share|send|enter|paste|provide|export|store|upload|reveal|recover)\b.{0,60}\b(seed phrase|recovery phrase|mnemonic|private key|secret key)\b/.test(normalized) || /\b(seed phrase|recovery phrase|mnemonic|private key|secret key)\b.{0,60}\b(ai|agent|server|cloud|provider)\b/.test(normalized);
|
|
64110
|
+
if (secretRequest) {
|
|
64111
|
+
violations.push({
|
|
64112
|
+
code: "forbidden_secret_request",
|
|
64113
|
+
severity: "block",
|
|
64114
|
+
message: "Plans cannot request seed phrases, private keys, recovery phrases, or secret keys.",
|
|
64115
|
+
path
|
|
64116
|
+
});
|
|
64117
|
+
}
|
|
64118
|
+
const authorityRequest = /\b(grant|give|create|use|authorize|allow|enable)\b.{0,60}\b(delegated signer|delegate signer|server signer|unlimited approval|unrestricted authority|unlimited authority)\b/.test(normalized) || /\b(unlimited approval|unrestricted authority|server signer|delegated signer)\b/.test(normalized);
|
|
64119
|
+
if (authorityRequest && !/\b(no|never|without|cannot|must not|do not|reject|block|forbid|forbidden|disallow)\b.{0,60}\b(unlimited approval|unrestricted authority|server signer|delegated signer)\b/.test(normalized)) {
|
|
64120
|
+
violations.push({
|
|
64121
|
+
code: "forbidden_authority_request",
|
|
64122
|
+
severity: "block",
|
|
64123
|
+
message: "Plans cannot create delegated signers, server signers, or unlimited approval authority.",
|
|
64124
|
+
path
|
|
64125
|
+
});
|
|
64126
|
+
}
|
|
64127
|
+
}
|
|
64128
|
+
function collectUnsafeAiClaimViolations(input) {
|
|
64129
|
+
if (typeof input.value === "string") {
|
|
64130
|
+
if (input.source === "ai") {
|
|
64131
|
+
collectUnsafeAiTextClaims(input.value, input.path, input.violations);
|
|
64132
|
+
}
|
|
64133
|
+
return;
|
|
64134
|
+
}
|
|
64135
|
+
if (!input.value || typeof input.value !== "object")
|
|
64136
|
+
return;
|
|
64137
|
+
if (Array.isArray(input.value)) {
|
|
64138
|
+
input.value.forEach((entry, index) => collectUnsafeAiClaimViolations({
|
|
64139
|
+
value: entry,
|
|
64140
|
+
path: `${input.path}[${index}]`,
|
|
64141
|
+
source: input.source,
|
|
64142
|
+
violations: input.violations
|
|
64143
|
+
}));
|
|
64144
|
+
return;
|
|
64145
|
+
}
|
|
64146
|
+
for (const [key, entry] of Object.entries(input.value)) {
|
|
64147
|
+
collectUnsafeAiClaimViolations({
|
|
64148
|
+
value: entry,
|
|
64149
|
+
path: `${input.path}.${key}`,
|
|
64150
|
+
source: input.source,
|
|
64151
|
+
violations: input.violations
|
|
64152
|
+
});
|
|
64153
|
+
}
|
|
64154
|
+
}
|
|
64155
|
+
function collectUnsafeAiTextClaims(text, path, violations) {
|
|
64156
|
+
const normalized = normalizeGuardrailText(text);
|
|
64157
|
+
const claims = [
|
|
64158
|
+
{
|
|
64159
|
+
code: "ai_claims_approved",
|
|
64160
|
+
pattern: /\b(already|pre|auto)[-\s]?(approved|approval)\b|\bapproved automatically\b/,
|
|
64161
|
+
message: "AI drafts cannot claim that wallet approval has already happened."
|
|
64162
|
+
},
|
|
64163
|
+
{
|
|
64164
|
+
code: "ai_claims_signed",
|
|
64165
|
+
pattern: /\b(already|pre|auto)[-\s]?(signed|signing)\b|\bsigned automatically\b/,
|
|
64166
|
+
message: "AI drafts cannot claim that a wallet signature has already happened."
|
|
64167
|
+
},
|
|
64168
|
+
{
|
|
64169
|
+
code: "ai_claims_submitted",
|
|
64170
|
+
pattern: /\b(already|pre|auto)[-\s]?(submitted|executed|broadcast|sent)\b|\bsubmitted automatically\b/,
|
|
64171
|
+
message: "AI drafts cannot claim that a transaction has already been submitted or executed."
|
|
64172
|
+
},
|
|
64173
|
+
{
|
|
64174
|
+
code: "ai_bypasses_wallet",
|
|
64175
|
+
pattern: /\b(no|without|skip|bypass)\b.{0,40}\b(wallet|approval|signature|signing)\b|\bdoes not require\b.{0,40}\b(wallet|approval|signature|signing)\b/,
|
|
64176
|
+
message: "AI drafts cannot bypass wallet approval or signing."
|
|
64177
|
+
},
|
|
64178
|
+
{
|
|
64179
|
+
code: "ai_claims_safe",
|
|
64180
|
+
pattern: /\b(guaranteed safe|risk[-\s]?free|100%\s+safe|safe to sign|guaranteed profit|guaranteed return|cannot fail|fully reversible)\b/,
|
|
64181
|
+
message: "AI drafts cannot claim that a transaction is guaranteed safe, profitable, reversible, or risk-free."
|
|
64182
|
+
}
|
|
64183
|
+
];
|
|
64184
|
+
for (const claim of claims) {
|
|
64185
|
+
if (claim.pattern.test(normalized)) {
|
|
64186
|
+
violations.push({
|
|
64187
|
+
code: claim.code,
|
|
64188
|
+
severity: "block",
|
|
64189
|
+
message: claim.message,
|
|
64190
|
+
path
|
|
64191
|
+
});
|
|
64192
|
+
}
|
|
64193
|
+
}
|
|
64194
|
+
}
|
|
64195
|
+
function collectMissingConstraintViolations(actionType, parameters, violations) {
|
|
64196
|
+
const required2 = requiredConstraintGroups(actionType);
|
|
64197
|
+
for (const group of required2) {
|
|
64198
|
+
if (!group.keys.some((key) => hasStringParam(parameters, key))) {
|
|
64199
|
+
violations.push({
|
|
64200
|
+
code: "missing_executable_constraint",
|
|
64201
|
+
severity: "block",
|
|
64202
|
+
message: `${group.label} is required before this plan can enter Approval Inbox.`,
|
|
64203
|
+
path: `$.parameters.${group.keys[0]}`
|
|
64204
|
+
});
|
|
64205
|
+
}
|
|
64206
|
+
}
|
|
64207
|
+
const amount = firstPresentParam(parameters, ["amount", "amountSol", "inputAmount", "plannedAmount"]);
|
|
64208
|
+
if (amount !== void 0 && !(Number(amount) > 0)) {
|
|
64209
|
+
violations.push({
|
|
64210
|
+
code: "invalid_amount_constraint",
|
|
64211
|
+
severity: "block",
|
|
64212
|
+
message: "Amount must be a positive number before this plan can enter Approval Inbox.",
|
|
64213
|
+
path: "$.parameters.amount"
|
|
64214
|
+
});
|
|
64215
|
+
}
|
|
64216
|
+
}
|
|
64217
|
+
function collectAiWarningViolations(plan, actionType, parameters, violations) {
|
|
64218
|
+
for (const key of ["route", "risk", "approval"]) {
|
|
64219
|
+
const value = stringValue(plan[key]);
|
|
64220
|
+
if (!value || value.length < 12) {
|
|
64221
|
+
violations.push({
|
|
64222
|
+
code: "vague_ai_review_text",
|
|
64223
|
+
severity: "warn",
|
|
64224
|
+
message: `AI ${key} text should be explicit before review.`,
|
|
64225
|
+
path: `$.plan.${key}`
|
|
64226
|
+
});
|
|
64227
|
+
}
|
|
64228
|
+
}
|
|
64229
|
+
if (isQueueableWorkflowAction(actionType) && !firstPresentParam(parameters, ["memo", "note", "reason"])) {
|
|
64230
|
+
violations.push({
|
|
64231
|
+
code: "missing_context_note",
|
|
64232
|
+
severity: "warn",
|
|
64233
|
+
message: "A memo or reason is recommended for queueable AI plans.",
|
|
64234
|
+
path: "$.parameters.memo"
|
|
64235
|
+
});
|
|
64236
|
+
}
|
|
64237
|
+
}
|
|
64238
|
+
function requiredConstraintGroups(actionType) {
|
|
64239
|
+
if (actionType === "transfer_sol") {
|
|
64240
|
+
return [
|
|
64241
|
+
{ label: "Recipient", keys: ["recipient", "recipientAddress"] },
|
|
64242
|
+
{ label: "Amount", keys: ["amount", "amountSol"] }
|
|
64243
|
+
];
|
|
64244
|
+
}
|
|
64245
|
+
if (actionType === "transfer_spl") {
|
|
64246
|
+
return [
|
|
64247
|
+
{ label: "Token", keys: ["token"] },
|
|
64248
|
+
{ label: "Recipient", keys: ["recipient", "recipientAddress"] },
|
|
64249
|
+
{ label: "Amount", keys: ["amount"] }
|
|
64250
|
+
];
|
|
64251
|
+
}
|
|
64252
|
+
if (actionType === "swap") {
|
|
64253
|
+
return [
|
|
64254
|
+
{ label: "Input token", keys: ["inputToken"] },
|
|
64255
|
+
{ label: "Output token", keys: ["outputToken"] },
|
|
64256
|
+
{ label: "Amount", keys: ["amount", "inputAmount"] },
|
|
64257
|
+
{ label: "Slippage cap", keys: ["slippageBps"] }
|
|
64258
|
+
];
|
|
64259
|
+
}
|
|
64260
|
+
if (actionType === "recurring_payment") {
|
|
64261
|
+
return [
|
|
64262
|
+
{ label: "Token", keys: ["token"] },
|
|
64263
|
+
{ label: "Recipient", keys: ["recipient", "recipientAddress"] },
|
|
64264
|
+
{ label: "Amount", keys: ["amount"] },
|
|
64265
|
+
{ label: "Cadence", keys: ["cadence"] }
|
|
64266
|
+
];
|
|
64267
|
+
}
|
|
64268
|
+
return [];
|
|
64269
|
+
}
|
|
64270
|
+
function guardrailSummary(verdict, finalizationRequirement, violations) {
|
|
64271
|
+
if (verdict === "block") {
|
|
64272
|
+
return violations.find((violation) => violation.severity === "block")?.message ?? "Plan is blocked by guardrails.";
|
|
64273
|
+
}
|
|
64274
|
+
if (verdict === "warn") {
|
|
64275
|
+
return violations.find((violation) => violation.severity === "warn")?.message ?? "Plan has guardrail warnings.";
|
|
64276
|
+
}
|
|
64277
|
+
if (finalizationRequirement === "transaction_preview") {
|
|
64278
|
+
return "Plan passed guardrails and requires transaction preview before wallet approval.";
|
|
64279
|
+
}
|
|
64280
|
+
if (finalizationRequirement === "wallet_decision_proof") {
|
|
64281
|
+
return "Plan passed guardrails and requires explicit wallet decision proof.";
|
|
64282
|
+
}
|
|
64283
|
+
return "Plan passed guardrails.";
|
|
64284
|
+
}
|
|
64285
|
+
function normalizeGuardrailText(value) {
|
|
64286
|
+
return value.toLowerCase().replace(/\s+/g, " ").trim();
|
|
64287
|
+
}
|
|
64288
|
+
function hasStringParam(parameters, key) {
|
|
64289
|
+
return Boolean(parameters[key]?.trim());
|
|
64290
|
+
}
|
|
64291
|
+
function firstPresentParam(parameters, keys) {
|
|
64292
|
+
for (const key of keys) {
|
|
64293
|
+
const value = parameters[key]?.trim();
|
|
64294
|
+
if (value)
|
|
64295
|
+
return value;
|
|
64296
|
+
}
|
|
64297
|
+
return void 0;
|
|
64298
|
+
}
|
|
64299
|
+
function normalizeStringRecord(value) {
|
|
64300
|
+
if (!isPlainRecord(value))
|
|
64301
|
+
return {};
|
|
64302
|
+
const output = {};
|
|
64303
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
64304
|
+
if (typeof entry === "string")
|
|
64305
|
+
output[key] = entry;
|
|
64306
|
+
}
|
|
64307
|
+
return output;
|
|
64308
|
+
}
|
|
64309
|
+
function normalizePlanFields(value) {
|
|
64310
|
+
if (!Array.isArray(value))
|
|
64311
|
+
return [];
|
|
64312
|
+
return value.filter((entry) => {
|
|
64313
|
+
return Boolean(isPlainRecord(entry) && typeof entry.label === "string" && typeof entry.value === "string");
|
|
64314
|
+
}).map((entry) => ({ label: entry.label, value: entry.value }));
|
|
64315
|
+
}
|
|
64316
|
+
function valueRecord(value) {
|
|
64317
|
+
return isPlainRecord(value) ? value : void 0;
|
|
64318
|
+
}
|
|
64319
|
+
function stringValue(value) {
|
|
64320
|
+
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
64321
|
+
}
|
|
64322
|
+
function isPlainRecord(input) {
|
|
64323
|
+
return isPlainObject2(input);
|
|
64324
|
+
}
|
|
64325
|
+
function stableJson(value) {
|
|
64326
|
+
return JSON.stringify(sortJson(value));
|
|
64327
|
+
}
|
|
64328
|
+
var SHA256_K = [
|
|
64329
|
+
1116352408,
|
|
64330
|
+
1899447441,
|
|
64331
|
+
3049323471,
|
|
64332
|
+
3921009573,
|
|
64333
|
+
961987163,
|
|
64334
|
+
1508970993,
|
|
64335
|
+
2453635748,
|
|
64336
|
+
2870763221,
|
|
64337
|
+
3624381080,
|
|
64338
|
+
310598401,
|
|
64339
|
+
607225278,
|
|
64340
|
+
1426881987,
|
|
64341
|
+
1925078388,
|
|
64342
|
+
2162078206,
|
|
64343
|
+
2614888103,
|
|
64344
|
+
3248222580,
|
|
64345
|
+
3835390401,
|
|
64346
|
+
4022224774,
|
|
64347
|
+
264347078,
|
|
64348
|
+
604807628,
|
|
64349
|
+
770255983,
|
|
64350
|
+
1249150122,
|
|
64351
|
+
1555081692,
|
|
64352
|
+
1996064986,
|
|
64353
|
+
2554220882,
|
|
64354
|
+
2821834349,
|
|
64355
|
+
2952996808,
|
|
64356
|
+
3210313671,
|
|
64357
|
+
3336571891,
|
|
64358
|
+
3584528711,
|
|
64359
|
+
113926993,
|
|
64360
|
+
338241895,
|
|
64361
|
+
666307205,
|
|
64362
|
+
773529912,
|
|
64363
|
+
1294757372,
|
|
64364
|
+
1396182291,
|
|
64365
|
+
1695183700,
|
|
64366
|
+
1986661051,
|
|
64367
|
+
2177026350,
|
|
64368
|
+
2456956037,
|
|
64369
|
+
2730485921,
|
|
64370
|
+
2820302411,
|
|
64371
|
+
3259730800,
|
|
64372
|
+
3345764771,
|
|
64373
|
+
3516065817,
|
|
64374
|
+
3600352804,
|
|
64375
|
+
4094571909,
|
|
64376
|
+
275423344,
|
|
64377
|
+
430227734,
|
|
64378
|
+
506948616,
|
|
64379
|
+
659060556,
|
|
64380
|
+
883997877,
|
|
64381
|
+
958139571,
|
|
64382
|
+
1322822218,
|
|
64383
|
+
1537002063,
|
|
64384
|
+
1747873779,
|
|
64385
|
+
1955562222,
|
|
64386
|
+
2024104815,
|
|
64387
|
+
2227730452,
|
|
64388
|
+
2361852424,
|
|
64389
|
+
2428436474,
|
|
64390
|
+
2756734187,
|
|
64391
|
+
3204031479,
|
|
64392
|
+
3329325298
|
|
64393
|
+
];
|
|
64394
|
+
function sha256Hex(value) {
|
|
64395
|
+
const bytes = utf8Bytes(value);
|
|
64396
|
+
const bitLength = bytes.length * 8;
|
|
64397
|
+
bytes.push(128);
|
|
64398
|
+
while (bytes.length % 64 !== 56)
|
|
64399
|
+
bytes.push(0);
|
|
64400
|
+
const high = Math.floor(bitLength / 4294967296);
|
|
64401
|
+
const low = bitLength >>> 0;
|
|
64402
|
+
for (const word of [high, low]) {
|
|
64403
|
+
bytes.push(word >>> 24 & 255, word >>> 16 & 255, word >>> 8 & 255, word & 255);
|
|
64404
|
+
}
|
|
64405
|
+
let h0 = 1779033703;
|
|
64406
|
+
let h1 = 3144134277;
|
|
64407
|
+
let h2 = 1013904242;
|
|
64408
|
+
let h3 = 2773480762;
|
|
64409
|
+
let h4 = 1359893119;
|
|
64410
|
+
let h5 = 2600822924;
|
|
64411
|
+
let h6 = 528734635;
|
|
64412
|
+
let h7 = 1541459225;
|
|
64413
|
+
const w3 = new Array(64);
|
|
64414
|
+
for (let offset = 0; offset < bytes.length; offset += 64) {
|
|
64415
|
+
for (let i = 0; i < 16; i += 1) {
|
|
64416
|
+
const index = offset + i * 4;
|
|
64417
|
+
w3[i] = (bytes[index] ?? 0) << 24 | (bytes[index + 1] ?? 0) << 16 | (bytes[index + 2] ?? 0) << 8 | (bytes[index + 3] ?? 0);
|
|
64418
|
+
}
|
|
64419
|
+
for (let i = 16; i < 64; i += 1) {
|
|
64420
|
+
const s0 = rotr(w3[i - 15], 7) ^ rotr(w3[i - 15], 18) ^ w3[i - 15] >>> 3;
|
|
64421
|
+
const s1 = rotr(w3[i - 2], 17) ^ rotr(w3[i - 2], 19) ^ w3[i - 2] >>> 10;
|
|
64422
|
+
w3[i] = w3[i - 16] + s0 + w3[i - 7] + s1 >>> 0;
|
|
64423
|
+
}
|
|
64424
|
+
let a = h0;
|
|
64425
|
+
let b3 = h1;
|
|
64426
|
+
let c = h2;
|
|
64427
|
+
let d = h3;
|
|
64428
|
+
let e = h4;
|
|
64429
|
+
let f = h5;
|
|
64430
|
+
let g2 = h6;
|
|
64431
|
+
let h = h7;
|
|
64432
|
+
for (let i = 0; i < 64; i += 1) {
|
|
64433
|
+
const s1 = rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25);
|
|
64434
|
+
const ch = e & f ^ ~e & g2;
|
|
64435
|
+
const temp1 = h + s1 + ch + SHA256_K[i] + w3[i] >>> 0;
|
|
64436
|
+
const s0 = rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22);
|
|
64437
|
+
const maj = a & b3 ^ a & c ^ b3 & c;
|
|
64438
|
+
const temp2 = s0 + maj >>> 0;
|
|
64439
|
+
h = g2;
|
|
64440
|
+
g2 = f;
|
|
64441
|
+
f = e;
|
|
64442
|
+
e = d + temp1 >>> 0;
|
|
64443
|
+
d = c;
|
|
64444
|
+
c = b3;
|
|
64445
|
+
b3 = a;
|
|
64446
|
+
a = temp1 + temp2 >>> 0;
|
|
64447
|
+
}
|
|
64448
|
+
h0 = h0 + a >>> 0;
|
|
64449
|
+
h1 = h1 + b3 >>> 0;
|
|
64450
|
+
h2 = h2 + c >>> 0;
|
|
64451
|
+
h3 = h3 + d >>> 0;
|
|
64452
|
+
h4 = h4 + e >>> 0;
|
|
64453
|
+
h5 = h5 + f >>> 0;
|
|
64454
|
+
h6 = h6 + g2 >>> 0;
|
|
64455
|
+
h7 = h7 + h >>> 0;
|
|
64456
|
+
}
|
|
64457
|
+
return [h0, h1, h2, h3, h4, h5, h6, h7].map((word) => word.toString(16).padStart(8, "0")).join("");
|
|
64458
|
+
}
|
|
64459
|
+
function rotr(value, bits) {
|
|
64460
|
+
return value >>> bits | value << 32 - bits;
|
|
64461
|
+
}
|
|
64462
|
+
function utf8Bytes(value) {
|
|
64463
|
+
const bytes = [];
|
|
64464
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
64465
|
+
let codePoint = value.charCodeAt(index);
|
|
64466
|
+
if (codePoint >= 55296 && codePoint <= 56319) {
|
|
64467
|
+
const next = value.charCodeAt(index + 1);
|
|
64468
|
+
if (next >= 56320 && next <= 57343) {
|
|
64469
|
+
codePoint = 65536 + (codePoint - 55296 << 10) + (next - 56320);
|
|
64470
|
+
index += 1;
|
|
64471
|
+
} else {
|
|
64472
|
+
codePoint = 65533;
|
|
64473
|
+
}
|
|
64474
|
+
} else if (codePoint >= 56320 && codePoint <= 57343) {
|
|
64475
|
+
codePoint = 65533;
|
|
64476
|
+
}
|
|
64477
|
+
if (codePoint < 128) {
|
|
64478
|
+
bytes.push(codePoint);
|
|
64479
|
+
} else if (codePoint < 2048) {
|
|
64480
|
+
bytes.push(192 | codePoint >> 6, 128 | codePoint & 63);
|
|
64481
|
+
} else if (codePoint < 65536) {
|
|
64482
|
+
bytes.push(224 | codePoint >> 12, 128 | codePoint >> 6 & 63, 128 | codePoint & 63);
|
|
64483
|
+
} else {
|
|
64484
|
+
bytes.push(240 | codePoint >> 18, 128 | codePoint >> 12 & 63, 128 | codePoint >> 6 & 63, 128 | codePoint & 63);
|
|
64485
|
+
}
|
|
64486
|
+
}
|
|
64487
|
+
return bytes;
|
|
64488
|
+
}
|
|
64489
|
+
function sortJson(value) {
|
|
64490
|
+
if (Array.isArray(value)) {
|
|
64491
|
+
return value.map(sortJson);
|
|
64492
|
+
}
|
|
64493
|
+
if (value && typeof value === "object") {
|
|
64494
|
+
const output = {};
|
|
64495
|
+
for (const key of Object.keys(value).sort()) {
|
|
64496
|
+
const entry = value[key];
|
|
64497
|
+
if (entry !== void 0)
|
|
64498
|
+
output[key] = sortJson(entry);
|
|
64499
|
+
}
|
|
64500
|
+
return output;
|
|
64501
|
+
}
|
|
64502
|
+
return value;
|
|
64503
|
+
}
|
|
64504
|
+
function indicatesUnlimitedAuthority(value) {
|
|
64505
|
+
if (value === true)
|
|
64506
|
+
return true;
|
|
64507
|
+
if (typeof value === "string") {
|
|
64508
|
+
const normalized = value.toLowerCase();
|
|
64509
|
+
return normalized.includes("unlimited") || normalized.includes("delegate") || normalized.includes("any amount");
|
|
64510
|
+
}
|
|
64511
|
+
if (typeof value === "number")
|
|
64512
|
+
return !Number.isFinite(value);
|
|
64513
|
+
return false;
|
|
64514
|
+
}
|
|
64515
|
+
function isPlainObject2(input) {
|
|
64516
|
+
if (typeof input !== "object" || input === null || Array.isArray(input))
|
|
64517
|
+
return false;
|
|
64518
|
+
const prototype = Object.getPrototypeOf(input);
|
|
64519
|
+
return prototype === Object.prototype || prototype === null;
|
|
64520
|
+
}
|
|
64521
|
+
|
|
63627
64522
|
// ../mcp-server/dist/amounts.js
|
|
63628
64523
|
function parseDecimalAmount(value, decimals, label) {
|
|
63629
64524
|
const trimmed = value.trim();
|
|
@@ -63709,7 +64604,8 @@ function normalizeConfig(input) {
|
|
|
63709
64604
|
...DEFAULT_CONFIG.jupiter,
|
|
63710
64605
|
...input.jupiter ?? {}
|
|
63711
64606
|
};
|
|
63712
|
-
|
|
64607
|
+
const recurring = input.recurring;
|
|
64608
|
+
return { cluster, rpcUrl, mainnet, tokens, jupiter, ...recurring !== void 0 && { recurring } };
|
|
63713
64609
|
}
|
|
63714
64610
|
function requireMainnetEnabled(config2) {
|
|
63715
64611
|
if (config2.cluster === "mainnet-beta" && !config2.mainnet.enabled) {
|
|
@@ -64193,6 +65089,21 @@ function buildRecurringPaymentInput(input, walletAddress, config2) {
|
|
|
64193
65089
|
const rawAmount = parseDecimalAmount(amount, tokenConfig.decimals, `${tokenConfig.symbol} recurring payment amount`);
|
|
64194
65090
|
assertMaxAmount(rawAmount, tokenConfig.maxTransfer, tokenConfig.decimals, `${tokenConfig.symbol} recurring payment amount`);
|
|
64195
65091
|
}
|
|
65092
|
+
const expiresAt = normalizeExpiresAt(input.expiresAt);
|
|
65093
|
+
const notifications = normalizeNotifications(input.notifications);
|
|
65094
|
+
enforceRecurringPolicy(config2.recurring, token, amount, {
|
|
65095
|
+
cadence: schedule.cadence,
|
|
65096
|
+
dayOfWeek: schedule.dayOfWeek,
|
|
65097
|
+
dayOfMonth: schedule.dayOfMonth,
|
|
65098
|
+
intervalDays: schedule.intervalDays,
|
|
65099
|
+
intervalHours: schedule.intervalHours,
|
|
65100
|
+
intervalMinutes: schedule.intervalMinutes,
|
|
65101
|
+
localTime: schedule.localTime,
|
|
65102
|
+
startAt: schedule.startAt,
|
|
65103
|
+
maxOccurrences: schedule.maxOccurrences,
|
|
65104
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
65105
|
+
expiresAt
|
|
65106
|
+
});
|
|
64196
65107
|
return {
|
|
64197
65108
|
walletAddress,
|
|
64198
65109
|
cluster: config2.cluster,
|
|
@@ -64200,9 +65111,83 @@ function buildRecurringPaymentInput(input, walletAddress, config2) {
|
|
|
64200
65111
|
recipient,
|
|
64201
65112
|
amount,
|
|
64202
65113
|
...schedule,
|
|
64203
|
-
...note !== void 0 && { note }
|
|
65114
|
+
...note !== void 0 && { note },
|
|
65115
|
+
...expiresAt !== void 0 && { expiresAt },
|
|
65116
|
+
...notifications !== void 0 && { notifications }
|
|
64204
65117
|
};
|
|
64205
65118
|
}
|
|
65119
|
+
function enforceRecurringPolicy(policy, token, amount, cadenceFields) {
|
|
65120
|
+
if (!policy)
|
|
65121
|
+
return;
|
|
65122
|
+
const lifetime = policy.maxLifetimeAmount?.[token];
|
|
65123
|
+
const perWeek = policy.maxPerWeekAmount?.[token];
|
|
65124
|
+
const perMonth = policy.maxPerMonthAmount?.[token];
|
|
65125
|
+
if (!lifetime && !perWeek && !perMonth)
|
|
65126
|
+
return;
|
|
65127
|
+
const estimate = lifetimeSpendEstimate(cadenceFields, amount, /* @__PURE__ */ new Date());
|
|
65128
|
+
if (lifetime && estimate.bounded && estimate.totalAmount && compareDecimal(estimate.totalAmount, lifetime) > 0) {
|
|
65129
|
+
throw new ProtocolError("invalid_request", `This schedule would spend up to ${estimate.totalAmount} ${token} total, exceeding your configured lifetime cap of ${lifetime} ${token}.`);
|
|
65130
|
+
}
|
|
65131
|
+
if (perWeek && compareDecimal(estimate.perWeek, perWeek) > 0) {
|
|
65132
|
+
throw new ProtocolError("invalid_request", `This schedule would spend up to ${estimate.perWeek} ${token} per week, exceeding your configured cap of ${perWeek} ${token} per week.`);
|
|
65133
|
+
}
|
|
65134
|
+
if (perMonth && compareDecimal(estimate.perMonth, perMonth) > 0) {
|
|
65135
|
+
throw new ProtocolError("invalid_request", `This schedule would spend up to ${estimate.perMonth} ${token} per month, exceeding your configured cap of ${perMonth} ${token} per month.`);
|
|
65136
|
+
}
|
|
65137
|
+
}
|
|
65138
|
+
function compareDecimal(left, right) {
|
|
65139
|
+
const a = Number(left);
|
|
65140
|
+
const b3 = Number(right);
|
|
65141
|
+
if (!Number.isFinite(a) || !Number.isFinite(b3))
|
|
65142
|
+
return 0;
|
|
65143
|
+
if (a < b3)
|
|
65144
|
+
return -1;
|
|
65145
|
+
if (a > b3)
|
|
65146
|
+
return 1;
|
|
65147
|
+
return 0;
|
|
65148
|
+
}
|
|
65149
|
+
function normalizeNotifications(value) {
|
|
65150
|
+
if (value === void 0 || value === null)
|
|
65151
|
+
return void 0;
|
|
65152
|
+
if (typeof value !== "object" || Array.isArray(value)) {
|
|
65153
|
+
throw new ProtocolError("invalid_request", "notifications must be an object.");
|
|
65154
|
+
}
|
|
65155
|
+
const obj = value;
|
|
65156
|
+
const result = {};
|
|
65157
|
+
if (obj.inApp !== void 0) {
|
|
65158
|
+
if (typeof obj.inApp !== "boolean") {
|
|
65159
|
+
throw new ProtocolError("invalid_request", "notifications.inApp must be a boolean.");
|
|
65160
|
+
}
|
|
65161
|
+
result.inApp = obj.inApp;
|
|
65162
|
+
}
|
|
65163
|
+
if (obj.webhookUrl !== void 0 && obj.webhookUrl !== null && obj.webhookUrl !== "") {
|
|
65164
|
+
if (typeof obj.webhookUrl !== "string") {
|
|
65165
|
+
throw new ProtocolError("invalid_request", "notifications.webhookUrl must be a string.");
|
|
65166
|
+
}
|
|
65167
|
+
try {
|
|
65168
|
+
const parsed = new URL(obj.webhookUrl);
|
|
65169
|
+
if (parsed.protocol !== "https:" && parsed.protocol !== "http:")
|
|
65170
|
+
throw new Error("protocol");
|
|
65171
|
+
} catch {
|
|
65172
|
+
throw new ProtocolError("invalid_request", "notifications.webhookUrl must be a valid http(s) URL.");
|
|
65173
|
+
}
|
|
65174
|
+
result.webhookUrl = obj.webhookUrl;
|
|
65175
|
+
}
|
|
65176
|
+
return Object.keys(result).length > 0 ? result : void 0;
|
|
65177
|
+
}
|
|
65178
|
+
function normalizeExpiresAt(value) {
|
|
65179
|
+
if (value === void 0 || value === null || value === "")
|
|
65180
|
+
return void 0;
|
|
65181
|
+
if (typeof value !== "string") {
|
|
65182
|
+
throw new ProtocolError("invalid_request", "expiresAt must be an ISO timestamp string.");
|
|
65183
|
+
}
|
|
65184
|
+
const trimmed = value.trim();
|
|
65185
|
+
const parsed = new Date(trimmed);
|
|
65186
|
+
if (Number.isNaN(parsed.getTime())) {
|
|
65187
|
+
throw new ProtocolError("invalid_request", "expiresAt must be a valid ISO timestamp.");
|
|
65188
|
+
}
|
|
65189
|
+
return trimmed;
|
|
65190
|
+
}
|
|
64206
65191
|
function normalizeRecurringSchedule(input) {
|
|
64207
65192
|
if (input.maxOccurrences !== void 0 && (!Number.isInteger(input.maxOccurrences) || input.maxOccurrences < 1)) {
|
|
64208
65193
|
throw new ProtocolError("invalid_request", "maxOccurrences must be a positive integer when provided.");
|
|
@@ -64542,10 +65527,13 @@ var JsonPreparedActionStore = class {
|
|
|
64542
65527
|
}
|
|
64543
65528
|
async listRecurringPaymentViews(now = /* @__PURE__ */ new Date()) {
|
|
64544
65529
|
const state = await this.read();
|
|
64545
|
-
return state.recurringPayments.map((payment) =>
|
|
64546
|
-
|
|
64547
|
-
|
|
64548
|
-
|
|
65530
|
+
return state.recurringPayments.map((payment) => {
|
|
65531
|
+
const nextDueAt = nextRecurringDueAt(payment, now);
|
|
65532
|
+
return {
|
|
65533
|
+
...payment,
|
|
65534
|
+
...nextDueAt ? { nextDueAt } : {}
|
|
65535
|
+
};
|
|
65536
|
+
}).sort((left, right) => {
|
|
64549
65537
|
const leftDue = left.nextDueAt ?? "9999-12-31T23:59:59.999Z";
|
|
64550
65538
|
const rightDue = right.nextDueAt ?? "9999-12-31T23:59:59.999Z";
|
|
64551
65539
|
return leftDue.localeCompare(rightDue);
|
|
@@ -64587,7 +65575,13 @@ var JsonPreparedActionStore = class {
|
|
|
64587
65575
|
if (payment.maxOccurrences !== void 0 && (payment.occurrencesCreated ?? 0) >= payment.maxOccurrences) {
|
|
64588
65576
|
continue;
|
|
64589
65577
|
}
|
|
64590
|
-
|
|
65578
|
+
if (payment.expiresAt) {
|
|
65579
|
+
const expiry = new Date(payment.expiresAt);
|
|
65580
|
+
if (!Number.isNaN(expiry.getTime()) && now.getTime() >= expiry.getTime()) {
|
|
65581
|
+
continue;
|
|
65582
|
+
}
|
|
65583
|
+
}
|
|
65584
|
+
const occurrence = latestDueOccurrence(payment, now);
|
|
64591
65585
|
if (!occurrence || occurrence.dueAt.getTime() > now.getTime())
|
|
64592
65586
|
continue;
|
|
64593
65587
|
const exists = state.actions.some((action2) => action2.recurringId === payment.id && action2.occurrenceKey === occurrence.key);
|
|
@@ -64679,105 +65673,13 @@ function normalizePreparedAction(action) {
|
|
|
64679
65673
|
}
|
|
64680
65674
|
};
|
|
64681
65675
|
}
|
|
64682
|
-
function
|
|
64683
|
-
const startAt = recurringStartAt(payment);
|
|
64684
|
-
if (!startAt) {
|
|
64685
|
-
return null;
|
|
64686
|
-
}
|
|
64687
|
-
let occurrence;
|
|
64688
|
-
switch (payment.cadence) {
|
|
64689
|
-
case "weekly":
|
|
64690
|
-
occurrence = latestWeeklyOccurrence(payment, now);
|
|
64691
|
-
break;
|
|
64692
|
-
case "monthly":
|
|
64693
|
-
occurrence = latestMonthlyOccurrence(payment, now);
|
|
64694
|
-
break;
|
|
64695
|
-
case "interval_days":
|
|
64696
|
-
occurrence = latestIntervalOccurrence(payment, now, payment.intervalDays, 24 * 60 * 60 * 1e3);
|
|
64697
|
-
break;
|
|
64698
|
-
case "interval_hours":
|
|
64699
|
-
occurrence = latestIntervalOccurrence(payment, now, payment.intervalHours, 60 * 60 * 1e3);
|
|
64700
|
-
break;
|
|
64701
|
-
case "interval_minutes":
|
|
64702
|
-
occurrence = latestIntervalOccurrence(payment, now, payment.intervalMinutes, 60 * 1e3);
|
|
64703
|
-
break;
|
|
64704
|
-
}
|
|
64705
|
-
if (!occurrence || occurrence.dueAt.getTime() < startAt.getTime()) {
|
|
64706
|
-
return null;
|
|
64707
|
-
}
|
|
64708
|
-
return occurrence;
|
|
64709
|
-
}
|
|
64710
|
-
function nextRecurringOccurrence(payment, now) {
|
|
64711
|
-
const startAt = recurringStartAt(payment);
|
|
64712
|
-
if (!startAt)
|
|
64713
|
-
return null;
|
|
65676
|
+
function nextRecurringDueAt(payment, now = /* @__PURE__ */ new Date()) {
|
|
64714
65677
|
if (payment.status !== "active")
|
|
64715
65678
|
return null;
|
|
64716
65679
|
if (payment.maxOccurrences !== void 0 && (payment.occurrencesCreated ?? 0) >= payment.maxOccurrences) {
|
|
64717
65680
|
return null;
|
|
64718
65681
|
}
|
|
64719
|
-
|
|
64720
|
-
case "weekly":
|
|
64721
|
-
return nextWeeklyOccurrence(payment, now, startAt);
|
|
64722
|
-
case "monthly":
|
|
64723
|
-
return nextMonthlyOccurrence(payment, now, startAt);
|
|
64724
|
-
case "interval_days":
|
|
64725
|
-
return nextIntervalOccurrence(payment, now, payment.intervalDays, 24 * 60 * 60 * 1e3);
|
|
64726
|
-
case "interval_hours":
|
|
64727
|
-
return nextIntervalOccurrence(payment, now, payment.intervalHours, 60 * 60 * 1e3);
|
|
64728
|
-
case "interval_minutes":
|
|
64729
|
-
return nextIntervalOccurrence(payment, now, payment.intervalMinutes, 60 * 1e3);
|
|
64730
|
-
}
|
|
64731
|
-
}
|
|
64732
|
-
function nextWeeklyOccurrence(payment, now, startAt) {
|
|
64733
|
-
if (!payment.localTime || !Number.isInteger(payment.dayOfWeek) || payment.dayOfWeek === void 0)
|
|
64734
|
-
return null;
|
|
64735
|
-
const time3 = parseLocalTime(payment.localTime);
|
|
64736
|
-
if (!time3)
|
|
64737
|
-
return null;
|
|
64738
|
-
const dueAt = new Date(now);
|
|
64739
|
-
dueAt.setHours(time3.hour, time3.minute, 0, 0);
|
|
64740
|
-
const daysForward = (payment.dayOfWeek - dueAt.getDay() + 7) % 7;
|
|
64741
|
-
dueAt.setDate(dueAt.getDate() + daysForward);
|
|
64742
|
-
if (dueAt.getTime() <= now.getTime()) {
|
|
64743
|
-
dueAt.setDate(dueAt.getDate() + 7);
|
|
64744
|
-
}
|
|
64745
|
-
while (dueAt.getTime() < startAt.getTime()) {
|
|
64746
|
-
dueAt.setDate(dueAt.getDate() + 7);
|
|
64747
|
-
}
|
|
64748
|
-
return { dueAt, key: dueAt.toISOString().slice(0, 10) };
|
|
64749
|
-
}
|
|
64750
|
-
function nextMonthlyOccurrence(payment, now, startAt) {
|
|
64751
|
-
if (!payment.localTime || !Number.isInteger(payment.dayOfMonth) || payment.dayOfMonth === void 0)
|
|
64752
|
-
return null;
|
|
64753
|
-
const time3 = parseLocalTime(payment.localTime);
|
|
64754
|
-
if (!time3)
|
|
64755
|
-
return null;
|
|
64756
|
-
let dueAt = clampedMonthlyDate(now.getFullYear(), now.getMonth(), payment.dayOfMonth, time3.hour, time3.minute);
|
|
64757
|
-
if (dueAt.getTime() <= now.getTime()) {
|
|
64758
|
-
dueAt = clampedMonthlyDate(now.getFullYear(), now.getMonth() + 1, payment.dayOfMonth, time3.hour, time3.minute);
|
|
64759
|
-
}
|
|
64760
|
-
while (dueAt.getTime() < startAt.getTime()) {
|
|
64761
|
-
dueAt = clampedMonthlyDate(dueAt.getFullYear(), dueAt.getMonth() + 1, payment.dayOfMonth, time3.hour, time3.minute);
|
|
64762
|
-
}
|
|
64763
|
-
return { dueAt, key: dueAt.toISOString().slice(0, 10) };
|
|
64764
|
-
}
|
|
64765
|
-
function nextIntervalOccurrence(payment, now, interval, intervalMs) {
|
|
64766
|
-
if (!Number.isInteger(interval) || interval === void 0 || interval < 1)
|
|
64767
|
-
return null;
|
|
64768
|
-
const anchor = recurringStartAt(payment);
|
|
64769
|
-
if (!anchor)
|
|
64770
|
-
return null;
|
|
64771
|
-
const totalIntervalMs = interval * intervalMs;
|
|
64772
|
-
const dueAt = new Date(anchor);
|
|
64773
|
-
if (dueAt.getTime() <= now.getTime()) {
|
|
64774
|
-
const elapsedMs = now.getTime() - dueAt.getTime();
|
|
64775
|
-
dueAt.setTime(dueAt.getTime() + (Math.floor(elapsedMs / totalIntervalMs) + 1) * totalIntervalMs);
|
|
64776
|
-
}
|
|
64777
|
-
return {
|
|
64778
|
-
dueAt,
|
|
64779
|
-
key: payment.cadence === "interval_days" ? dueAt.toISOString().slice(0, 10) : dueAt.toISOString()
|
|
64780
|
-
};
|
|
65682
|
+
return nextFutureOccurrence(payment, now)?.dueAt.toISOString() ?? null;
|
|
64781
65683
|
}
|
|
64782
65684
|
function actionReceipt(action) {
|
|
64783
65685
|
const recipient = typeof action.params.recipient === "string" ? action.params.recipient : void 0;
|
|
@@ -64798,93 +65700,15 @@ function actionReceipt(action) {
|
|
|
64798
65700
|
cluster: action.cluster,
|
|
64799
65701
|
createdAt: action.createdAt,
|
|
64800
65702
|
completedAt: action.confirmedAt ?? action.updatedAt,
|
|
64801
|
-
...action.error !== void 0 && { error: action.error }
|
|
65703
|
+
...action.error !== void 0 && { error: action.error },
|
|
65704
|
+
...action.recurringId !== void 0 && { recurringId: action.recurringId },
|
|
65705
|
+
...action.occurrenceKey !== void 0 && { occurrenceKey: action.occurrenceKey }
|
|
64802
65706
|
};
|
|
64803
65707
|
}
|
|
64804
65708
|
function explorerUrl2(txid, cluster) {
|
|
64805
65709
|
const clusterParam = cluster === "mainnet-beta" ? "" : `?cluster=${cluster}`;
|
|
64806
65710
|
return `https://solscan.io/tx/${txid}${clusterParam}`;
|
|
64807
65711
|
}
|
|
64808
|
-
function latestWeeklyOccurrence(payment, now) {
|
|
64809
|
-
if (!payment.localTime) {
|
|
64810
|
-
return null;
|
|
64811
|
-
}
|
|
64812
|
-
const [hourRaw, minuteRaw] = payment.localTime.split(":");
|
|
64813
|
-
const hour = Number(hourRaw);
|
|
64814
|
-
const minute = Number(minuteRaw);
|
|
64815
|
-
if (!Number.isInteger(hour) || !Number.isInteger(minute) || hour < 0 || hour > 23 || minute < 0 || minute > 59) {
|
|
64816
|
-
return null;
|
|
64817
|
-
}
|
|
64818
|
-
if (!Number.isInteger(payment.dayOfWeek) || payment.dayOfWeek === void 0) {
|
|
64819
|
-
return null;
|
|
64820
|
-
}
|
|
64821
|
-
const dueAt = new Date(now);
|
|
64822
|
-
dueAt.setHours(hour, minute, 0, 0);
|
|
64823
|
-
const daysBack = (dueAt.getDay() - payment.dayOfWeek + 7) % 7;
|
|
64824
|
-
dueAt.setDate(dueAt.getDate() - daysBack);
|
|
64825
|
-
if (dueAt.getTime() > now.getTime()) {
|
|
64826
|
-
dueAt.setDate(dueAt.getDate() - 7);
|
|
64827
|
-
}
|
|
64828
|
-
return { dueAt, key: dueAt.toISOString().slice(0, 10) };
|
|
64829
|
-
}
|
|
64830
|
-
function latestMonthlyOccurrence(payment, now) {
|
|
64831
|
-
if (!payment.localTime) {
|
|
64832
|
-
return null;
|
|
64833
|
-
}
|
|
64834
|
-
const time3 = parseLocalTime(payment.localTime);
|
|
64835
|
-
if (!time3 || !Number.isInteger(payment.dayOfMonth) || payment.dayOfMonth === void 0) {
|
|
64836
|
-
return null;
|
|
64837
|
-
}
|
|
64838
|
-
const dueAt = clampedMonthlyDate(now.getFullYear(), now.getMonth(), payment.dayOfMonth, time3.hour, time3.minute);
|
|
64839
|
-
if (dueAt.getTime() > now.getTime()) {
|
|
64840
|
-
dueAt.setMonth(dueAt.getMonth() - 1);
|
|
64841
|
-
const previous = clampedMonthlyDate(dueAt.getFullYear(), dueAt.getMonth(), payment.dayOfMonth, time3.hour, time3.minute);
|
|
64842
|
-
return { dueAt: previous, key: previous.toISOString().slice(0, 10) };
|
|
64843
|
-
}
|
|
64844
|
-
return { dueAt, key: dueAt.toISOString().slice(0, 10) };
|
|
64845
|
-
}
|
|
64846
|
-
function latestIntervalOccurrence(payment, now, interval, intervalMs) {
|
|
64847
|
-
if (!Number.isInteger(interval) || interval === void 0 || interval < 1) {
|
|
64848
|
-
return null;
|
|
64849
|
-
}
|
|
64850
|
-
const anchor = new Date(payment.startAt ?? payment.createdAt);
|
|
64851
|
-
if (Number.isNaN(anchor.getTime())) {
|
|
64852
|
-
return null;
|
|
64853
|
-
}
|
|
64854
|
-
const dueAt = new Date(anchor);
|
|
64855
|
-
const time3 = payment.localTime ? parseLocalTime(payment.localTime) : null;
|
|
64856
|
-
if (time3 && payment.cadence === "interval_days") {
|
|
64857
|
-
dueAt.setHours(time3.hour, time3.minute, 0, 0);
|
|
64858
|
-
}
|
|
64859
|
-
if (dueAt.getTime() > now.getTime()) {
|
|
64860
|
-
return null;
|
|
64861
|
-
}
|
|
64862
|
-
const elapsedMs = now.getTime() - dueAt.getTime();
|
|
64863
|
-
const totalIntervalMs = interval * intervalMs;
|
|
64864
|
-
const intervalsElapsed = Math.floor(elapsedMs / totalIntervalMs);
|
|
64865
|
-
dueAt.setTime(dueAt.getTime() + intervalsElapsed * totalIntervalMs);
|
|
64866
|
-
return {
|
|
64867
|
-
dueAt,
|
|
64868
|
-
key: payment.cadence === "interval_days" ? dueAt.toISOString().slice(0, 10) : dueAt.toISOString()
|
|
64869
|
-
};
|
|
64870
|
-
}
|
|
64871
|
-
function recurringStartAt(payment) {
|
|
64872
|
-
const startAt = new Date(payment.startAt ?? payment.createdAt);
|
|
64873
|
-
return Number.isNaN(startAt.getTime()) ? null : startAt;
|
|
64874
|
-
}
|
|
64875
|
-
function parseLocalTime(localTime) {
|
|
64876
|
-
const [hourRaw, minuteRaw] = localTime.split(":");
|
|
64877
|
-
const hour = Number(hourRaw);
|
|
64878
|
-
const minute = Number(minuteRaw);
|
|
64879
|
-
if (!Number.isInteger(hour) || !Number.isInteger(minute) || hour < 0 || hour > 23 || minute < 0 || minute > 59) {
|
|
64880
|
-
return null;
|
|
64881
|
-
}
|
|
64882
|
-
return { hour, minute };
|
|
64883
|
-
}
|
|
64884
|
-
function clampedMonthlyDate(year, month, dayOfMonth, hour, minute) {
|
|
64885
|
-
const lastDay = new Date(year, month + 1, 0).getDate();
|
|
64886
|
-
return new Date(year, month, Math.min(dayOfMonth, lastDay), hour, minute, 0, 0);
|
|
64887
|
-
}
|
|
64888
65712
|
function statusForDueAt(dueAt, now) {
|
|
64889
65713
|
return new Date(dueAt).getTime() > now.getTime() ? "scheduled" : "ready";
|
|
64890
65714
|
}
|
|
@@ -67204,7 +68028,7 @@ function clean(...arrays) {
|
|
|
67204
68028
|
function createView(arr) {
|
|
67205
68029
|
return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
|
|
67206
68030
|
}
|
|
67207
|
-
function
|
|
68031
|
+
function rotr2(word, shift) {
|
|
67208
68032
|
return word << 32 - shift | word >>> shift;
|
|
67209
68033
|
}
|
|
67210
68034
|
var isLE = /* @__PURE__ */ (() => new Uint8Array(new Uint32Array([287454020]).buffer)[0] === 68)();
|
|
@@ -67758,7 +68582,7 @@ var SHA512_IV = /* @__PURE__ */ Uint32Array.from([
|
|
|
67758
68582
|
]);
|
|
67759
68583
|
|
|
67760
68584
|
// ../../node_modules/.pnpm/@noble+hashes@1.8.0/node_modules/@noble/hashes/esm/sha2.js
|
|
67761
|
-
var
|
|
68585
|
+
var SHA256_K2 = /* @__PURE__ */ Uint32Array.from([
|
|
67762
68586
|
1116352408,
|
|
67763
68587
|
1899447441,
|
|
67764
68588
|
3049323471,
|
|
@@ -67858,15 +68682,15 @@ var SHA256 = class extends HashMD {
|
|
|
67858
68682
|
for (let i = 16; i < 64; i++) {
|
|
67859
68683
|
const W15 = SHA256_W[i - 15];
|
|
67860
68684
|
const W22 = SHA256_W[i - 2];
|
|
67861
|
-
const s0 =
|
|
67862
|
-
const s1 =
|
|
68685
|
+
const s0 = rotr2(W15, 7) ^ rotr2(W15, 18) ^ W15 >>> 3;
|
|
68686
|
+
const s1 = rotr2(W22, 17) ^ rotr2(W22, 19) ^ W22 >>> 10;
|
|
67863
68687
|
SHA256_W[i] = s1 + SHA256_W[i - 7] + s0 + SHA256_W[i - 16] | 0;
|
|
67864
68688
|
}
|
|
67865
68689
|
let { A: A4, B: B3, C: C2, D: D3, E: E3, F: F3, G: G3, H: H5 } = this;
|
|
67866
68690
|
for (let i = 0; i < 64; i++) {
|
|
67867
|
-
const sigma1 =
|
|
67868
|
-
const T1 = H5 + sigma1 + Chi(E3, F3, G3) +
|
|
67869
|
-
const sigma0 =
|
|
68691
|
+
const sigma1 = rotr2(E3, 6) ^ rotr2(E3, 11) ^ rotr2(E3, 25);
|
|
68692
|
+
const T1 = H5 + sigma1 + Chi(E3, F3, G3) + SHA256_K2[i] + SHA256_W[i] | 0;
|
|
68693
|
+
const sigma0 = rotr2(A4, 2) ^ rotr2(A4, 13) ^ rotr2(A4, 22);
|
|
67870
68694
|
const T22 = sigma0 + Maj(A4, B3, C2) | 0;
|
|
67871
68695
|
H5 = G3;
|
|
67872
68696
|
G3 = F3;
|
|
@@ -68551,8 +69375,8 @@ function fromNumber(value, options = {}) {
|
|
|
68551
69375
|
value: `${value}${suffix}`
|
|
68552
69376
|
});
|
|
68553
69377
|
}
|
|
68554
|
-
const
|
|
68555
|
-
const hex = `0x${
|
|
69378
|
+
const stringValue2 = (signed && value_ < 0 ? (1n << BigInt(size3 * 8)) + BigInt(value_) : value_).toString(16);
|
|
69379
|
+
const hex = `0x${stringValue2}`;
|
|
68556
69380
|
if (size3)
|
|
68557
69381
|
return padLeft(hex, size3);
|
|
68558
69382
|
return hex;
|
|
@@ -76503,7 +77327,7 @@ var float32ArrayTag = "[object Float32Array]";
|
|
|
76503
77327
|
var float64ArrayTag = "[object Float64Array]";
|
|
76504
77328
|
|
|
76505
77329
|
// ../../node_modules/.pnpm/es-toolkit@1.44.0/node_modules/es-toolkit/dist/predicate/isPlainObject.mjs
|
|
76506
|
-
function
|
|
77330
|
+
function isPlainObject3(value) {
|
|
76507
77331
|
if (!value || typeof value !== "object") {
|
|
76508
77332
|
return false;
|
|
76509
77333
|
}
|
|
@@ -76660,7 +77484,7 @@ function areObjectsEqual(a, b3, stack, areValuesEqual) {
|
|
|
76660
77484
|
return a.name === b3.name && a.message === b3.message;
|
|
76661
77485
|
}
|
|
76662
77486
|
case objectTag: {
|
|
76663
|
-
const areEqualInstances = areObjectsEqual(a.constructor, b3.constructor, stack, areValuesEqual) ||
|
|
77487
|
+
const areEqualInstances = areObjectsEqual(a.constructor, b3.constructor, stack, areValuesEqual) || isPlainObject3(a) && isPlainObject3(b3);
|
|
76664
77488
|
if (!areEqualInstances) {
|
|
76665
77489
|
return false;
|
|
76666
77490
|
}
|
|
@@ -80941,6 +81765,7 @@ var BridgeAiPlanner = class {
|
|
|
80941
81765
|
throw new ProtocolError("unsupported_method", "Bridge AI is not configured. Set AGENTIC_AI_API_KEY or provide a bridge session key.");
|
|
80942
81766
|
}
|
|
80943
81767
|
const normalizedRequest = normalizeRequest(request);
|
|
81768
|
+
assertAiDraftRequestAllowed(normalizedRequest);
|
|
80944
81769
|
if (config2.apiFormat === "anthropic") {
|
|
80945
81770
|
return this.generateAnthropicPlan(config2, normalizedRequest);
|
|
80946
81771
|
}
|
|
@@ -81108,7 +81933,7 @@ function normalizeStrictAiPlan(payload, request, providerLabel) {
|
|
|
81108
81933
|
}
|
|
81109
81934
|
function aiPlanFromParsed(parsed, request) {
|
|
81110
81935
|
const parameters = request.parameters;
|
|
81111
|
-
|
|
81936
|
+
const plan = {
|
|
81112
81937
|
intent: stringOr(parsed.intent, `${request.template.title}: ${request.prompt}`),
|
|
81113
81938
|
route: stringOr(parsed.route, `Draft ${request.template.actionType} request and show route details before wallet approval.`),
|
|
81114
81939
|
risk: stringOr(parsed.risk, `Risk level ${request.template.risk}. Verify all visible fields before signing.`),
|
|
@@ -81122,6 +81947,67 @@ function aiPlanFromParsed(parsed, request) {
|
|
|
81122
81947
|
fields: Object.entries(parameters).filter(([, value]) => value.trim().length > 0).map(([key, value]) => ({ label: titleCase(key), value })),
|
|
81123
81948
|
safeguards: normalizeSafeguards(parsed.safeguards)
|
|
81124
81949
|
};
|
|
81950
|
+
return withGuardrailReport(plan, request);
|
|
81951
|
+
}
|
|
81952
|
+
function assertAiDraftRequestAllowed(request) {
|
|
81953
|
+
try {
|
|
81954
|
+
assertPlanGuardrails({
|
|
81955
|
+
source: "ai",
|
|
81956
|
+
category: request.template.category,
|
|
81957
|
+
actionType: request.template.actionType,
|
|
81958
|
+
templateId: request.template.id,
|
|
81959
|
+
templateTitle: request.template.title,
|
|
81960
|
+
parameters: request.parameters,
|
|
81961
|
+
userNotes: request.userNotes,
|
|
81962
|
+
prompt: request.prompt,
|
|
81963
|
+
plan: {
|
|
81964
|
+
source: "ai",
|
|
81965
|
+
category: request.template.category,
|
|
81966
|
+
actionType: request.template.actionType,
|
|
81967
|
+
templateId: request.template.id,
|
|
81968
|
+
templateTitle: request.template.title,
|
|
81969
|
+
parameters: request.parameters,
|
|
81970
|
+
prompt: request.prompt,
|
|
81971
|
+
userNotes: request.userNotes,
|
|
81972
|
+
intent: request.prompt,
|
|
81973
|
+
route: "AI draft only. Wallet approval is required later.",
|
|
81974
|
+
risk: `Requested risk level ${request.template.risk}.`,
|
|
81975
|
+
approval: "Wallet approval is required before signing or submitting."
|
|
81976
|
+
}
|
|
81977
|
+
});
|
|
81978
|
+
} catch (err) {
|
|
81979
|
+
if (err instanceof Error) {
|
|
81980
|
+
throw new ProtocolError("invalid_request", err.message);
|
|
81981
|
+
}
|
|
81982
|
+
throw err;
|
|
81983
|
+
}
|
|
81984
|
+
}
|
|
81985
|
+
function withGuardrailReport(plan, request) {
|
|
81986
|
+
try {
|
|
81987
|
+
const report = assertPlanGuardrails({
|
|
81988
|
+
plan: { ...plan },
|
|
81989
|
+
source: plan.source,
|
|
81990
|
+
category: plan.category,
|
|
81991
|
+
actionType: plan.actionType,
|
|
81992
|
+
templateId: request.template.id,
|
|
81993
|
+
templateTitle: plan.templateTitle,
|
|
81994
|
+
parameters: plan.parameters,
|
|
81995
|
+
fields: plan.fields,
|
|
81996
|
+
userNotes: plan.userNotes,
|
|
81997
|
+
prompt: request.prompt
|
|
81998
|
+
});
|
|
81999
|
+
return {
|
|
82000
|
+
...plan,
|
|
82001
|
+
guardrailReport: report,
|
|
82002
|
+
constraintFingerprint: report.constraintFingerprint,
|
|
82003
|
+
...report.constraintHash ? { constraintHash: report.constraintHash } : {}
|
|
82004
|
+
};
|
|
82005
|
+
} catch (err) {
|
|
82006
|
+
if (err instanceof Error) {
|
|
82007
|
+
throw new ProtocolError("invalid_request", err.message);
|
|
82008
|
+
}
|
|
82009
|
+
throw err;
|
|
82010
|
+
}
|
|
81125
82011
|
}
|
|
81126
82012
|
function isPlanJson(value) {
|
|
81127
82013
|
return typeof value.intent === "string" && typeof value.route === "string" && typeof value.risk === "string" && typeof value.approval === "string" && Array.isArray(value.safeguards) && value.safeguards.every((entry) => typeof entry === "string");
|
|
@@ -81465,6 +82351,14 @@ async function handleRequest(req, res, backend, actionConfig, preparedActions, l
|
|
|
81465
82351
|
writeJson(res, 200, { artifact: await requireLabArtifactStore(labArtifacts).upsertArtifact(artifact) });
|
|
81466
82352
|
return;
|
|
81467
82353
|
}
|
|
82354
|
+
if (req.method === "POST" && url.pathname === "/bridge/lab-artifacts/delete") {
|
|
82355
|
+
const body = await readJson(req);
|
|
82356
|
+
if (!body.artifactId) {
|
|
82357
|
+
throw new ProtocolError("invalid_request", "Missing artifactId.");
|
|
82358
|
+
}
|
|
82359
|
+
writeJson(res, 200, { deleted: await requireLabArtifactStore(labArtifacts).deleteArtifact(body.artifactId) });
|
|
82360
|
+
return;
|
|
82361
|
+
}
|
|
81468
82362
|
if (req.method === "GET" && url.pathname === "/bridge/health") {
|
|
81469
82363
|
const caps = await backend.capabilities().catch(() => null);
|
|
81470
82364
|
const rpcWritable = actionConfig ? await checkRpcWritable(actionConfig.rpcUrl) : { ok: false, message: "Action config unavailable." };
|
|
@@ -81880,6 +82774,13 @@ var JsonLabArtifactStore = class {
|
|
|
81880
82774
|
const state = await this.read();
|
|
81881
82775
|
return sortArtifacts(state.artifacts);
|
|
81882
82776
|
}
|
|
82777
|
+
async deleteArtifact(id) {
|
|
82778
|
+
return this.mutate((state) => {
|
|
82779
|
+
const before = state.artifacts.length;
|
|
82780
|
+
state.artifacts = state.artifacts.filter((artifact) => artifact.id !== id);
|
|
82781
|
+
return state.artifacts.length !== before;
|
|
82782
|
+
});
|
|
82783
|
+
}
|
|
81883
82784
|
getStoragePath() {
|
|
81884
82785
|
return this.path;
|
|
81885
82786
|
}
|
|
@@ -82574,7 +83475,7 @@ async function approvePreparedAction(state, idOrIndex) {
|
|
|
82574
83475
|
body: JSON.stringify({ actionId: action.id })
|
|
82575
83476
|
});
|
|
82576
83477
|
printOk(state.options, `Approved prepared action ${action.id}.`);
|
|
82577
|
-
console.log(
|
|
83478
|
+
console.log(stableJson2(result));
|
|
82578
83479
|
await printInbox(state, "all").catch(() => void 0);
|
|
82579
83480
|
}
|
|
82580
83481
|
async function rejectPreparedAction(state, idOrIndex, reason) {
|
|
@@ -82585,7 +83486,7 @@ async function rejectPreparedAction(state, idOrIndex, reason) {
|
|
|
82585
83486
|
body: JSON.stringify({ actionId: action.id, reason: reason ?? "Rejected from terminal." })
|
|
82586
83487
|
});
|
|
82587
83488
|
printOk(state.options, `Rejected prepared action ${action.id}.`);
|
|
82588
|
-
console.log(
|
|
83489
|
+
console.log(stableJson2(result));
|
|
82589
83490
|
}
|
|
82590
83491
|
async function archivePreparedAction(state, idOrIndex) {
|
|
82591
83492
|
const action = await resolveAction(state, idOrIndex);
|
|
@@ -82594,7 +83495,7 @@ async function archivePreparedAction(state, idOrIndex) {
|
|
|
82594
83495
|
body: JSON.stringify({ actionId: action.id })
|
|
82595
83496
|
});
|
|
82596
83497
|
printOk(state.options, `Archived prepared action ${action.id}.`);
|
|
82597
|
-
console.log(
|
|
83498
|
+
console.log(stableJson2(result));
|
|
82598
83499
|
}
|
|
82599
83500
|
async function inspectPreparedActionInteractive(state, idOrIndex) {
|
|
82600
83501
|
const action = await resolveAction(state, idOrIndex);
|
|
@@ -82623,7 +83524,7 @@ async function runScheduleCommand(state, rl, args) {
|
|
|
82623
83524
|
body: JSON.stringify({ recurringId })
|
|
82624
83525
|
});
|
|
82625
83526
|
printOk(state.options, `Recurring payment ${op}: ${recurringId}`);
|
|
82626
|
-
console.log(
|
|
83527
|
+
console.log(stableJson2(result2));
|
|
82627
83528
|
return;
|
|
82628
83529
|
}
|
|
82629
83530
|
await requireWalletConnected(state);
|
|
@@ -82660,7 +83561,7 @@ async function runScheduleCommand(state, rl, args) {
|
|
|
82660
83561
|
body: JSON.stringify(body)
|
|
82661
83562
|
});
|
|
82662
83563
|
printOk(state.options, "Recurring approval created.");
|
|
82663
|
-
console.log(
|
|
83564
|
+
console.log(stableJson2(result));
|
|
82664
83565
|
}
|
|
82665
83566
|
async function runPlanCommand(state, rl, naturalLanguage) {
|
|
82666
83567
|
printSection("Agent Plan");
|
|
@@ -82730,7 +83631,7 @@ async function runResearchCommand(state, rl, args) {
|
|
|
82730
83631
|
const inlineInput = args.slice(1).join(" ");
|
|
82731
83632
|
const input = inlineInput || await prompt(rl, "Artifact input", lab.defaultInput);
|
|
82732
83633
|
const artifact = await buildResearchArtifact(state.options, lab, input);
|
|
82733
|
-
console.log(
|
|
83634
|
+
console.log(stableJson2(artifact));
|
|
82734
83635
|
if (await confirm(rl, "Sign this research artifact?", true)) {
|
|
82735
83636
|
const approval = await signTextWithWallet(
|
|
82736
83637
|
state,
|
|
@@ -82755,7 +83656,7 @@ async function runQuoteCommand(state, rl) {
|
|
|
82755
83656
|
method: "POST",
|
|
82756
83657
|
body: JSON.stringify({ amount, inputToken, outputToken, slippageBps })
|
|
82757
83658
|
});
|
|
82758
|
-
console.log(
|
|
83659
|
+
console.log(stableJson2(result));
|
|
82759
83660
|
}
|
|
82760
83661
|
async function printReceipts(state) {
|
|
82761
83662
|
const response = await bridgeRequest(state.options, "/bridge/receipts");
|
|
@@ -83068,7 +83969,7 @@ async function handleWalletHostRequest(root, req, res) {
|
|
|
83068
83969
|
}
|
|
83069
83970
|
const url = new URL(req.url ?? "/", `http://${req.headers.host ?? "127.0.0.1"}`);
|
|
83070
83971
|
if (url.pathname === WALLET_HOST_HEALTH_PATH) {
|
|
83071
|
-
const body2 = req.method === "HEAD" ? Buffer.alloc(0) : `${
|
|
83972
|
+
const body2 = req.method === "HEAD" ? Buffer.alloc(0) : `${stableJson2({ ok: true, service: "agentic-wallet-host" })}
|
|
83072
83973
|
`;
|
|
83073
83974
|
writeStaticResponse(res, 200, "application/json; charset=utf-8", body2);
|
|
83074
83975
|
return;
|
|
@@ -83148,7 +84049,7 @@ async function ensureRuntimeFiles(options) {
|
|
|
83148
84049
|
await mkdir3(dirname3(options.preparedActionsPath), { recursive: true });
|
|
83149
84050
|
await mkdir3(dirname3(options.labArtifactsPath), { recursive: true });
|
|
83150
84051
|
if (!existsSync(options.configPath)) {
|
|
83151
|
-
await writeFile3(options.configPath, `${
|
|
84052
|
+
await writeFile3(options.configPath, `${stableJson2(DEFAULT_CONFIG)}
|
|
83152
84053
|
`, "utf8");
|
|
83153
84054
|
}
|
|
83154
84055
|
}
|
|
@@ -83427,7 +84328,7 @@ async function saveResearchArtifact(options, artifact) {
|
|
|
83427
84328
|
await mkdir3(dir, { recursive: true });
|
|
83428
84329
|
const existing = await readJsonFile(path).catch(() => ({ artifacts: [] }));
|
|
83429
84330
|
const artifacts = [artifact, ...(existing.artifacts ?? []).filter((item) => item.id !== artifact.id)].slice(0, 50);
|
|
83430
|
-
await writeFile3(path, `${
|
|
84331
|
+
await writeFile3(path, `${stableJson2({ artifacts })}
|
|
83431
84332
|
`, "utf8");
|
|
83432
84333
|
}
|
|
83433
84334
|
async function readJsonFile(path) {
|
|
@@ -83503,7 +84404,7 @@ function agentPlanSigningMessage(plan) {
|
|
|
83503
84404
|
`Risk: ${plan.risk}`,
|
|
83504
84405
|
`Constraints: ${plan.constraints.join(" | ")}`,
|
|
83505
84406
|
`Created: ${plan.createdAt}`,
|
|
83506
|
-
`Hash: ${sha2564(
|
|
84407
|
+
`Hash: ${sha2564(stableJson2(plan))}`
|
|
83507
84408
|
].join("\n");
|
|
83508
84409
|
}
|
|
83509
84410
|
function researchSigningMessage(artifact) {
|
|
@@ -83557,7 +84458,7 @@ async function buildResearchArtifact(options, lab, input) {
|
|
|
83557
84458
|
cluster,
|
|
83558
84459
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
83559
84460
|
};
|
|
83560
|
-
const payloadHash = sha2564(
|
|
84461
|
+
const payloadHash = sha2564(stableJson2(baseArtifact));
|
|
83561
84462
|
return { ...baseArtifact, payloadHash };
|
|
83562
84463
|
}
|
|
83563
84464
|
function filterPreparedActions(actions, filter) {
|
|
@@ -83614,7 +84515,7 @@ function printPreparedActionDetail(action, row) {
|
|
|
83614
84515
|
console.log(` Error: ${action.error}`);
|
|
83615
84516
|
}
|
|
83616
84517
|
if (Object.keys(action.params).length > 0) {
|
|
83617
|
-
console.log(` Params: ${
|
|
84518
|
+
console.log(` Params: ${stableJson2(action.params).replace(/\n/g, "\n ")}`);
|
|
83618
84519
|
}
|
|
83619
84520
|
}
|
|
83620
84521
|
function renderPreparedActionsCompact(actions) {
|
|
@@ -83711,7 +84612,7 @@ function printDoctor(options, doctor) {
|
|
|
83711
84612
|
const walletHost = isRecord(doctor.walletHost) ? doctor.walletHost : {};
|
|
83712
84613
|
console.log(`Browser wallet host: ${walletHost.reachable ? "reachable" : "offline"}`);
|
|
83713
84614
|
if (options.json) {
|
|
83714
|
-
console.log(
|
|
84615
|
+
console.log(stableJson2(doctor));
|
|
83715
84616
|
}
|
|
83716
84617
|
}
|
|
83717
84618
|
function renderBanner(state) {
|
|
@@ -83788,10 +84689,10 @@ function printResult(result, options) {
|
|
|
83788
84689
|
return;
|
|
83789
84690
|
}
|
|
83790
84691
|
if (options.json) {
|
|
83791
|
-
console.log(
|
|
84692
|
+
console.log(stableJson2(result));
|
|
83792
84693
|
return;
|
|
83793
84694
|
}
|
|
83794
|
-
console.log(
|
|
84695
|
+
console.log(stableJson2(result));
|
|
83795
84696
|
}
|
|
83796
84697
|
function printSection(title) {
|
|
83797
84698
|
console.log(`
|
|
@@ -84095,16 +84996,16 @@ function stripTrailingSlash(value) {
|
|
|
84095
84996
|
function isRecord(value) {
|
|
84096
84997
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
84097
84998
|
}
|
|
84098
|
-
function
|
|
84099
|
-
return JSON.stringify(
|
|
84999
|
+
function stableJson2(value) {
|
|
85000
|
+
return JSON.stringify(sortJson2(value), null, 2);
|
|
84100
85001
|
}
|
|
84101
|
-
function
|
|
85002
|
+
function sortJson2(value) {
|
|
84102
85003
|
if (Array.isArray(value)) {
|
|
84103
|
-
return value.map(
|
|
85004
|
+
return value.map(sortJson2);
|
|
84104
85005
|
}
|
|
84105
85006
|
if (isRecord(value)) {
|
|
84106
85007
|
return Object.fromEntries(
|
|
84107
|
-
Object.keys(value).sort().map((key) => [key,
|
|
85008
|
+
Object.keys(value).sort().map((key) => [key, sortJson2(value[key])])
|
|
84108
85009
|
);
|
|
84109
85010
|
}
|
|
84110
85011
|
return value;
|