@juspay/neurolink 11.29.2 → 11.30.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/CHANGELOG.md +3 -3
- package/dist/auth/anthropicOAuth.d.ts +50 -0
- package/dist/auth/anthropicOAuth.js +78 -0
- package/dist/browser/neurolink.min.js +393 -393
- package/dist/cli/commands/proxy.d.ts +2 -0
- package/dist/cli/commands/proxy.js +284 -4
- package/dist/cli/commands/proxyExpose.d.ts +35 -0
- package/dist/cli/commands/proxyExpose.js +252 -0
- package/dist/cli/commands/proxyPeer.d.ts +29 -0
- package/dist/cli/commands/proxyPeer.js +738 -0
- package/dist/cli/commands/proxyShare.d.ts +37 -0
- package/dist/cli/commands/proxyShare.js +1080 -0
- package/dist/cli/parser.js +7 -1
- package/dist/proxy/peerStore.d.ts +52 -0
- package/dist/proxy/peerStore.js +324 -0
- package/dist/proxy/peerTransport.d.ts +38 -0
- package/dist/proxy/peerTransport.js +242 -0
- package/dist/proxy/proxyPaths.d.ts +8 -0
- package/dist/proxy/proxyPaths.js +55 -17
- package/dist/proxy/requestLogger.js +8 -0
- package/dist/proxy/residentGrants.d.ts +57 -0
- package/dist/proxy/residentGrants.js +393 -0
- package/dist/proxy/shareAudit.d.ts +81 -0
- package/dist/proxy/shareAudit.js +280 -0
- package/dist/proxy/shareContext.d.ts +38 -0
- package/dist/proxy/shareContext.js +92 -0
- package/dist/proxy/shareGate.d.ts +64 -0
- package/dist/proxy/shareGate.js +216 -0
- package/dist/proxy/shareGrants.d.ts +115 -0
- package/dist/proxy/shareGrants.js +590 -0
- package/dist/proxy/shareLease.d.ts +101 -0
- package/dist/proxy/shareLease.js +192 -0
- package/dist/proxy/shareLedger.d.ts +105 -0
- package/dist/proxy/shareLedger.js +406 -0
- package/dist/proxy/shareListener.d.ts +60 -0
- package/dist/proxy/shareListener.js +143 -0
- package/dist/proxy/shareNotes.d.ts +97 -0
- package/dist/proxy/shareNotes.js +234 -0
- package/dist/proxy/sharePolicy.d.ts +110 -0
- package/dist/proxy/sharePolicy.js +366 -0
- package/dist/proxy/shareProvisioning.d.ts +110 -0
- package/dist/proxy/shareProvisioning.js +237 -0
- package/dist/proxy/shareReceipts.d.ts +99 -0
- package/dist/proxy/shareReceipts.js +303 -0
- package/dist/proxy/shareSigning.d.ts +40 -0
- package/dist/proxy/shareSigning.js +78 -0
- package/dist/server/routes/claudeProxyRoutes.js +1066 -3
- package/dist/types/cli.d.ts +61 -0
- package/dist/types/proxy.d.ts +781 -0
- package/package.json +2 -1
package/dist/types/proxy.d.ts
CHANGED
|
@@ -1367,6 +1367,12 @@ export type ProxyPaths = {
|
|
|
1367
1367
|
cooldownFile: string;
|
|
1368
1368
|
/** proxy-usage-stats.json — restart- and handoff-safe usage counters */
|
|
1369
1369
|
statsFile?: string;
|
|
1370
|
+
/** proxy-grants.json — grants this node has issued to borrowers */
|
|
1371
|
+
grantsFile?: string;
|
|
1372
|
+
/** proxy-share-ledger.json — coin balances, holds and settled spend */
|
|
1373
|
+
ledgerFile?: string;
|
|
1374
|
+
/** proxy-peers.json — lenders this node may borrow from */
|
|
1375
|
+
peersFile?: string;
|
|
1370
1376
|
/** Whether this is a dev-mode isolated instance */
|
|
1371
1377
|
isDev: boolean;
|
|
1372
1378
|
};
|
|
@@ -1804,6 +1810,10 @@ export type RuntimeRequestMetadata = {
|
|
|
1804
1810
|
rejectForUpdate?: boolean;
|
|
1805
1811
|
terminalErrorType?: string;
|
|
1806
1812
|
terminalErrorCode?: string;
|
|
1813
|
+
/** Releases this request's peer-share concurrency slot. Set by the share
|
|
1814
|
+
* gate for borrowed traffic; invoked once the response body completes, so a
|
|
1815
|
+
* long stream holds its slot for as long as it is actually streaming. */
|
|
1816
|
+
shareRelease?: () => void;
|
|
1807
1817
|
};
|
|
1808
1818
|
/** Accumulated upstream body capture from a raw stream. */
|
|
1809
1819
|
export type RawStreamCapture = {
|
|
@@ -2840,3 +2850,774 @@ export type ParsedOpenAIRequest = {
|
|
|
2840
2850
|
jsonSchema?: unknown;
|
|
2841
2851
|
};
|
|
2842
2852
|
};
|
|
2853
|
+
/**
|
|
2854
|
+
* How a borrower reaches the lender's capacity.
|
|
2855
|
+
*
|
|
2856
|
+
* - `live` — the borrower forwards each request to the lender's exposed proxy.
|
|
2857
|
+
* The lender's credentials never leave the lender's device and every request
|
|
2858
|
+
* passes the lender's gate, so control is immediate and cryptographic. The
|
|
2859
|
+
* borrower is dependent on the lender's device being reachable.
|
|
2860
|
+
* - `complete` — the borrower holds an independently provisioned OAuth grant on
|
|
2861
|
+
* the lender's account and calls the upstream directly. Survives the lender
|
|
2862
|
+
* being offline; control is enforced by a signed lease plus usage audit,
|
|
2863
|
+
* which makes it cooperative rather than cryptographic.
|
|
2864
|
+
*/
|
|
2865
|
+
export type ProxyShareLevel = "live" | "complete";
|
|
2866
|
+
export type ProxyShareGrantState = "active" | "paused" | "revoked" | "expired";
|
|
2867
|
+
/** Whether consumption is metered against a coin balance or uncapped. */
|
|
2868
|
+
export type ProxyShareLedgerMode = "coins" | "unlimited";
|
|
2869
|
+
/** A ceiling expressed as a percentage of each subscription window. */
|
|
2870
|
+
export type ProxyShareWindowSlice = {
|
|
2871
|
+
/** Percent of the 5-hour session window. */
|
|
2872
|
+
session5hPct?: number;
|
|
2873
|
+
/** Percent of the 7-day weekly window. */
|
|
2874
|
+
weekly7dPct?: number;
|
|
2875
|
+
};
|
|
2876
|
+
/**
|
|
2877
|
+
* Use-it-or-lose-it capacity: admit the borrower only in the run-up to a window
|
|
2878
|
+
* reset, and only when little of that window was consumed. `maxSlicePct` caps
|
|
2879
|
+
* how much of the remaining window the borrower may take while spilling over,
|
|
2880
|
+
* so a spillover grant can still carry a hard ceiling.
|
|
2881
|
+
*/
|
|
2882
|
+
export type ProxyShareSpilloverGate = {
|
|
2883
|
+
beforeResetHours: number;
|
|
2884
|
+
whenUtilizationBelowPct: number;
|
|
2885
|
+
maxSlicePct?: number;
|
|
2886
|
+
};
|
|
2887
|
+
/** Hour-of-day admission window, evaluated in the lender's local time. */
|
|
2888
|
+
export type ProxyShareSchedule = {
|
|
2889
|
+
fromHour: number;
|
|
2890
|
+
toHour: number;
|
|
2891
|
+
};
|
|
2892
|
+
export type ProxyShareRate = {
|
|
2893
|
+
perMinute?: number;
|
|
2894
|
+
concurrency?: number;
|
|
2895
|
+
};
|
|
2896
|
+
/**
|
|
2897
|
+
* The gate set. Every configured gate must pass; the effective allowance is the
|
|
2898
|
+
* minimum across all of them. Gates are deliberately orthogonal so a headroom
|
|
2899
|
+
* grant can also carry a window-slice ceiling, a spillover grant can also carry
|
|
2900
|
+
* a model allowlist, and so on.
|
|
2901
|
+
*/
|
|
2902
|
+
export type ProxyShareGates = {
|
|
2903
|
+
/** Hard ceiling on how much of the **pool** the borrower may consume, as a
|
|
2904
|
+
* percentage of one window's worth of capacity. Pool-wide because an
|
|
2905
|
+
* operator saying "a fifth" means a fifth of what they have, not a fifth of
|
|
2906
|
+
* every credential they happen to own. */
|
|
2907
|
+
maxSlice?: ProxyShareWindowSlice;
|
|
2908
|
+
/** Per-account ceiling. Rare — reach for `maxSlice` unless you specifically
|
|
2909
|
+
* mean "this much of every credential, independently". */
|
|
2910
|
+
maxSlicePerAccount?: ProxyShareWindowSlice;
|
|
2911
|
+
/** Admit only while the lender's own utilization leaves this much headroom. */
|
|
2912
|
+
reserveFloor?: ProxyShareWindowSlice;
|
|
2913
|
+
spillover?: ProxyShareSpilloverGate;
|
|
2914
|
+
/** Model tier allowlist, matched case-insensitively as substrings. */
|
|
2915
|
+
models?: string[];
|
|
2916
|
+
/** Which of the lender's accounts are lendable under this grant. */
|
|
2917
|
+
accounts?: string[];
|
|
2918
|
+
rate?: ProxyShareRate;
|
|
2919
|
+
schedule?: ProxyShareSchedule;
|
|
2920
|
+
/** Grant expiry, epoch ms. */
|
|
2921
|
+
notAfter?: number;
|
|
2922
|
+
};
|
|
2923
|
+
export type ProxyShareRefillPeriod = "session" | "week";
|
|
2924
|
+
export type ProxyShareEntitlement = {
|
|
2925
|
+
ledger: ProxyShareLedgerMode;
|
|
2926
|
+
/** Remaining balance when `ledger` is "coins". */
|
|
2927
|
+
coins?: number;
|
|
2928
|
+
refill?: {
|
|
2929
|
+
amount: number;
|
|
2930
|
+
per: ProxyShareRefillPeriod;
|
|
2931
|
+
lastAt?: number;
|
|
2932
|
+
};
|
|
2933
|
+
};
|
|
2934
|
+
/** One lender-issued authorization for one borrower. */
|
|
2935
|
+
export type ProxyShareGrant = {
|
|
2936
|
+
schemaVersion: 1;
|
|
2937
|
+
id: string;
|
|
2938
|
+
peerLabel: string;
|
|
2939
|
+
/** sha256(salt + token). The token itself is never persisted. */
|
|
2940
|
+
tokenHash: string;
|
|
2941
|
+
tokenSalt: string;
|
|
2942
|
+
level: ProxyShareLevel;
|
|
2943
|
+
state: ProxyShareGrantState;
|
|
2944
|
+
entitlement: ProxyShareEntitlement;
|
|
2945
|
+
gates: ProxyShareGates;
|
|
2946
|
+
createdAt: number;
|
|
2947
|
+
updatedAt: number;
|
|
2948
|
+
lastUsedAt?: number;
|
|
2949
|
+
note?: string;
|
|
2950
|
+
/** Complete-mode only: shared secret the lease signature is keyed by. */
|
|
2951
|
+
leaseSecret?: string;
|
|
2952
|
+
/**
|
|
2953
|
+
* Shared secret receipts and netting claims are keyed by. Minted with the
|
|
2954
|
+
* grant and handed to the borrower in the share link; deliberately survives
|
|
2955
|
+
* `share rotate`, so receipts issued under an old token stay checkable.
|
|
2956
|
+
*/
|
|
2957
|
+
receiptSecret?: string;
|
|
2958
|
+
/** Cumulative coins forgiven by reciprocal netting on this grant. */
|
|
2959
|
+
nettedCoins?: number;
|
|
2960
|
+
/** Complete-mode only: which of the lender's own accounts was provisioned. */
|
|
2961
|
+
provisionedAccount?: string;
|
|
2962
|
+
/** Complete-mode lease shape. Absent means the defaults apply. */
|
|
2963
|
+
leasePolicy?: {
|
|
2964
|
+
ttlMs: number;
|
|
2965
|
+
heartbeatEveryMs: number;
|
|
2966
|
+
offlineGraceMs: number;
|
|
2967
|
+
};
|
|
2968
|
+
};
|
|
2969
|
+
export type ProxyShareGrantFile = {
|
|
2970
|
+
schemaVersion: 1;
|
|
2971
|
+
grants: Record<string, ProxyShareGrant>;
|
|
2972
|
+
/** This node's stable public address, when it has one. Recorded once so
|
|
2973
|
+
* every share link is minted against it without retyping. */
|
|
2974
|
+
publicUrl?: string;
|
|
2975
|
+
/** Node-level secret coin notes are signed with. Minted on first issue. */
|
|
2976
|
+
noteSecret?: string;
|
|
2977
|
+
};
|
|
2978
|
+
/** Why a borrowed request was refused. Surfaced verbatim in a response header. */
|
|
2979
|
+
export type ProxyShareRefusalReason = "missing_token" | "unknown_token" | "malformed_token" | "paused" | "revoked" | "expired" | "out_of_window" | "model_not_allowed" | "exhausted" | "rate_limited" | "concurrency_limited" | "reserve_floor"
|
|
2980
|
+
/** Spillover is configured and the lender is not yet spilling. Transient. */
|
|
2981
|
+
| "spillover_inactive" | "slice_exhausted" | "no_capacity";
|
|
2982
|
+
/**
|
|
2983
|
+
* Result of evaluating an inbound borrowed request.
|
|
2984
|
+
*
|
|
2985
|
+
* A refusal carries its own status and reason so the borrower can distinguish
|
|
2986
|
+
* "you are out of credits" from an upstream rate limit. Conflating the two makes
|
|
2987
|
+
* a borrower cool the peer as if it were throttled and retry forever.
|
|
2988
|
+
*/
|
|
2989
|
+
export type ProxyShareAdmission = {
|
|
2990
|
+
admitted: true;
|
|
2991
|
+
grant: ProxyShareGrant;
|
|
2992
|
+
} | {
|
|
2993
|
+
admitted: false;
|
|
2994
|
+
status: number;
|
|
2995
|
+
reason: ProxyShareRefusalReason;
|
|
2996
|
+
message: string;
|
|
2997
|
+
retryAfterSeconds?: number;
|
|
2998
|
+
grant?: ProxyShareGrant;
|
|
2999
|
+
};
|
|
3000
|
+
/** The refusing half of {@link ProxyShareAdmission}. */
|
|
3001
|
+
export type ProxyShareRefusedAdmission = Extract<ProxyShareAdmission, {
|
|
3002
|
+
admitted: false;
|
|
3003
|
+
}>;
|
|
3004
|
+
/** Request-scoped view of the grant serving the current borrowed request. */
|
|
3005
|
+
export type ProxyShareRequestContext = {
|
|
3006
|
+
grantId: string;
|
|
3007
|
+
peerLabel: string;
|
|
3008
|
+
level: ProxyShareLevel;
|
|
3009
|
+
gates: ProxyShareGates;
|
|
3010
|
+
ledger: ProxyShareLedgerMode;
|
|
3011
|
+
/** Pre-authorization opened at admission; settlement closes it. */
|
|
3012
|
+
holdId?: string;
|
|
3013
|
+
/** Model the borrower asked for, carried so settlement can price it. */
|
|
3014
|
+
model?: string;
|
|
3015
|
+
};
|
|
3016
|
+
/** What `share create` returns — the only moment the raw token exists. */
|
|
3017
|
+
export type ProxyShareIssuedGrant = {
|
|
3018
|
+
grant: ProxyShareGrant;
|
|
3019
|
+
token: string;
|
|
3020
|
+
};
|
|
3021
|
+
/** Everything `createShareGrant` needs to mint a grant. */
|
|
3022
|
+
export type ProxyShareGrantInput = {
|
|
3023
|
+
peerLabel: string;
|
|
3024
|
+
level: ProxyShareLevel;
|
|
3025
|
+
entitlement: ProxyShareEntitlement;
|
|
3026
|
+
gates: ProxyShareGates;
|
|
3027
|
+
note?: string;
|
|
3028
|
+
};
|
|
3029
|
+
/** Partial edit applied by `share set` / `share topup` / `share level`. */
|
|
3030
|
+
export type ProxyShareGrantPatch = {
|
|
3031
|
+
entitlement?: Partial<ProxyShareEntitlement>;
|
|
3032
|
+
gates?: ProxyShareGates;
|
|
3033
|
+
level?: ProxyShareLevel;
|
|
3034
|
+
note?: string;
|
|
3035
|
+
};
|
|
3036
|
+
/** Runtime counters the rate gates need, supplied by the caller so the policy
|
|
3037
|
+
* evaluator stays pure. */
|
|
3038
|
+
export type ProxyShareRuntimeCounters = {
|
|
3039
|
+
requestsInLastMinute: number;
|
|
3040
|
+
inFlight: number;
|
|
3041
|
+
};
|
|
3042
|
+
/** Everything `evaluateShareAdmission` needs. Pure input — no I/O. */
|
|
3043
|
+
export type ProxyShareAdmissionInput = {
|
|
3044
|
+
grant: ProxyShareGrant;
|
|
3045
|
+
now: number;
|
|
3046
|
+
/** Requested model, used against the model allowlist. */
|
|
3047
|
+
model?: string;
|
|
3048
|
+
counters: ProxyShareRuntimeCounters;
|
|
3049
|
+
/** Remaining coins; omitted for an unlimited grant. */
|
|
3050
|
+
coinBalance?: number;
|
|
3051
|
+
};
|
|
3052
|
+
/** One candidate account as the share gates see it. */
|
|
3053
|
+
export type ProxyShareAccountView = {
|
|
3054
|
+
accountKey: string;
|
|
3055
|
+
/** 0..1 utilization of the 5h window, or null when unobserved. */
|
|
3056
|
+
sessionUsed: number | null;
|
|
3057
|
+
/** 0..1 utilization of the 7d window, or null when unobserved. */
|
|
3058
|
+
weeklyUsed: number | null;
|
|
3059
|
+
/** Epoch ms when the 5h window resets, or null when unknown. */
|
|
3060
|
+
sessionResetAt: number | null;
|
|
3061
|
+
/** Epoch ms when the 7d window resets, or null when unknown. */
|
|
3062
|
+
weeklyResetAt: number | null;
|
|
3063
|
+
/** Fraction (0..1) of the current 5h window this grant has already taken. */
|
|
3064
|
+
borrowedSessionFraction: number;
|
|
3065
|
+
/** Fraction (0..1) of the current 7d window this grant has already taken. */
|
|
3066
|
+
borrowedWeeklyFraction: number;
|
|
3067
|
+
};
|
|
3068
|
+
/**
|
|
3069
|
+
* A grant's consumption of the pool, normalised to one window's worth.
|
|
3070
|
+
*
|
|
3071
|
+
* `Σ per-account fractions / accountCount`, so 0.2 means the borrower has taken
|
|
3072
|
+
* a fifth of total pool capacity however it was spread across credentials.
|
|
3073
|
+
*/
|
|
3074
|
+
export type ProxySharePoolUsage = {
|
|
3075
|
+
sessionFraction: number;
|
|
3076
|
+
weeklyFraction: number;
|
|
3077
|
+
};
|
|
3078
|
+
/**
|
|
3079
|
+
* One borrower's outstanding request for a resident credential.
|
|
3080
|
+
*
|
|
3081
|
+
* Holds the challenge, never a verifier and never a token — the lender is not
|
|
3082
|
+
* in a position to leak what it does not have. `code` exists only between the
|
|
3083
|
+
* lender authorizing and the borrower claiming, and is erased by consumption.
|
|
3084
|
+
*/
|
|
3085
|
+
export type ProxyShareProvisionRequest = {
|
|
3086
|
+
schemaVersion: 1;
|
|
3087
|
+
grantId: string;
|
|
3088
|
+
/** Base64url SHA-256 of the borrower's verifier. */
|
|
3089
|
+
codeChallenge: string;
|
|
3090
|
+
challengeMethod: "S256";
|
|
3091
|
+
/** Borrower-chosen state, echoed through the authorization round trip. */
|
|
3092
|
+
state: string;
|
|
3093
|
+
requestedAt: number;
|
|
3094
|
+
expiresAt: number;
|
|
3095
|
+
status: ProxyShareProvisionStatus;
|
|
3096
|
+
/** Present only between authorization and the single claim that consumes it. */
|
|
3097
|
+
code?: string;
|
|
3098
|
+
authorizedAt?: number;
|
|
3099
|
+
claimedAt?: number;
|
|
3100
|
+
/** Which of the lender's accounts was authorized, for the drift audit. */
|
|
3101
|
+
accountLabel?: string;
|
|
3102
|
+
};
|
|
3103
|
+
export type ProxyShareProvisionStatus = "pending" | "authorized" | "consumed";
|
|
3104
|
+
export type ProxyShareProvisionFile = {
|
|
3105
|
+
schemaVersion: 1;
|
|
3106
|
+
requests: Record<string, ProxyShareProvisionRequest>;
|
|
3107
|
+
};
|
|
3108
|
+
/**
|
|
3109
|
+
* A lender's signed statement that one borrowed request was settled, and for
|
|
3110
|
+
* how much.
|
|
3111
|
+
*
|
|
3112
|
+
* `usage` travels with it so the borrower can recompute the charge from the
|
|
3113
|
+
* response it actually received, rather than taking the coin figure on faith.
|
|
3114
|
+
* `sequence` is contiguous per grant, so a withheld receipt shows up as a gap.
|
|
3115
|
+
*/
|
|
3116
|
+
export type ProxyShareReceipt = {
|
|
3117
|
+
schemaVersion: 1;
|
|
3118
|
+
grantId: string;
|
|
3119
|
+
/** Monotonic, contiguous, per grant. */
|
|
3120
|
+
sequence: number;
|
|
3121
|
+
settledAt: number;
|
|
3122
|
+
model?: string;
|
|
3123
|
+
usage: ProxyShareUsage;
|
|
3124
|
+
coins: number;
|
|
3125
|
+
/** Remaining balance after this charge; null on an unlimited grant. */
|
|
3126
|
+
balanceAfter: number | null;
|
|
3127
|
+
signature: string;
|
|
3128
|
+
};
|
|
3129
|
+
export type ProxyShareReceiptFile = {
|
|
3130
|
+
schemaVersion: 1;
|
|
3131
|
+
/** Per grant, oldest first, bounded. */
|
|
3132
|
+
receipts: Record<string, ProxyShareReceipt[]>;
|
|
3133
|
+
/** Cumulative coins each grant has had forgiven by netting. */
|
|
3134
|
+
netted: Record<string, number>;
|
|
3135
|
+
/**
|
|
3136
|
+
* Lifetime coins receipted per grant.
|
|
3137
|
+
*
|
|
3138
|
+
* Kept separately because `receipts` is trimmed: summing the retained history
|
|
3139
|
+
* would quietly under-count a busy grant, and netting reads this number.
|
|
3140
|
+
*/
|
|
3141
|
+
consumedTotal?: Record<string, number>;
|
|
3142
|
+
/**
|
|
3143
|
+
* Highest sequence issued per grant, for the same reason.
|
|
3144
|
+
*
|
|
3145
|
+
* Taking it from the retained tail is right only until the tail is trimmed
|
|
3146
|
+
* away, and a sequence that restarts would look like a replay to the
|
|
3147
|
+
* borrower's audit.
|
|
3148
|
+
*/
|
|
3149
|
+
highestSequence?: Record<string, number>;
|
|
3150
|
+
};
|
|
3151
|
+
/** What a borrower makes of the receipts it collected. */
|
|
3152
|
+
export type ProxyShareStatement = {
|
|
3153
|
+
grantId: string;
|
|
3154
|
+
receipts: number;
|
|
3155
|
+
coins: number;
|
|
3156
|
+
/** Receipts whose signature did not verify against the shared secret. */
|
|
3157
|
+
unverified: number;
|
|
3158
|
+
/** Receipts whose coin figure disagrees with its own usage block. */
|
|
3159
|
+
miscounted: number;
|
|
3160
|
+
/** Sequence numbers missing from an otherwise contiguous run. */
|
|
3161
|
+
gaps: number[];
|
|
3162
|
+
latestSequence: number;
|
|
3163
|
+
};
|
|
3164
|
+
/** One side's position in a reciprocal netting round. */
|
|
3165
|
+
export type ProxyShareNettingClaim = {
|
|
3166
|
+
/** Cumulative coins the *other* node has consumed under my grant to them. */
|
|
3167
|
+
consumedByYou: number;
|
|
3168
|
+
/** Cumulative coins already forgiven on my side, so a replay nets nothing. */
|
|
3169
|
+
alreadyNetted: number;
|
|
3170
|
+
signature: string;
|
|
3171
|
+
};
|
|
3172
|
+
export type ProxyShareNettingResult = {
|
|
3173
|
+
/** Coins forgiven in this round, on both sides. */
|
|
3174
|
+
netted: number;
|
|
3175
|
+
/** Cumulative total after this round. */
|
|
3176
|
+
totalNetted: number;
|
|
3177
|
+
detail: string;
|
|
3178
|
+
};
|
|
3179
|
+
/**
|
|
3180
|
+
* A bearer credit one node issued, which any node holding it may redeem against
|
|
3181
|
+
* the issuer.
|
|
3182
|
+
*
|
|
3183
|
+
* Signed by the issuer with a node-level secret, because the grant that
|
|
3184
|
+
* eventually redeems it need not have existed when it was issued.
|
|
3185
|
+
*/
|
|
3186
|
+
export type ProxyShareNote = {
|
|
3187
|
+
schemaVersion: 1;
|
|
3188
|
+
noteId: string;
|
|
3189
|
+
issuer: string;
|
|
3190
|
+
coins: number;
|
|
3191
|
+
issuedAt: number;
|
|
3192
|
+
notAfter: number;
|
|
3193
|
+
memo?: string;
|
|
3194
|
+
signature: string;
|
|
3195
|
+
};
|
|
3196
|
+
export type ProxyShareNoteStatus = "valid" | "spent" | "expired" | "unknown" | "forged";
|
|
3197
|
+
export type ProxyShareNoteRecord = {
|
|
3198
|
+
noteId: string;
|
|
3199
|
+
coins: number;
|
|
3200
|
+
issuedAt: number;
|
|
3201
|
+
notAfter: number;
|
|
3202
|
+
memo?: string;
|
|
3203
|
+
redeemedAt?: number;
|
|
3204
|
+
redeemedByGrant?: string;
|
|
3205
|
+
};
|
|
3206
|
+
export type ProxyShareNoteFile = {
|
|
3207
|
+
schemaVersion: 1;
|
|
3208
|
+
notes: Record<string, ProxyShareNoteRecord>;
|
|
3209
|
+
};
|
|
3210
|
+
/** The slice of a node HTTP server the proxy runtime actually closes. */
|
|
3211
|
+
export type ProxyClosableServer = {
|
|
3212
|
+
close?: (callback?: (error?: Error) => void) => void;
|
|
3213
|
+
};
|
|
3214
|
+
/** A running gate-only share listener, as its supervisor sees it. */
|
|
3215
|
+
export type ProxyShareListenerHandle = {
|
|
3216
|
+
port: number;
|
|
3217
|
+
close: () => Promise<void>;
|
|
3218
|
+
};
|
|
3219
|
+
/** Result of lodging or authorizing a split-PKCE provisioning request. */
|
|
3220
|
+
export type ProxyShareProvisionOutcome = {
|
|
3221
|
+
ok: true;
|
|
3222
|
+
request: ProxyShareProvisionRequest;
|
|
3223
|
+
} | {
|
|
3224
|
+
ok: false;
|
|
3225
|
+
reason: string;
|
|
3226
|
+
};
|
|
3227
|
+
/** Result of authenticating a `/peer/*` caller by its share token. */
|
|
3228
|
+
export type ProxyPeerAuthOutcome = {
|
|
3229
|
+
ok: true;
|
|
3230
|
+
grant: ProxyShareGrant;
|
|
3231
|
+
} | {
|
|
3232
|
+
ok: false;
|
|
3233
|
+
body: ProxyShareRefusalResponse["body"];
|
|
3234
|
+
};
|
|
3235
|
+
/** What a borrower gets back when its authorization code is ready to collect. */
|
|
3236
|
+
export type ProxyShareProvisionClaim = {
|
|
3237
|
+
code: string;
|
|
3238
|
+
state: string;
|
|
3239
|
+
accountLabel: string;
|
|
3240
|
+
leaseSecret: string;
|
|
3241
|
+
lease: ProxyShareLease;
|
|
3242
|
+
lenderUrl: string;
|
|
3243
|
+
};
|
|
3244
|
+
/** The verifier a borrower is holding while it waits to be authorized. */
|
|
3245
|
+
export type ProxyPeerPendingProvision = {
|
|
3246
|
+
codeVerifier: string;
|
|
3247
|
+
state: string;
|
|
3248
|
+
requestedAt: number;
|
|
3249
|
+
};
|
|
3250
|
+
/**
|
|
3251
|
+
* What `GET /peer/limits` tells a borrower.
|
|
3252
|
+
*
|
|
3253
|
+
* Scoped to the caller's own grant on purpose: it carries no account labels and
|
|
3254
|
+
* no per-account figures, so it cannot be used to describe — or count — the
|
|
3255
|
+
* lender's pool. `null` on a slice means no ceiling is configured for that
|
|
3256
|
+
* window, which is different from a ceiling with nothing left.
|
|
3257
|
+
*/
|
|
3258
|
+
export type ProxyPeerLimitsSnapshot = {
|
|
3259
|
+
grantState: ProxyShareGrantState;
|
|
3260
|
+
level: ProxyShareLevel;
|
|
3261
|
+
ledger: ProxyShareLedgerMode;
|
|
3262
|
+
remainingCoins?: number;
|
|
3263
|
+
/** Whether at least one of the lender's accounts can serve this grant now. */
|
|
3264
|
+
servable: boolean;
|
|
3265
|
+
withheldReason?: ProxyShareRefusalReason;
|
|
3266
|
+
sliceLeftPct: {
|
|
3267
|
+
session: number | null;
|
|
3268
|
+
weekly: number | null;
|
|
3269
|
+
};
|
|
3270
|
+
retryAfterSeconds?: number;
|
|
3271
|
+
};
|
|
3272
|
+
/** Why one account was withheld from a grant. */
|
|
3273
|
+
export type ProxyShareAccountExclusion = {
|
|
3274
|
+
accountKey: string;
|
|
3275
|
+
reason: ProxyShareRefusalReason;
|
|
3276
|
+
};
|
|
3277
|
+
export type ProxyShareAccountFilterResult = {
|
|
3278
|
+
allowed: string[];
|
|
3279
|
+
excluded: ProxyShareAccountExclusion[];
|
|
3280
|
+
};
|
|
3281
|
+
/** A refusal rendered for the wire: status, headers and Anthropic-shaped body. */
|
|
3282
|
+
export type ProxyShareRefusalResponse = {
|
|
3283
|
+
status: number;
|
|
3284
|
+
headers: Record<string, string>;
|
|
3285
|
+
body: {
|
|
3286
|
+
type: "error";
|
|
3287
|
+
error: {
|
|
3288
|
+
type: string;
|
|
3289
|
+
message: string;
|
|
3290
|
+
};
|
|
3291
|
+
};
|
|
3292
|
+
};
|
|
3293
|
+
/**
|
|
3294
|
+
* What the inbound gate decided.
|
|
3295
|
+
*
|
|
3296
|
+
* `local` is the unauthenticated path a node's own client takes on loopback; it
|
|
3297
|
+
* carries no grant and no accounting. `admitted` owns a concurrency slot that
|
|
3298
|
+
* the caller must release. `refused` is ready to write to the wire as-is.
|
|
3299
|
+
*/
|
|
3300
|
+
export type ProxyShareGateOutcome = {
|
|
3301
|
+
kind: "local";
|
|
3302
|
+
} | {
|
|
3303
|
+
kind: "admitted";
|
|
3304
|
+
context: ProxyShareRequestContext;
|
|
3305
|
+
release: () => void;
|
|
3306
|
+
} | {
|
|
3307
|
+
kind: "refused";
|
|
3308
|
+
response: ProxyShareRefusalResponse;
|
|
3309
|
+
};
|
|
3310
|
+
/** Per-grant sliding-window request timestamps and in-flight count. */
|
|
3311
|
+
export type ProxyShareGrantCounters = {
|
|
3312
|
+
timestamps: number[];
|
|
3313
|
+
inFlight: number;
|
|
3314
|
+
};
|
|
3315
|
+
/** Model-weighted token usage settled against a grant. */
|
|
3316
|
+
export type ProxyShareUsage = {
|
|
3317
|
+
inputTokens: number;
|
|
3318
|
+
outputTokens: number;
|
|
3319
|
+
cacheCreationTokens?: number;
|
|
3320
|
+
cacheReadTokens?: number;
|
|
3321
|
+
};
|
|
3322
|
+
/**
|
|
3323
|
+
* One grant's consumption of one account's current windows.
|
|
3324
|
+
*
|
|
3325
|
+
* Keyed by the window's reset timestamp so a reset starts a fresh bucket
|
|
3326
|
+
* automatically — without that, a slice ceiling would latch permanently after
|
|
3327
|
+
* the first busy window.
|
|
3328
|
+
*/
|
|
3329
|
+
export type ProxyShareLedgerBucket = {
|
|
3330
|
+
grantId: string;
|
|
3331
|
+
accountKey: string;
|
|
3332
|
+
sessionResetAt: number | null;
|
|
3333
|
+
weeklyResetAt: number | null;
|
|
3334
|
+
/** Accumulated 5h-window utilization attributable to this grant (0..1). */
|
|
3335
|
+
sessionFraction: number;
|
|
3336
|
+
/** Accumulated 7d-window utilization attributable to this grant (0..1). */
|
|
3337
|
+
weeklyFraction: number;
|
|
3338
|
+
coinsSpent: number;
|
|
3339
|
+
requests: number;
|
|
3340
|
+
updatedAt: number;
|
|
3341
|
+
};
|
|
3342
|
+
export type ProxyShareLedgerFile = {
|
|
3343
|
+
schemaVersion: 1;
|
|
3344
|
+
buckets: Record<string, ProxyShareLedgerBucket>;
|
|
3345
|
+
};
|
|
3346
|
+
/** An open pre-authorization against a grant's balance. */
|
|
3347
|
+
export type ProxyShareHold = {
|
|
3348
|
+
id: string;
|
|
3349
|
+
grantId: string;
|
|
3350
|
+
coins: number;
|
|
3351
|
+
openedAt: number;
|
|
3352
|
+
};
|
|
3353
|
+
/** Coin settlement for a finished borrowed request. */
|
|
3354
|
+
export type ProxyShareSettlement = {
|
|
3355
|
+
grantId: string;
|
|
3356
|
+
accountKey: string;
|
|
3357
|
+
model?: string;
|
|
3358
|
+
usage: ProxyShareUsage;
|
|
3359
|
+
holdId?: string;
|
|
3360
|
+
};
|
|
3361
|
+
/**
|
|
3362
|
+
* A before/after utilization observation for one borrowed request.
|
|
3363
|
+
*
|
|
3364
|
+
* Recorded where the response's quota headers are parsed, because that is the
|
|
3365
|
+
* only point at which both the previous snapshot and the new one are in hand.
|
|
3366
|
+
* Token usage settles separately: on a stream it is not known until
|
|
3367
|
+
* `message_delta`, long after the headers arrived.
|
|
3368
|
+
*/
|
|
3369
|
+
export type ProxyShareWindowObservation = {
|
|
3370
|
+
grantId: string;
|
|
3371
|
+
accountKey: string;
|
|
3372
|
+
sessionBefore?: number | null;
|
|
3373
|
+
sessionAfter?: number | null;
|
|
3374
|
+
sessionResetAt?: number | null;
|
|
3375
|
+
weeklyBefore?: number | null;
|
|
3376
|
+
weeklyAfter?: number | null;
|
|
3377
|
+
weeklyResetAt?: number | null;
|
|
3378
|
+
};
|
|
3379
|
+
/** Per-grant rollup for `share status`. */
|
|
3380
|
+
export type ProxyShareGrantUsageSummary = {
|
|
3381
|
+
grantId: string;
|
|
3382
|
+
coinsSpent: number;
|
|
3383
|
+
requests: number;
|
|
3384
|
+
accounts: number;
|
|
3385
|
+
lastUsedAt: number | null;
|
|
3386
|
+
};
|
|
3387
|
+
/** Why a peer is temporarily not worth trying. */
|
|
3388
|
+
export type ProxyPeerCooldownReason = "exhausted" | "paused" | "revoked" | "expired" | "withheld" | "unreachable" | "upstream_error";
|
|
3389
|
+
/** Last thing a peer told us, kept so `peer status` can answer offline. */
|
|
3390
|
+
export type ProxyPeerObservation = {
|
|
3391
|
+
grantStatus?: string;
|
|
3392
|
+
grantReason?: string;
|
|
3393
|
+
remainingCoins?: number;
|
|
3394
|
+
observedAt: number;
|
|
3395
|
+
};
|
|
3396
|
+
/** A lender this node may borrow from. */
|
|
3397
|
+
export type ProxyPeer = {
|
|
3398
|
+
schemaVersion: 1;
|
|
3399
|
+
name: string;
|
|
3400
|
+
url: string;
|
|
3401
|
+
token: string;
|
|
3402
|
+
/** Lower is tried first. Peers of equal priority keep insertion order. */
|
|
3403
|
+
priority: number;
|
|
3404
|
+
enabled: boolean;
|
|
3405
|
+
createdAt: number;
|
|
3406
|
+
updatedAt: number;
|
|
3407
|
+
note?: string;
|
|
3408
|
+
lastUsedAt?: number;
|
|
3409
|
+
cooldownUntil?: number;
|
|
3410
|
+
cooldownReason?: ProxyPeerCooldownReason;
|
|
3411
|
+
lastObservation?: ProxyPeerObservation;
|
|
3412
|
+
/** Set while a split-PKCE provisioning request is outstanding. */
|
|
3413
|
+
pendingProvision?: ProxyPeerPendingProvision;
|
|
3414
|
+
/** Shared secret this lender's receipts are signed with, when known. */
|
|
3415
|
+
receiptSecret?: string;
|
|
3416
|
+
/** Label of the grant this node issued to the same person, for netting. */
|
|
3417
|
+
reciprocalPeer?: string;
|
|
3418
|
+
/** Highest receipt sequence collected from this lender. */
|
|
3419
|
+
lastReceiptSequence?: number;
|
|
3420
|
+
};
|
|
3421
|
+
export type ProxyPeerFile = {
|
|
3422
|
+
schemaVersion: 1;
|
|
3423
|
+
peers: Record<string, ProxyPeer>;
|
|
3424
|
+
};
|
|
3425
|
+
/** Outcome of forwarding one request to one peer. */
|
|
3426
|
+
export type ProxyPeerAttempt = {
|
|
3427
|
+
ok: true;
|
|
3428
|
+
response: Response;
|
|
3429
|
+
peer: ProxyPeer;
|
|
3430
|
+
} | {
|
|
3431
|
+
ok: false;
|
|
3432
|
+
peer: ProxyPeer;
|
|
3433
|
+
status?: number;
|
|
3434
|
+
reason: ProxyPeerCooldownReason;
|
|
3435
|
+
message: string;
|
|
3436
|
+
retryAfterSeconds?: number;
|
|
3437
|
+
};
|
|
3438
|
+
/** What `peer add` accepts. */
|
|
3439
|
+
export type ProxyPeerInput = {
|
|
3440
|
+
name: string;
|
|
3441
|
+
url: string;
|
|
3442
|
+
token: string;
|
|
3443
|
+
/** Shared secret this lender signs receipts with, when the link carried one. */
|
|
3444
|
+
receiptSecret?: string;
|
|
3445
|
+
priority?: number;
|
|
3446
|
+
note?: string;
|
|
3447
|
+
};
|
|
3448
|
+
export type ProxyPeerArgs = {
|
|
3449
|
+
action?: "add" | "request" | "list" | "status" | "sync" | "receipts" | "net" | "redeem" | "test" | "remove" | "pause" | "resume" | "set";
|
|
3450
|
+
/** `peer request --claim`: collect a code the lender has authorized. */
|
|
3451
|
+
claim?: boolean;
|
|
3452
|
+
/** Shared secret for verifying this lender's receipts, when added by hand. */
|
|
3453
|
+
receiptSecret?: string;
|
|
3454
|
+
/** `peer net`: label of the grant this node issued to the same person. */
|
|
3455
|
+
reciprocal?: string;
|
|
3456
|
+
/** `peer redeem`: the coin note to present. */
|
|
3457
|
+
noteValue?: string;
|
|
3458
|
+
/** `peer redeem --check`: ask the issuer about a note without spending it. */
|
|
3459
|
+
check?: boolean;
|
|
3460
|
+
/** Local account label for a provisioned credential. */
|
|
3461
|
+
label?: string;
|
|
3462
|
+
name?: string;
|
|
3463
|
+
url?: string;
|
|
3464
|
+
token?: string;
|
|
3465
|
+
link?: string;
|
|
3466
|
+
priority?: number;
|
|
3467
|
+
note?: string;
|
|
3468
|
+
json?: boolean;
|
|
3469
|
+
dev?: boolean;
|
|
3470
|
+
};
|
|
3471
|
+
/**
|
|
3472
|
+
* The offline-survivable projection of a grant.
|
|
3473
|
+
*
|
|
3474
|
+
* A complete-mode borrower holds a credential on the lender's account and calls
|
|
3475
|
+
* the upstream directly, so the lender's gate is not in the request path. The
|
|
3476
|
+
* lease is what control looks like without that gate: the borrower enforces it
|
|
3477
|
+
* locally, refreshes it by heartbeat, and stops when it can no longer prove the
|
|
3478
|
+
* lender still consents.
|
|
3479
|
+
*/
|
|
3480
|
+
export type ProxyShareLease = {
|
|
3481
|
+
schemaVersion: 1;
|
|
3482
|
+
grantId: string;
|
|
3483
|
+
peerLabel: string;
|
|
3484
|
+
issuedAt: number;
|
|
3485
|
+
/** Hard stop, honored even by a borrower that never calls home again. */
|
|
3486
|
+
notAfter: number;
|
|
3487
|
+
/** How often the borrower should check in. */
|
|
3488
|
+
heartbeatEveryMs: number;
|
|
3489
|
+
/** How long the borrower may keep serving while the lender is unreachable. */
|
|
3490
|
+
offlineGraceMs: number;
|
|
3491
|
+
/** The gate set, snapshotted at issue time. */
|
|
3492
|
+
gates: ProxyShareGates;
|
|
3493
|
+
/** Coin balance at issue time; "unlimited" for an uncapped grant. */
|
|
3494
|
+
entitlementSnapshot: number | "unlimited";
|
|
3495
|
+
/** HMAC over the payload, keyed by the grant's lease secret. */
|
|
3496
|
+
signature: string;
|
|
3497
|
+
};
|
|
3498
|
+
/** Why a lease is not currently usable. */
|
|
3499
|
+
export type ProxyShareLeaseVerdict = {
|
|
3500
|
+
usable: true;
|
|
3501
|
+
nextHeartbeatDueAt: number;
|
|
3502
|
+
} | {
|
|
3503
|
+
usable: false;
|
|
3504
|
+
reason: "unsigned" | "expired" | "grace_elapsed" | "stopped";
|
|
3505
|
+
detail: string;
|
|
3506
|
+
};
|
|
3507
|
+
/** The refusing half of {@link ProxyShareLeaseVerdict}. */
|
|
3508
|
+
export type ProxyShareLeaseRefusal = Extract<ProxyShareLeaseVerdict, {
|
|
3509
|
+
usable: false;
|
|
3510
|
+
}>;
|
|
3511
|
+
/** What a borrower sends when checking in. */
|
|
3512
|
+
export type ProxyShareHeartbeatRequest = {
|
|
3513
|
+
grantId: string;
|
|
3514
|
+
/** Coins the borrower believes it has spent since the last heartbeat. */
|
|
3515
|
+
coinsSpent?: number;
|
|
3516
|
+
requests?: number;
|
|
3517
|
+
/** Borrower's clock, for drift diagnostics only. */
|
|
3518
|
+
reportedAt: number;
|
|
3519
|
+
};
|
|
3520
|
+
/** What the lender answers with. */
|
|
3521
|
+
export type ProxyShareHeartbeatResponse = {
|
|
3522
|
+
ok: true;
|
|
3523
|
+
lease: ProxyShareLease;
|
|
3524
|
+
} | {
|
|
3525
|
+
ok: false;
|
|
3526
|
+
stop: true;
|
|
3527
|
+
reason: string;
|
|
3528
|
+
};
|
|
3529
|
+
/** The stopping half of {@link ProxyShareHeartbeatResponse}. */
|
|
3530
|
+
export type ProxyShareHeartbeatStop = Extract<ProxyShareHeartbeatResponse, {
|
|
3531
|
+
ok: false;
|
|
3532
|
+
}>;
|
|
3533
|
+
/** The renewing half of {@link ProxyShareHeartbeatResponse}. */
|
|
3534
|
+
export type ProxyShareHeartbeatRenewal = Extract<ProxyShareHeartbeatResponse, {
|
|
3535
|
+
ok: true;
|
|
3536
|
+
}>;
|
|
3537
|
+
/** A credential provisioned onto a borrower's device under a complete grant. */
|
|
3538
|
+
export type ProxyResidentGrant = {
|
|
3539
|
+
schemaVersion: 1;
|
|
3540
|
+
/** Local tokenStore label, unique on the borrower's device. */
|
|
3541
|
+
accountLabel: string;
|
|
3542
|
+
grantId: string;
|
|
3543
|
+
lenderName: string;
|
|
3544
|
+
lenderUrl: string;
|
|
3545
|
+
/** Shared secret used to verify leases from this lender. */
|
|
3546
|
+
leaseSecret: string;
|
|
3547
|
+
lease: ProxyShareLease;
|
|
3548
|
+
lastHeartbeatAt?: number;
|
|
3549
|
+
/** Coins spent since the last successful heartbeat, awaiting report. */
|
|
3550
|
+
unreportedCoins?: number;
|
|
3551
|
+
unreportedRequests?: number;
|
|
3552
|
+
};
|
|
3553
|
+
export type ProxyResidentGrantFile = {
|
|
3554
|
+
schemaVersion: 1;
|
|
3555
|
+
grants: Record<string, ProxyResidentGrant>;
|
|
3556
|
+
};
|
|
3557
|
+
/**
|
|
3558
|
+
* One heartbeat's worth of evidence about a complete-mode grant.
|
|
3559
|
+
*
|
|
3560
|
+
* The lender cannot see a resident credential's requests — they never touch this
|
|
3561
|
+
* node. What it *can* see is the account's own utilization, which the provider
|
|
3562
|
+
* reports and the borrower cannot influence. Pairing that with what the borrower
|
|
3563
|
+
* claimed to spend is the whole audit.
|
|
3564
|
+
*/
|
|
3565
|
+
export type ProxyShareAuditObservation = {
|
|
3566
|
+
at: number;
|
|
3567
|
+
/** 0..1 utilization of the account's 5h window at this heartbeat. */
|
|
3568
|
+
sessionUsed: number | null;
|
|
3569
|
+
/** 0..1 utilization of the account's 7d window at this heartbeat. */
|
|
3570
|
+
weeklyUsed: number | null;
|
|
3571
|
+
/** Coins the borrower reported since the previous heartbeat. */
|
|
3572
|
+
reportedCoins: number;
|
|
3573
|
+
/** Requests this node itself served on the account **since the previous
|
|
3574
|
+
* observation**. A per-interval delta, not a running total: the drift check
|
|
3575
|
+
* asks whether the lender used the account during this interval. */
|
|
3576
|
+
lenderRequests: number;
|
|
3577
|
+
};
|
|
3578
|
+
/** Rolling audit state for one complete-mode grant. */
|
|
3579
|
+
export type ProxyShareAuditRecord = {
|
|
3580
|
+
grantId: string;
|
|
3581
|
+
/** The lender's own account the credential was provisioned from. */
|
|
3582
|
+
accountLabel: string;
|
|
3583
|
+
lastObservation?: ProxyShareAuditObservation;
|
|
3584
|
+
/** Running lifetime total of lender-served requests on the account, kept so
|
|
3585
|
+
* the next observation's delta can be computed. */
|
|
3586
|
+
lenderRequestsTotal?: number;
|
|
3587
|
+
/** Consecutive heartbeats where the account moved but nothing was reported. */
|
|
3588
|
+
driftStreak: number;
|
|
3589
|
+
lastDriftAt?: number;
|
|
3590
|
+
lastDriftDetail?: string;
|
|
3591
|
+
/** Set once the streak crossed the tolerance and the grant was paused. */
|
|
3592
|
+
autoPausedAt?: number;
|
|
3593
|
+
};
|
|
3594
|
+
export type ProxyShareAuditFile = {
|
|
3595
|
+
schemaVersion: 1;
|
|
3596
|
+
records: Record<string, ProxyShareAuditRecord>;
|
|
3597
|
+
};
|
|
3598
|
+
/** The verdict of comparing one heartbeat against the account's real movement. */
|
|
3599
|
+
export type ProxyShareDriftVerdict = {
|
|
3600
|
+
drifted: false;
|
|
3601
|
+
reason: "no_baseline" | "attributable" | "quiet";
|
|
3602
|
+
} | {
|
|
3603
|
+
drifted: true;
|
|
3604
|
+
/** How much of a window moved without being accounted for. */
|
|
3605
|
+
unexplainedSessionPct: number;
|
|
3606
|
+
unexplainedWeeklyPct: number;
|
|
3607
|
+
detail: string;
|
|
3608
|
+
};
|
|
3609
|
+
/** The handover artifact a lender gives a complete-share borrower. */
|
|
3610
|
+
export type ProxyShareProvisioningBundle = {
|
|
3611
|
+
schemaVersion: 1;
|
|
3612
|
+
grantId: string;
|
|
3613
|
+
lenderName: string;
|
|
3614
|
+
lenderUrl: string;
|
|
3615
|
+
accountLabel: string;
|
|
3616
|
+
leaseSecret: string;
|
|
3617
|
+
lease: ProxyShareLease;
|
|
3618
|
+
tokens: {
|
|
3619
|
+
accessToken: string;
|
|
3620
|
+
refreshToken?: string;
|
|
3621
|
+
expiresAt?: number;
|
|
3622
|
+
};
|
|
3623
|
+
};
|