@stacknet/keyutils 0.4.8 → 0.6.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/components/index.cjs +2 -2
- package/dist/components/index.d.cts +103 -15
- package/dist/components/index.d.ts +103 -15
- package/dist/components/index.js +2 -2
- package/dist/core/index.cjs +1 -1
- package/dist/core/index.js +1 -1
- package/dist/hooks/index.cjs +2 -2
- package/dist/hooks/index.d.cts +136 -8
- package/dist/hooks/index.d.ts +136 -8
- package/dist/hooks/index.js +2 -2
- package/dist/index.cjs +2 -2
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +2 -2
- package/dist/types/index.d.cts +122 -1
- package/dist/types/index.d.ts +122 -1
- package/dist/utils/index.cjs +1 -1
- package/dist/utils/index.d.cts +58 -3
- package/dist/utils/index.d.ts +58 -3
- package/dist/utils/index.js +1 -1
- package/package.json +1 -1
package/dist/types/index.d.cts
CHANGED
|
@@ -72,14 +72,17 @@ interface DirectTransferResult {
|
|
|
72
72
|
transferredAt: number;
|
|
73
73
|
}
|
|
74
74
|
type FilingStatus = 'submitted' | 'validated' | 'paid' | 'failed';
|
|
75
|
+
type PayoutMethod = 'usdc' | 'stripe';
|
|
75
76
|
interface FilingResult {
|
|
76
77
|
keyId: string;
|
|
78
|
+
filingId: string;
|
|
77
79
|
fileHash: string;
|
|
78
80
|
txSignature?: string;
|
|
79
81
|
paperAmount: number;
|
|
80
82
|
status: FilingStatus;
|
|
81
83
|
beneficiary: string;
|
|
82
84
|
filedAt: string;
|
|
85
|
+
payoutMethod?: PayoutMethod;
|
|
83
86
|
}
|
|
84
87
|
interface FilingHistoryEntry extends FilingResult {
|
|
85
88
|
proofPda?: string;
|
|
@@ -89,6 +92,124 @@ interface FilingHistoryEntry extends FilingResult {
|
|
|
89
92
|
type EligibleKey = NodeKeyInfo & {
|
|
90
93
|
paperWork: string;
|
|
91
94
|
};
|
|
95
|
+
type PayoutAccountMethod = 'stripe' | 'solana';
|
|
96
|
+
/**
|
|
97
|
+
* The user's saved payout config in the context of one stack.
|
|
98
|
+
*
|
|
99
|
+
* Stripe Connect is per-(user, stack) — each stack runs its own platform
|
|
100
|
+
* under its own secret, so a given user has independent connected accounts
|
|
101
|
+
* across stacks. The `stripe` field reflects the connection for the SCOPE
|
|
102
|
+
* stack only; query other stacks via `useUserStripeStacks()` or by passing
|
|
103
|
+
* a different `stackId` to `usePayoutAccount`.
|
|
104
|
+
*
|
|
105
|
+
* The Solana wallet is global (one verified address services every stack).
|
|
106
|
+
*
|
|
107
|
+
* `method` records the user's preferred rail. The active filing flow
|
|
108
|
+
* verifies the chosen rail is configured for the key's originating stack
|
|
109
|
+
* and falls back to a clear error if not.
|
|
110
|
+
*/
|
|
111
|
+
interface PayoutAccount {
|
|
112
|
+
/** Which method is currently configured. `null` when nothing is set up. */
|
|
113
|
+
method: PayoutAccountMethod | null;
|
|
114
|
+
stripe?: {
|
|
115
|
+
/** acct_*. Masked for display. */
|
|
116
|
+
accountIdMasked: string;
|
|
117
|
+
/** Stripe-reported flags from `accounts.retrieve`. */
|
|
118
|
+
chargesEnabled: boolean;
|
|
119
|
+
payoutsEnabled: boolean;
|
|
120
|
+
detailsSubmitted: boolean;
|
|
121
|
+
/** When non-null, the user needs to finish onboarding at this URL. */
|
|
122
|
+
pendingOnboardingUrl?: string | null;
|
|
123
|
+
/** Stack whose Stripe platform credentials are driving this connection. */
|
|
124
|
+
stackId: string;
|
|
125
|
+
updatedAt: string;
|
|
126
|
+
};
|
|
127
|
+
solana?: {
|
|
128
|
+
addressMasked: string;
|
|
129
|
+
/** Full address — safe to expose since the proof of control is on the
|
|
130
|
+
* server (we verified the signature). The client uses this to display. */
|
|
131
|
+
address: string;
|
|
132
|
+
verifiedAt: string;
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* One stack the user has a Stripe Connect account on. Returned by
|
|
137
|
+
* `useUserStripeStacks()` for the multi-stack settings view.
|
|
138
|
+
*/
|
|
139
|
+
interface StripeStackPayout {
|
|
140
|
+
stackId: string;
|
|
141
|
+
accountIdMasked: string;
|
|
142
|
+
chargesEnabled: boolean;
|
|
143
|
+
payoutsEnabled: boolean;
|
|
144
|
+
detailsSubmitted: boolean;
|
|
145
|
+
pendingOnboardingUrl?: string | null;
|
|
146
|
+
updatedAt: string;
|
|
147
|
+
}
|
|
148
|
+
interface CryptoNonceResponse {
|
|
149
|
+
nonce: string;
|
|
150
|
+
/** Canonical message the wallet must sign — includes the nonce. */
|
|
151
|
+
message: string;
|
|
152
|
+
expiresAt: string;
|
|
153
|
+
}
|
|
154
|
+
interface StripeConnectStartResponse {
|
|
155
|
+
accountIdMasked: string;
|
|
156
|
+
/** Hosted Stripe AccountLink URL — redirect the user here. */
|
|
157
|
+
onboardingUrl: string;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Per-stack payout configuration, as resolved by stacknet from the stack's
|
|
161
|
+
* config + secrets. Drives the payout-method picker and locks the destination.
|
|
162
|
+
*/
|
|
163
|
+
interface StackPayoutCapabilities {
|
|
164
|
+
stackId: string;
|
|
165
|
+
stackName: string;
|
|
166
|
+
stripe: {
|
|
167
|
+
enabled: boolean;
|
|
168
|
+
/** Human-readable reason when disabled (rendered as "disabled by {stackName} stack" UX). */
|
|
169
|
+
disabledReason?: string;
|
|
170
|
+
/** Masked / display-only descriptor — never the raw account id. */
|
|
171
|
+
destinationLabel?: string;
|
|
172
|
+
};
|
|
173
|
+
usdc: {
|
|
174
|
+
enabled: boolean;
|
|
175
|
+
disabledReason?: string;
|
|
176
|
+
/** Resolved on-chain payout address from the stack config. */
|
|
177
|
+
defaultDestination: string;
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
type FilingTrackerStep = 'sent' | 'routed' | 'confirmed' | 'finalized' | 'filed';
|
|
181
|
+
type FilingTrackerStatus = 'pending' | 'current' | 'done' | 'failed';
|
|
182
|
+
interface FilingTrackerState {
|
|
183
|
+
id: FilingTrackerStep;
|
|
184
|
+
label: string;
|
|
185
|
+
status: FilingTrackerStatus;
|
|
186
|
+
timestampMs: number | null;
|
|
187
|
+
detail: string | null;
|
|
188
|
+
approvalsCount?: number;
|
|
189
|
+
approvalsThreshold?: number;
|
|
190
|
+
/** Optional outbound link (Solscan / Stripe dashboard). */
|
|
191
|
+
externalUrl?: string;
|
|
192
|
+
}
|
|
193
|
+
interface FilingDetail extends FilingResult {
|
|
194
|
+
payoutMethod: PayoutMethod;
|
|
195
|
+
/** Server-supplied; not editable from the client. */
|
|
196
|
+
memo: string;
|
|
197
|
+
/** Server-supplied; not editable from the client. USDC raw units (string to avoid bigint loss). */
|
|
198
|
+
amountUsdc: string;
|
|
199
|
+
tokensUsed: string;
|
|
200
|
+
tracker: FilingTrackerState[];
|
|
201
|
+
proofPda?: string;
|
|
202
|
+
intentHashHex?: string;
|
|
203
|
+
stripePaymentIntentId?: string;
|
|
204
|
+
failureReason?: string;
|
|
205
|
+
/**
|
|
206
|
+
* The Solana wallet recorded as the intent's beneficiary on-chain. For
|
|
207
|
+
* usdc filings this matches `beneficiary`; for stripe filings the
|
|
208
|
+
* `beneficiary` is the off-chain Stripe account id and this is the
|
|
209
|
+
* wallet the resolver uses to look up the credentials mapping.
|
|
210
|
+
*/
|
|
211
|
+
onchainBeneficiary?: string;
|
|
212
|
+
}
|
|
92
213
|
type Platform = 'ios' | 'android' | 'windows' | 'mac' | 'linux';
|
|
93
214
|
interface PlatformDownload {
|
|
94
215
|
platform: Platform;
|
|
@@ -125,4 +246,4 @@ interface KeyUtilsCallbacks {
|
|
|
125
246
|
onFilingError?: (error: Error) => void;
|
|
126
247
|
}
|
|
127
248
|
|
|
128
|
-
export type { DirectTransferResult, EligibleKey, FilingHistoryEntry, FilingResult, FilingStatus, KeyListing, KeyUtilsCallbacks, KeyUtilsConfig, KeyWidgetTab, LedgerEntry, ListingResult, MintResult, NodeKeyInfo, PaymentMethod, Platform, PlatformDownload, PricingInfo };
|
|
249
|
+
export type { CryptoNonceResponse, DirectTransferResult, EligibleKey, FilingDetail, FilingHistoryEntry, FilingResult, FilingStatus, FilingTrackerState, FilingTrackerStatus, FilingTrackerStep, KeyListing, KeyUtilsCallbacks, KeyUtilsConfig, KeyWidgetTab, LedgerEntry, ListingResult, MintResult, NodeKeyInfo, PaymentMethod, PayoutAccount, PayoutAccountMethod, PayoutMethod, Platform, PlatformDownload, PricingInfo, StackPayoutCapabilities, StripeConnectStartResponse, StripeStackPayout };
|
package/dist/types/index.d.ts
CHANGED
|
@@ -72,14 +72,17 @@ interface DirectTransferResult {
|
|
|
72
72
|
transferredAt: number;
|
|
73
73
|
}
|
|
74
74
|
type FilingStatus = 'submitted' | 'validated' | 'paid' | 'failed';
|
|
75
|
+
type PayoutMethod = 'usdc' | 'stripe';
|
|
75
76
|
interface FilingResult {
|
|
76
77
|
keyId: string;
|
|
78
|
+
filingId: string;
|
|
77
79
|
fileHash: string;
|
|
78
80
|
txSignature?: string;
|
|
79
81
|
paperAmount: number;
|
|
80
82
|
status: FilingStatus;
|
|
81
83
|
beneficiary: string;
|
|
82
84
|
filedAt: string;
|
|
85
|
+
payoutMethod?: PayoutMethod;
|
|
83
86
|
}
|
|
84
87
|
interface FilingHistoryEntry extends FilingResult {
|
|
85
88
|
proofPda?: string;
|
|
@@ -89,6 +92,124 @@ interface FilingHistoryEntry extends FilingResult {
|
|
|
89
92
|
type EligibleKey = NodeKeyInfo & {
|
|
90
93
|
paperWork: string;
|
|
91
94
|
};
|
|
95
|
+
type PayoutAccountMethod = 'stripe' | 'solana';
|
|
96
|
+
/**
|
|
97
|
+
* The user's saved payout config in the context of one stack.
|
|
98
|
+
*
|
|
99
|
+
* Stripe Connect is per-(user, stack) — each stack runs its own platform
|
|
100
|
+
* under its own secret, so a given user has independent connected accounts
|
|
101
|
+
* across stacks. The `stripe` field reflects the connection for the SCOPE
|
|
102
|
+
* stack only; query other stacks via `useUserStripeStacks()` or by passing
|
|
103
|
+
* a different `stackId` to `usePayoutAccount`.
|
|
104
|
+
*
|
|
105
|
+
* The Solana wallet is global (one verified address services every stack).
|
|
106
|
+
*
|
|
107
|
+
* `method` records the user's preferred rail. The active filing flow
|
|
108
|
+
* verifies the chosen rail is configured for the key's originating stack
|
|
109
|
+
* and falls back to a clear error if not.
|
|
110
|
+
*/
|
|
111
|
+
interface PayoutAccount {
|
|
112
|
+
/** Which method is currently configured. `null` when nothing is set up. */
|
|
113
|
+
method: PayoutAccountMethod | null;
|
|
114
|
+
stripe?: {
|
|
115
|
+
/** acct_*. Masked for display. */
|
|
116
|
+
accountIdMasked: string;
|
|
117
|
+
/** Stripe-reported flags from `accounts.retrieve`. */
|
|
118
|
+
chargesEnabled: boolean;
|
|
119
|
+
payoutsEnabled: boolean;
|
|
120
|
+
detailsSubmitted: boolean;
|
|
121
|
+
/** When non-null, the user needs to finish onboarding at this URL. */
|
|
122
|
+
pendingOnboardingUrl?: string | null;
|
|
123
|
+
/** Stack whose Stripe platform credentials are driving this connection. */
|
|
124
|
+
stackId: string;
|
|
125
|
+
updatedAt: string;
|
|
126
|
+
};
|
|
127
|
+
solana?: {
|
|
128
|
+
addressMasked: string;
|
|
129
|
+
/** Full address — safe to expose since the proof of control is on the
|
|
130
|
+
* server (we verified the signature). The client uses this to display. */
|
|
131
|
+
address: string;
|
|
132
|
+
verifiedAt: string;
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* One stack the user has a Stripe Connect account on. Returned by
|
|
137
|
+
* `useUserStripeStacks()` for the multi-stack settings view.
|
|
138
|
+
*/
|
|
139
|
+
interface StripeStackPayout {
|
|
140
|
+
stackId: string;
|
|
141
|
+
accountIdMasked: string;
|
|
142
|
+
chargesEnabled: boolean;
|
|
143
|
+
payoutsEnabled: boolean;
|
|
144
|
+
detailsSubmitted: boolean;
|
|
145
|
+
pendingOnboardingUrl?: string | null;
|
|
146
|
+
updatedAt: string;
|
|
147
|
+
}
|
|
148
|
+
interface CryptoNonceResponse {
|
|
149
|
+
nonce: string;
|
|
150
|
+
/** Canonical message the wallet must sign — includes the nonce. */
|
|
151
|
+
message: string;
|
|
152
|
+
expiresAt: string;
|
|
153
|
+
}
|
|
154
|
+
interface StripeConnectStartResponse {
|
|
155
|
+
accountIdMasked: string;
|
|
156
|
+
/** Hosted Stripe AccountLink URL — redirect the user here. */
|
|
157
|
+
onboardingUrl: string;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Per-stack payout configuration, as resolved by stacknet from the stack's
|
|
161
|
+
* config + secrets. Drives the payout-method picker and locks the destination.
|
|
162
|
+
*/
|
|
163
|
+
interface StackPayoutCapabilities {
|
|
164
|
+
stackId: string;
|
|
165
|
+
stackName: string;
|
|
166
|
+
stripe: {
|
|
167
|
+
enabled: boolean;
|
|
168
|
+
/** Human-readable reason when disabled (rendered as "disabled by {stackName} stack" UX). */
|
|
169
|
+
disabledReason?: string;
|
|
170
|
+
/** Masked / display-only descriptor — never the raw account id. */
|
|
171
|
+
destinationLabel?: string;
|
|
172
|
+
};
|
|
173
|
+
usdc: {
|
|
174
|
+
enabled: boolean;
|
|
175
|
+
disabledReason?: string;
|
|
176
|
+
/** Resolved on-chain payout address from the stack config. */
|
|
177
|
+
defaultDestination: string;
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
type FilingTrackerStep = 'sent' | 'routed' | 'confirmed' | 'finalized' | 'filed';
|
|
181
|
+
type FilingTrackerStatus = 'pending' | 'current' | 'done' | 'failed';
|
|
182
|
+
interface FilingTrackerState {
|
|
183
|
+
id: FilingTrackerStep;
|
|
184
|
+
label: string;
|
|
185
|
+
status: FilingTrackerStatus;
|
|
186
|
+
timestampMs: number | null;
|
|
187
|
+
detail: string | null;
|
|
188
|
+
approvalsCount?: number;
|
|
189
|
+
approvalsThreshold?: number;
|
|
190
|
+
/** Optional outbound link (Solscan / Stripe dashboard). */
|
|
191
|
+
externalUrl?: string;
|
|
192
|
+
}
|
|
193
|
+
interface FilingDetail extends FilingResult {
|
|
194
|
+
payoutMethod: PayoutMethod;
|
|
195
|
+
/** Server-supplied; not editable from the client. */
|
|
196
|
+
memo: string;
|
|
197
|
+
/** Server-supplied; not editable from the client. USDC raw units (string to avoid bigint loss). */
|
|
198
|
+
amountUsdc: string;
|
|
199
|
+
tokensUsed: string;
|
|
200
|
+
tracker: FilingTrackerState[];
|
|
201
|
+
proofPda?: string;
|
|
202
|
+
intentHashHex?: string;
|
|
203
|
+
stripePaymentIntentId?: string;
|
|
204
|
+
failureReason?: string;
|
|
205
|
+
/**
|
|
206
|
+
* The Solana wallet recorded as the intent's beneficiary on-chain. For
|
|
207
|
+
* usdc filings this matches `beneficiary`; for stripe filings the
|
|
208
|
+
* `beneficiary` is the off-chain Stripe account id and this is the
|
|
209
|
+
* wallet the resolver uses to look up the credentials mapping.
|
|
210
|
+
*/
|
|
211
|
+
onchainBeneficiary?: string;
|
|
212
|
+
}
|
|
92
213
|
type Platform = 'ios' | 'android' | 'windows' | 'mac' | 'linux';
|
|
93
214
|
interface PlatformDownload {
|
|
94
215
|
platform: Platform;
|
|
@@ -125,4 +246,4 @@ interface KeyUtilsCallbacks {
|
|
|
125
246
|
onFilingError?: (error: Error) => void;
|
|
126
247
|
}
|
|
127
248
|
|
|
128
|
-
export type { DirectTransferResult, EligibleKey, FilingHistoryEntry, FilingResult, FilingStatus, KeyListing, KeyUtilsCallbacks, KeyUtilsConfig, KeyWidgetTab, LedgerEntry, ListingResult, MintResult, NodeKeyInfo, PaymentMethod, Platform, PlatformDownload, PricingInfo };
|
|
249
|
+
export type { CryptoNonceResponse, DirectTransferResult, EligibleKey, FilingDetail, FilingHistoryEntry, FilingResult, FilingStatus, FilingTrackerState, FilingTrackerStatus, FilingTrackerStep, KeyListing, KeyUtilsCallbacks, KeyUtilsConfig, KeyWidgetTab, LedgerEntry, ListingResult, MintResult, NodeKeyInfo, PaymentMethod, PayoutAccount, PayoutAccountMethod, PayoutMethod, Platform, PlatformDownload, PricingInfo, StackPayoutCapabilities, StripeConnectStartResponse, StripeStackPayout };
|
package/dist/utils/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
'use strict';var clsx=require('clsx'),tailwindMerge=require('tailwind-merge');function
|
|
1
|
+
'use strict';var clsx=require('clsx'),tailwindMerge=require('tailwind-merge');var d=false;function _(){if(typeof document>"u")return {};let e=document.cookie.match(/(?:^|;\s*)__csrf=([^;]*)/);if(!e)return d||(d=true,console.warn("[keyutils] __csrf cookie not found; mutations will be sent without a CSRF token")),{};let n=e[1];try{n=decodeURIComponent(n);}catch{}return {"x-csrf-token":n}}var b=500;function g(e,n){if(typeof e!="string"||e.length===0)return n;let t=e.replace(/[\u0000-\u001F\u007F]/g," ");return t.length>500?t.slice(0,500)+"\u2026":t}async function R(e,n){try{let t=await e.json();if(t&&typeof t=="object"&&"error"in t)return g(t.error,n)}catch{}return n}function F(e,n="#"){if(!e||typeof e!="string")return n;let t=e.trim();if(t===""||t==="#")return n;if(t.startsWith("/")||t.startsWith("./")||t.startsWith("../"))return t;try{let o=new URL(t);if(o.protocol==="http:"||o.protocol==="https:")return o.toString()}catch{}return n}var c={sent:"sent",routed:"routed",confirmed:"confirmed",finalized:"finalized",filed:"filed"},u={sent:{pending:"sent",progressing:"sending",done:"sent"},routed:{pending:"routed",progressing:"routing",done:"routed"},confirmed:{pending:"confirmed",progressing:"confirming",done:"confirmed"},finalized:{pending:"finalized",progressing:"finalizing",done:"finalized"},filed:{pending:"filed",progressing:"filing",done:"filed"}},k=["sent","routed","confirmed","finalized","filed"];function T(e){let n=new Map;(e??[]).forEach(r=>n.set(r.id,r));let t=k.map(r=>{let i=n.get(r);return i?{...i,label:i.label||c[r]}:{id:r,label:c[r],status:"pending",timestampMs:null,detail:null}}),o=t.reduce((r,i,a)=>i.status==="done"||i.status==="failed"?a:r,-1);if(o>0)for(let r=0;r<o;r++)t[r].status!=="failed"&&(t[r]={...t[r],status:"done"});if(!t.some(r=>r.status==="failed")){let r=t.findIndex(i=>i.status!=="done");if(r>=0){let i=t[r];i.status!=="current"&&(t[r]={...i,status:"current"});}}return t}function p(e){return e.find(n=>n.status==="current")??null}function m(e){return e.length>0&&e.every(n=>n.status==="done")}function x(e){return e.some(n=>n.status==="failed")}function E(e,n){if(!n)return {text:"loading",playing:true,stepId:"sent"};if(x(e))return {text:"failed",playing:false,stepId:"filed"};if(m(e))return {text:u.filed.done,playing:false,stepId:"filed"};let o=p(e)?.id??"sent";return {text:u[o].progressing,playing:true,stepId:o}}function v(...e){return tailwindMerge.twMerge(clsx.clsx(e))}function P(e){return e==null?"0":e>=1e9?`${(e/1e9).toFixed(1)}B`:e>=1e6?`${(e/1e6).toFixed(1)}M`:e>=1e3?`${(e/1e3).toFixed(1)}K`:e.toLocaleString()}function z(e,n){return n<=0?0:Math.min(100,Math.round(e/n*100))}function U(e){return e>=70?"bg-green-500":e>=30?"bg-yellow-500":"bg-red-500"}function K(e,n={}){let t=n.withSymbol!==false,o=Math.max(0,Math.min(6,n.maxDecimals??2));if(e==null||e==="")return t?"$0.00":"0.00";let s;try{if(typeof e=="bigint")s=e;else if(typeof e=="number")s=BigInt(Math.trunc(e));else {let l=String(e).trim().replace(/^\+/,"");if(/^-?\d+$/.test(l))s=BigInt(l);else {let f=Number(l);if(!Number.isFinite(f))return t?"$0.00":"0.00";s=BigInt(Math.trunc(f));}}}catch{return t?"$0.00":"0.00"}let r=s<0n,i=r?-s:s,a=i/1000000n,S=(i%1000000n).toString().padStart(6,"0").slice(0,o),h=a.toLocaleString("en-US"),y=o>0?`.${S}`:"";return `${r?"-":""}${t?"$":""}${h}${y}`}function O(e){if(e==null||e==="")return "";let n=typeof e=="string"&&/^\d+$/.test(e)?Number(e):e,t=new Date(n);return isNaN(t.getTime())?"":t.toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"})}function H(){if(typeof navigator>"u")return "mac";let e=navigator.userAgent.toLowerCase();return /iphone|ipad|ipod/.test(e)?"ios":/android/.test(e)?"android":/win/.test(e)?"windows":/linux/.test(e)?"linux":"mac"}exports.MAX_ERROR_LEN=b;exports.TRACKER_LABELS=c;exports.TRACKER_VERBS=u;exports.calculateBalancePercentage=z;exports.clampErrorMessage=g;exports.cn=v;exports.csrfHeaders=_;exports.currentState=p;exports.deriveTrackerStates=T;exports.detectPlatform=H;exports.formatDate=O;exports.formatPaperUsd=K;exports.formatTokens=P;exports.getBalanceColor=U;exports.hasFailed=x;exports.isAllDone=m;exports.pickHeadline=E;exports.readErrorMessage=R;exports.safeUrl=F;
|
package/dist/utils/index.d.cts
CHANGED
|
@@ -1,7 +1,20 @@
|
|
|
1
1
|
import { ClassValue } from 'clsx';
|
|
2
|
-
import { Platform } from '../types/index.cjs';
|
|
2
|
+
import { FilingTrackerStep, FilingTrackerState, Platform } from '../types/index.cjs';
|
|
3
3
|
|
|
4
|
-
/**
|
|
4
|
+
/**
|
|
5
|
+
* Read the `__csrf` cookie and return it as the `x-csrf-token` header for
|
|
6
|
+
* mutating requests.
|
|
7
|
+
*
|
|
8
|
+
* Returns `{}` outside the browser (so native callers can use the same
|
|
9
|
+
* helper as a no-op). In the browser, returns `{}` when the cookie is
|
|
10
|
+
* missing — the server is the trust boundary and must reject — but logs
|
|
11
|
+
* a one-time warning so the missing token surfaces in the dev console
|
|
12
|
+
* rather than failing silently.
|
|
13
|
+
*
|
|
14
|
+
* The cookie value is `decodeURIComponent`'d to match the encoding the
|
|
15
|
+
* server applies when setting it; without this, tokens containing `+`,
|
|
16
|
+
* `=`, or `%` would desync between client and server.
|
|
17
|
+
*/
|
|
5
18
|
declare function csrfHeaders(): Record<string, string>;
|
|
6
19
|
|
|
7
20
|
/**
|
|
@@ -30,11 +43,53 @@ declare function readErrorMessage(res: Response, fallback: string): Promise<stri
|
|
|
30
43
|
*/
|
|
31
44
|
declare function safeUrl(url: string | undefined | null, fallback?: string): string;
|
|
32
45
|
|
|
46
|
+
declare const TRACKER_LABELS: Record<FilingTrackerStep, string>;
|
|
47
|
+
/**
|
|
48
|
+
* Verb tenses per state. `pending` is the neutral noun used when the row
|
|
49
|
+
* hasn't been entered yet; `progressing` is the gerund shown while the step
|
|
50
|
+
* is in-flight (terminal typing animation); `done` is the past-tense label
|
|
51
|
+
* used once the step completes. All lowercase by design.
|
|
52
|
+
*/
|
|
53
|
+
declare const TRACKER_VERBS: Record<FilingTrackerStep, {
|
|
54
|
+
pending: string;
|
|
55
|
+
progressing: string;
|
|
56
|
+
done: string;
|
|
57
|
+
}>;
|
|
58
|
+
/** Pure normalization of a server-shaped tracker. Cascade-forward + current pointer. */
|
|
59
|
+
declare function deriveTrackerStates(raw: FilingTrackerState[] | null | undefined): FilingTrackerState[];
|
|
60
|
+
declare function currentState(states: FilingTrackerState[]): FilingTrackerState | null;
|
|
61
|
+
declare function isAllDone(states: FilingTrackerState[]): boolean;
|
|
62
|
+
declare function hasFailed(states: FilingTrackerState[]): boolean;
|
|
63
|
+
/** Pick the headline word for the big typing-text animation. */
|
|
64
|
+
declare function pickHeadline(states: FilingTrackerState[], loaded: boolean): {
|
|
65
|
+
text: string;
|
|
66
|
+
playing: boolean;
|
|
67
|
+
stepId: FilingTrackerStep;
|
|
68
|
+
};
|
|
69
|
+
|
|
33
70
|
declare function cn(...inputs: ClassValue[]): string;
|
|
34
71
|
declare function formatTokens(amount: number | undefined | null): string;
|
|
35
72
|
declare function calculateBalancePercentage(current: number, max: number): number;
|
|
36
73
|
declare function getBalanceColor(percentage: number): string;
|
|
74
|
+
/**
|
|
75
|
+
* Format a paperwork USD amount for display.
|
|
76
|
+
*
|
|
77
|
+
* Stacknet stores `paper_work` as a 6-decimal fixed-point integer string —
|
|
78
|
+
* so `'1500000'` means $1.50. Pass any of (string | number | bigint | null
|
|
79
|
+
* | undefined) and get back a plain dollar string. By default, returns
|
|
80
|
+
* with 2 decimals + `$` prefix; pass `{ withSymbol: false }` for a bare
|
|
81
|
+
* decimal number, or `{ maxDecimals: 6 }` to surface sub-cent precision.
|
|
82
|
+
*
|
|
83
|
+
* formatPaperUsd('0') → '$0.00'
|
|
84
|
+
* formatPaperUsd('1500000') → '$1.50'
|
|
85
|
+
* formatPaperUsd('1234567') → '$1.23'
|
|
86
|
+
* formatPaperUsd('1234567', { maxDecimals: 6 }) → '$1.234567'
|
|
87
|
+
*/
|
|
88
|
+
declare function formatPaperUsd(raw: string | number | bigint | null | undefined, opts?: {
|
|
89
|
+
withSymbol?: boolean;
|
|
90
|
+
maxDecimals?: number;
|
|
91
|
+
}): string;
|
|
37
92
|
declare function formatDate(dateString: string | number | null | undefined): string;
|
|
38
93
|
declare function detectPlatform(): Platform;
|
|
39
94
|
|
|
40
|
-
export { MAX_ERROR_LEN, calculateBalancePercentage, clampErrorMessage, cn, csrfHeaders, detectPlatform, formatDate, formatTokens, getBalanceColor, readErrorMessage, safeUrl };
|
|
95
|
+
export { MAX_ERROR_LEN, TRACKER_LABELS, TRACKER_VERBS, calculateBalancePercentage, clampErrorMessage, cn, csrfHeaders, currentState, deriveTrackerStates, detectPlatform, formatDate, formatPaperUsd, formatTokens, getBalanceColor, hasFailed, isAllDone, pickHeadline, readErrorMessage, safeUrl };
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -1,7 +1,20 @@
|
|
|
1
1
|
import { ClassValue } from 'clsx';
|
|
2
|
-
import { Platform } from '../types/index.js';
|
|
2
|
+
import { FilingTrackerStep, FilingTrackerState, Platform } from '../types/index.js';
|
|
3
3
|
|
|
4
|
-
/**
|
|
4
|
+
/**
|
|
5
|
+
* Read the `__csrf` cookie and return it as the `x-csrf-token` header for
|
|
6
|
+
* mutating requests.
|
|
7
|
+
*
|
|
8
|
+
* Returns `{}` outside the browser (so native callers can use the same
|
|
9
|
+
* helper as a no-op). In the browser, returns `{}` when the cookie is
|
|
10
|
+
* missing — the server is the trust boundary and must reject — but logs
|
|
11
|
+
* a one-time warning so the missing token surfaces in the dev console
|
|
12
|
+
* rather than failing silently.
|
|
13
|
+
*
|
|
14
|
+
* The cookie value is `decodeURIComponent`'d to match the encoding the
|
|
15
|
+
* server applies when setting it; without this, tokens containing `+`,
|
|
16
|
+
* `=`, or `%` would desync between client and server.
|
|
17
|
+
*/
|
|
5
18
|
declare function csrfHeaders(): Record<string, string>;
|
|
6
19
|
|
|
7
20
|
/**
|
|
@@ -30,11 +43,53 @@ declare function readErrorMessage(res: Response, fallback: string): Promise<stri
|
|
|
30
43
|
*/
|
|
31
44
|
declare function safeUrl(url: string | undefined | null, fallback?: string): string;
|
|
32
45
|
|
|
46
|
+
declare const TRACKER_LABELS: Record<FilingTrackerStep, string>;
|
|
47
|
+
/**
|
|
48
|
+
* Verb tenses per state. `pending` is the neutral noun used when the row
|
|
49
|
+
* hasn't been entered yet; `progressing` is the gerund shown while the step
|
|
50
|
+
* is in-flight (terminal typing animation); `done` is the past-tense label
|
|
51
|
+
* used once the step completes. All lowercase by design.
|
|
52
|
+
*/
|
|
53
|
+
declare const TRACKER_VERBS: Record<FilingTrackerStep, {
|
|
54
|
+
pending: string;
|
|
55
|
+
progressing: string;
|
|
56
|
+
done: string;
|
|
57
|
+
}>;
|
|
58
|
+
/** Pure normalization of a server-shaped tracker. Cascade-forward + current pointer. */
|
|
59
|
+
declare function deriveTrackerStates(raw: FilingTrackerState[] | null | undefined): FilingTrackerState[];
|
|
60
|
+
declare function currentState(states: FilingTrackerState[]): FilingTrackerState | null;
|
|
61
|
+
declare function isAllDone(states: FilingTrackerState[]): boolean;
|
|
62
|
+
declare function hasFailed(states: FilingTrackerState[]): boolean;
|
|
63
|
+
/** Pick the headline word for the big typing-text animation. */
|
|
64
|
+
declare function pickHeadline(states: FilingTrackerState[], loaded: boolean): {
|
|
65
|
+
text: string;
|
|
66
|
+
playing: boolean;
|
|
67
|
+
stepId: FilingTrackerStep;
|
|
68
|
+
};
|
|
69
|
+
|
|
33
70
|
declare function cn(...inputs: ClassValue[]): string;
|
|
34
71
|
declare function formatTokens(amount: number | undefined | null): string;
|
|
35
72
|
declare function calculateBalancePercentage(current: number, max: number): number;
|
|
36
73
|
declare function getBalanceColor(percentage: number): string;
|
|
74
|
+
/**
|
|
75
|
+
* Format a paperwork USD amount for display.
|
|
76
|
+
*
|
|
77
|
+
* Stacknet stores `paper_work` as a 6-decimal fixed-point integer string —
|
|
78
|
+
* so `'1500000'` means $1.50. Pass any of (string | number | bigint | null
|
|
79
|
+
* | undefined) and get back a plain dollar string. By default, returns
|
|
80
|
+
* with 2 decimals + `$` prefix; pass `{ withSymbol: false }` for a bare
|
|
81
|
+
* decimal number, or `{ maxDecimals: 6 }` to surface sub-cent precision.
|
|
82
|
+
*
|
|
83
|
+
* formatPaperUsd('0') → '$0.00'
|
|
84
|
+
* formatPaperUsd('1500000') → '$1.50'
|
|
85
|
+
* formatPaperUsd('1234567') → '$1.23'
|
|
86
|
+
* formatPaperUsd('1234567', { maxDecimals: 6 }) → '$1.234567'
|
|
87
|
+
*/
|
|
88
|
+
declare function formatPaperUsd(raw: string | number | bigint | null | undefined, opts?: {
|
|
89
|
+
withSymbol?: boolean;
|
|
90
|
+
maxDecimals?: number;
|
|
91
|
+
}): string;
|
|
37
92
|
declare function formatDate(dateString: string | number | null | undefined): string;
|
|
38
93
|
declare function detectPlatform(): Platform;
|
|
39
94
|
|
|
40
|
-
export { MAX_ERROR_LEN, calculateBalancePercentage, clampErrorMessage, cn, csrfHeaders, detectPlatform, formatDate, formatTokens, getBalanceColor, readErrorMessage, safeUrl };
|
|
95
|
+
export { MAX_ERROR_LEN, TRACKER_LABELS, TRACKER_VERBS, calculateBalancePercentage, clampErrorMessage, cn, csrfHeaders, currentState, deriveTrackerStates, detectPlatform, formatDate, formatPaperUsd, formatTokens, getBalanceColor, hasFailed, isAllDone, pickHeadline, readErrorMessage, safeUrl };
|
package/dist/utils/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import {clsx}from'clsx';import {twMerge}from'tailwind-merge';function
|
|
1
|
+
import {clsx}from'clsx';import {twMerge}from'tailwind-merge';var d=false;function _(){if(typeof document>"u")return {};let e=document.cookie.match(/(?:^|;\s*)__csrf=([^;]*)/);if(!e)return d||(d=true,console.warn("[keyutils] __csrf cookie not found; mutations will be sent without a CSRF token")),{};let n=e[1];try{n=decodeURIComponent(n);}catch{}return {"x-csrf-token":n}}var b=500;function g(e,n){if(typeof e!="string"||e.length===0)return n;let t=e.replace(/[\u0000-\u001F\u007F]/g," ");return t.length>500?t.slice(0,500)+"\u2026":t}async function R(e,n){try{let t=await e.json();if(t&&typeof t=="object"&&"error"in t)return g(t.error,n)}catch{}return n}function F(e,n="#"){if(!e||typeof e!="string")return n;let t=e.trim();if(t===""||t==="#")return n;if(t.startsWith("/")||t.startsWith("./")||t.startsWith("../"))return t;try{let o=new URL(t);if(o.protocol==="http:"||o.protocol==="https:")return o.toString()}catch{}return n}var c={sent:"sent",routed:"routed",confirmed:"confirmed",finalized:"finalized",filed:"filed"},u={sent:{pending:"sent",progressing:"sending",done:"sent"},routed:{pending:"routed",progressing:"routing",done:"routed"},confirmed:{pending:"confirmed",progressing:"confirming",done:"confirmed"},finalized:{pending:"finalized",progressing:"finalizing",done:"finalized"},filed:{pending:"filed",progressing:"filing",done:"filed"}},k=["sent","routed","confirmed","finalized","filed"];function T(e){let n=new Map;(e??[]).forEach(r=>n.set(r.id,r));let t=k.map(r=>{let i=n.get(r);return i?{...i,label:i.label||c[r]}:{id:r,label:c[r],status:"pending",timestampMs:null,detail:null}}),o=t.reduce((r,i,a)=>i.status==="done"||i.status==="failed"?a:r,-1);if(o>0)for(let r=0;r<o;r++)t[r].status!=="failed"&&(t[r]={...t[r],status:"done"});if(!t.some(r=>r.status==="failed")){let r=t.findIndex(i=>i.status!=="done");if(r>=0){let i=t[r];i.status!=="current"&&(t[r]={...i,status:"current"});}}return t}function p(e){return e.find(n=>n.status==="current")??null}function m(e){return e.length>0&&e.every(n=>n.status==="done")}function x(e){return e.some(n=>n.status==="failed")}function E(e,n){if(!n)return {text:"loading",playing:true,stepId:"sent"};if(x(e))return {text:"failed",playing:false,stepId:"filed"};if(m(e))return {text:u.filed.done,playing:false,stepId:"filed"};let o=p(e)?.id??"sent";return {text:u[o].progressing,playing:true,stepId:o}}function v(...e){return twMerge(clsx(e))}function P(e){return e==null?"0":e>=1e9?`${(e/1e9).toFixed(1)}B`:e>=1e6?`${(e/1e6).toFixed(1)}M`:e>=1e3?`${(e/1e3).toFixed(1)}K`:e.toLocaleString()}function z(e,n){return n<=0?0:Math.min(100,Math.round(e/n*100))}function U(e){return e>=70?"bg-green-500":e>=30?"bg-yellow-500":"bg-red-500"}function K(e,n={}){let t=n.withSymbol!==false,o=Math.max(0,Math.min(6,n.maxDecimals??2));if(e==null||e==="")return t?"$0.00":"0.00";let s;try{if(typeof e=="bigint")s=e;else if(typeof e=="number")s=BigInt(Math.trunc(e));else {let l=String(e).trim().replace(/^\+/,"");if(/^-?\d+$/.test(l))s=BigInt(l);else {let f=Number(l);if(!Number.isFinite(f))return t?"$0.00":"0.00";s=BigInt(Math.trunc(f));}}}catch{return t?"$0.00":"0.00"}let r=s<0n,i=r?-s:s,a=i/1000000n,S=(i%1000000n).toString().padStart(6,"0").slice(0,o),h=a.toLocaleString("en-US"),y=o>0?`.${S}`:"";return `${r?"-":""}${t?"$":""}${h}${y}`}function O(e){if(e==null||e==="")return "";let n=typeof e=="string"&&/^\d+$/.test(e)?Number(e):e,t=new Date(n);return isNaN(t.getTime())?"":t.toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"})}function H(){if(typeof navigator>"u")return "mac";let e=navigator.userAgent.toLowerCase();return /iphone|ipad|ipod/.test(e)?"ios":/android/.test(e)?"android":/win/.test(e)?"windows":/linux/.test(e)?"linux":"mac"}export{b as MAX_ERROR_LEN,c as TRACKER_LABELS,u as TRACKER_VERBS,z as calculateBalancePercentage,g as clampErrorMessage,v as cn,_ as csrfHeaders,p as currentState,T as deriveTrackerStates,H as detectPlatform,O as formatDate,K as formatPaperUsd,P as formatTokens,U as getBalanceColor,x as hasFailed,m as isAllDone,E as pickHeadline,R as readErrorMessage,F as safeUrl};
|