@conto_finance/sdk 0.6.2-beta.1 → 0.7.1
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/README.md +8 -3
- package/dist/browserbase.d.mts +2 -1
- package/dist/browserbase.d.ts +2 -1
- package/dist/browserbase.js +5 -2
- package/dist/browserbase.mjs +1 -1
- package/dist/checkout-verifier.d.mts +2 -1
- package/dist/checkout-verifier.d.ts +2 -1
- package/dist/{chunk-VSIO6PYA.mjs → chunk-JBTJXIMI.mjs} +5 -2
- package/dist/chunk-PVMUL3JC.mjs +30 -0
- package/dist/index.d.mts +135 -4
- package/dist/index.d.ts +135 -4
- package/dist/index.js +119 -13
- package/dist/index.mjs +97 -13
- package/dist/link-wallet.d.mts +8 -2
- package/dist/link-wallet.d.ts +8 -2
- package/dist/link-wallet.js +33 -11
- package/dist/link-wallet.mjs +9 -11
- package/dist/playwright.d.mts +2 -1
- package/dist/playwright.d.ts +2 -1
- package/dist/playwright.js +5 -2
- package/dist/playwright.mjs +1 -1
- package/package.json +6 -7
package/dist/index.d.ts
CHANGED
|
@@ -40,6 +40,48 @@ interface PurchaseGroceryItem {
|
|
|
40
40
|
interface PurchaseGroceryList {
|
|
41
41
|
items: PurchaseGroceryItem[];
|
|
42
42
|
}
|
|
43
|
+
/** A grocery list purchase's items, delivery and fees at the store. */
|
|
44
|
+
interface PurchaseGrocery {
|
|
45
|
+
/** Each list item that has settled so far, by its position in the list. */
|
|
46
|
+
items: ({
|
|
47
|
+
index: number;
|
|
48
|
+
label: string;
|
|
49
|
+
status: 'added';
|
|
50
|
+
/** The store's product name. */
|
|
51
|
+
name: string;
|
|
52
|
+
quantity: number;
|
|
53
|
+
/** The line's price for that quantity. */
|
|
54
|
+
price: PurchaseMoney;
|
|
55
|
+
} | {
|
|
56
|
+
index: number;
|
|
57
|
+
label: string;
|
|
58
|
+
status: 'skipped';
|
|
59
|
+
reason: 'no_match' | 'size_unavailable' | 'brand_unavailable' | 'excluded';
|
|
60
|
+
})[];
|
|
61
|
+
/** The delivery time chosen at checkout. */
|
|
62
|
+
delivery: {
|
|
63
|
+
title: string;
|
|
64
|
+
window: string;
|
|
65
|
+
kind: 'priority' | 'standard' | 'scheduled' | 'other';
|
|
66
|
+
windowStart: string | null;
|
|
67
|
+
windowEnd: string | null;
|
|
68
|
+
price: PurchaseMoney | null;
|
|
69
|
+
} | null;
|
|
70
|
+
/** The store checkout's totals and fees, as it showed them. */
|
|
71
|
+
summary: {
|
|
72
|
+
itemsSubtotal: PurchaseMoney | null;
|
|
73
|
+
deliveryFee: PurchaseMoney | null;
|
|
74
|
+
serviceFee: PurchaseMoney | null;
|
|
75
|
+
bagFee: PurchaseMoney | null;
|
|
76
|
+
tax: PurchaseMoney | null;
|
|
77
|
+
tip: PurchaseMoney | null;
|
|
78
|
+
otherFees: {
|
|
79
|
+
label: string;
|
|
80
|
+
amount: PurchaseMoney;
|
|
81
|
+
}[];
|
|
82
|
+
total: PurchaseMoney | null;
|
|
83
|
+
} | null;
|
|
84
|
+
}
|
|
43
85
|
interface PurchaseRequest {
|
|
44
86
|
url: string;
|
|
45
87
|
task?: string;
|
|
@@ -66,6 +108,15 @@ interface PurchaseAction {
|
|
|
66
108
|
maximum: PurchaseMoney;
|
|
67
109
|
maxCost: PurchaseMoney;
|
|
68
110
|
};
|
|
111
|
+
/**
|
|
112
|
+
* For a merchant_signin you answer: the store sign-in step. Answer `email`
|
|
113
|
+
* with `{ email }` (or `{ email, createAccount: true, agreedToStoreTerms: true }`)
|
|
114
|
+
* and `code` with `{ code }`, the 6-digit code the store sent the buyer.
|
|
115
|
+
*/
|
|
116
|
+
signin?: {
|
|
117
|
+
store: 'instacart';
|
|
118
|
+
step: 'email' | 'code';
|
|
119
|
+
};
|
|
69
120
|
/**
|
|
70
121
|
* For buyer, cardholder and reviewer actions: the Conto page that completes
|
|
71
122
|
* it. It works only inside a hosted buyer session or the dashboard, so it is
|
|
@@ -119,7 +170,15 @@ interface Purchase {
|
|
|
119
170
|
result: {
|
|
120
171
|
outcome: 'merchant_confirmed' | 'checkout_reported' | 'credential_unused' | 'not_completed' | 'denied' | 'cancelled';
|
|
121
172
|
merchantReference: string | null;
|
|
173
|
+
/** merchant_confirmed: the store's order number, when shown. */
|
|
174
|
+
orderNumber?: string | null;
|
|
175
|
+
/** merchant_confirmed: the store's receipt or order page, when shown. */
|
|
176
|
+
receiptUrl?: string | null;
|
|
177
|
+
/** merchant_confirmed: the amount the store charged, when shown. */
|
|
178
|
+
charged?: PurchaseMoney | null;
|
|
122
179
|
} | null;
|
|
180
|
+
/** Present for a grocery list purchase. */
|
|
181
|
+
grocery?: PurchaseGrocery;
|
|
123
182
|
paymentEvidence: PurchaseEvidence;
|
|
124
183
|
progress: {
|
|
125
184
|
steps: number;
|
|
@@ -190,8 +249,8 @@ interface CreatePurchaseInput {
|
|
|
190
249
|
delegationId: string;
|
|
191
250
|
};
|
|
192
251
|
/**
|
|
193
|
-
*
|
|
194
|
-
*
|
|
252
|
+
* New purchases snapshot saved delivery details at creation for the store's
|
|
253
|
+
* delivery form. Leave out to use them when present, pass the buyer id
|
|
195
254
|
* to require them, or null to never use them.
|
|
196
255
|
*/
|
|
197
256
|
buyerProfileId?: string | null;
|
|
@@ -1294,6 +1353,29 @@ interface RefreshBalanceResult {
|
|
|
1294
1353
|
balances: WalletChainBalanceSnapshot[];
|
|
1295
1354
|
lastRefreshed: string;
|
|
1296
1355
|
}
|
|
1356
|
+
/** A one-time message for a self-custody wallet's address to sign. */
|
|
1357
|
+
interface WalletOwnershipChallenge {
|
|
1358
|
+
walletId: string;
|
|
1359
|
+
address: string;
|
|
1360
|
+
chainType: ChainType;
|
|
1361
|
+
chainId: string;
|
|
1362
|
+
/** Sign exactly this text: EIP-191 personal_sign on EVM, Ed25519 on Solana. */
|
|
1363
|
+
message: string;
|
|
1364
|
+
expiresAt: string;
|
|
1365
|
+
/** When the wallet was last proven, or null if never. */
|
|
1366
|
+
provenAt: string | null;
|
|
1367
|
+
}
|
|
1368
|
+
interface ProveWalletOwnershipInput {
|
|
1369
|
+
/** The challenge message, unchanged. */
|
|
1370
|
+
message: string;
|
|
1371
|
+
/** EVM: 0x-prefixed hex signature. Solana: base58 or base64 signature. */
|
|
1372
|
+
signature: string;
|
|
1373
|
+
}
|
|
1374
|
+
interface WalletOwnershipProof {
|
|
1375
|
+
walletId: string;
|
|
1376
|
+
proven: true;
|
|
1377
|
+
provenAt: string;
|
|
1378
|
+
}
|
|
1297
1379
|
interface PolicyRule {
|
|
1298
1380
|
id: string;
|
|
1299
1381
|
policyId: string;
|
|
@@ -1583,6 +1665,13 @@ declare class WalletsClient {
|
|
|
1583
1665
|
provision(walletId: string): Promise<ProvisionWalletResult>;
|
|
1584
1666
|
/** Refresh a wallet's balance from the chain */
|
|
1585
1667
|
refreshBalance(walletId: string): Promise<RefreshBalanceResult>;
|
|
1668
|
+
/**
|
|
1669
|
+
* Get a one-time message for a self-custody wallet's address to sign. It
|
|
1670
|
+
* expires after 10 minutes and replaces any earlier challenge.
|
|
1671
|
+
*/
|
|
1672
|
+
createOwnershipChallenge(walletId: string): Promise<WalletOwnershipChallenge>;
|
|
1673
|
+
/** Prove your organization controls a self-custody wallet's address. */
|
|
1674
|
+
proveOwnership(walletId: string, input: ProveWalletOwnershipInput): Promise<WalletOwnershipProof>;
|
|
1586
1675
|
}
|
|
1587
1676
|
declare class PoliciesClient {
|
|
1588
1677
|
private client;
|
|
@@ -2554,6 +2643,33 @@ interface WaitForCheckoutApprovalOptions {
|
|
|
2554
2643
|
signal?: AbortSignal;
|
|
2555
2644
|
}
|
|
2556
2645
|
|
|
2646
|
+
/**
|
|
2647
|
+
* The Link card request is waiting for the person. Conto has already approved
|
|
2648
|
+
* the purchase, and Link has created the request.
|
|
2649
|
+
*/
|
|
2650
|
+
interface LinkApprovalEvent {
|
|
2651
|
+
/** The checkpoint Conto approved. */
|
|
2652
|
+
checkpoint: CheckoutCheckpoint;
|
|
2653
|
+
/** The Link spend request id, such as lsrq_... */
|
|
2654
|
+
linkRequestId: string;
|
|
2655
|
+
/**
|
|
2656
|
+
* The Stripe Link page where the person can approve on the web while signed
|
|
2657
|
+
* in to Link, so they do not need the Link app. Only an HTTPS link.com address
|
|
2658
|
+
* is passed. Absent when Link gave none or it did not pass that check. The
|
|
2659
|
+
* person can still approve in the Link app.
|
|
2660
|
+
*/
|
|
2661
|
+
approvalUrl?: string;
|
|
2662
|
+
/** When Link stops accepting approval, as an ISO 8601 time, when Link reports it. */
|
|
2663
|
+
approvalExpiresAt?: string;
|
|
2664
|
+
}
|
|
2665
|
+
/**
|
|
2666
|
+
* Called once when the Link card request is waiting for the person, after
|
|
2667
|
+
* Conto approved the purchase and before the SDK starts waiting. Show
|
|
2668
|
+
* approvalUrl to the person. The SDK does not wait for it to finish, and an
|
|
2669
|
+
* error it throws or rejects with does not affect the purchase. A retry that
|
|
2670
|
+
* resumes a waiting request calls it again with the same URL.
|
|
2671
|
+
*/
|
|
2672
|
+
type LinkApprovalCallback = (event: LinkApprovalEvent) => void | Promise<void>;
|
|
2557
2673
|
/**
|
|
2558
2674
|
* A Link card for one purchase: the checkpoint begin input plus the Link
|
|
2559
2675
|
* wallet that runs in your environment. The checkout method is always LINK.
|
|
@@ -2565,6 +2681,8 @@ interface GetLinkCardInput extends Omit<BeginCheckoutCheckpointInput, 'checkoutM
|
|
|
2565
2681
|
ownerApprovalTimeoutMs?: number;
|
|
2566
2682
|
/** How long to wait for the person to approve in Link. Defaults to 10 minutes. */
|
|
2567
2683
|
linkApprovalTimeoutMs?: number;
|
|
2684
|
+
/** Called once with the Link approval page when the person needs to approve in Link. */
|
|
2685
|
+
onLinkApproval?: LinkApprovalCallback;
|
|
2568
2686
|
signal?: AbortSignal;
|
|
2569
2687
|
}
|
|
2570
2688
|
/** A new Link card for a changed final total. */
|
|
@@ -2578,6 +2696,8 @@ interface ReplaceLinkCardInput {
|
|
|
2578
2696
|
totals?: CommerceTotalInput[];
|
|
2579
2697
|
ownerApprovalTimeoutMs?: number;
|
|
2580
2698
|
linkApprovalTimeoutMs?: number;
|
|
2699
|
+
/** Called once with the Link approval page when the person needs to approve in Link. */
|
|
2700
|
+
onLinkApproval?: LinkApprovalCallback;
|
|
2581
2701
|
signal?: AbortSignal;
|
|
2582
2702
|
}
|
|
2583
2703
|
interface LinkCardResult {
|
|
@@ -3291,6 +3411,13 @@ declare class CheckoutApprovalTimeoutError extends ContoError {
|
|
|
3291
3411
|
declare class LinkCardError extends ContoError {
|
|
3292
3412
|
readonly checkpoint: CheckoutCheckpoint;
|
|
3293
3413
|
readonly linkRequestId?: string;
|
|
3414
|
+
/**
|
|
3415
|
+
* The Stripe Link page where the person could approve the request, set when
|
|
3416
|
+
* the SDK stopped while the request was waiting for them. It works only while
|
|
3417
|
+
* the request is still open in Link. When holdReleased is true, Conto has
|
|
3418
|
+
* already cancelled the request.
|
|
3419
|
+
*/
|
|
3420
|
+
readonly approvalUrl?: string;
|
|
3294
3421
|
/** True when Conto cancelled the checkpoint and released the held spend. */
|
|
3295
3422
|
readonly holdReleased: boolean;
|
|
3296
3423
|
constructor(input: {
|
|
@@ -3298,6 +3425,7 @@ declare class LinkCardError extends ContoError {
|
|
|
3298
3425
|
code: string;
|
|
3299
3426
|
checkpoint: CheckoutCheckpoint;
|
|
3300
3427
|
linkRequestId?: string;
|
|
3428
|
+
approvalUrl?: string;
|
|
3301
3429
|
holdReleased: boolean;
|
|
3302
3430
|
retryGuidance?: string;
|
|
3303
3431
|
});
|
|
@@ -3765,7 +3893,9 @@ declare class CheckoutClient {
|
|
|
3765
3893
|
* 1. Conto runs checkpoint 1 and holds the spend. When a rule requires the
|
|
3766
3894
|
* owner's approval, this waits for it.
|
|
3767
3895
|
* 2. Only then does the wallet ask Link for a card for exactly the approved
|
|
3768
|
-
* amount at this merchant. The person approves it in
|
|
3896
|
+
* amount at this merchant. The person approves it in Link. Pass
|
|
3897
|
+
* onLinkApproval to get Link's approval page, so they can approve on the
|
|
3898
|
+
* web without the Link app.
|
|
3769
3899
|
* 3. The card is returned. It never reaches Conto.
|
|
3770
3900
|
*
|
|
3771
3901
|
* Then fill in the card, call confirm(result.checkpoint, { amountMinor,
|
|
@@ -3790,4 +3920,5 @@ declare class CheckoutClient {
|
|
|
3790
3920
|
replaceLinkCard(previous: LinkCardResult, input: ReplaceLinkCardInput): Promise<LinkCardResult>;
|
|
3791
3921
|
}
|
|
3792
3922
|
|
|
3793
|
-
export {
|
|
3923
|
+
export { AdminPurchasingClient, BrowserActionFinalizationPendingError, BrowserCheckoutTargetVerificationError, CardsClient, CheckoutApprovalDeniedError, CheckoutApprovalExpiredError, CheckoutApprovalPendingError, CheckoutApprovalTimeoutError, CheckoutCheckpointClosedError, CheckoutClient, ConnectedCardsClient, Conto, ContoAdmin, ContoAdminError, ContoError, ControlledExternalCardPaymentTool, ExternalCardConfirmationPendingError, Conto as Giro, ContoError as GiroError, LinkCardCredential, LinkCardDeniedError, LinkCardError, LinkCardExpiredError, LinkCardTimeoutError, LinkWallet, LinkWalletUnavailableError, OrganizationPurchasesClient, OrganizationRecurringPurchasesClient, PurchasesClient, RecurringPurchasesClient, TestCardsClient, canonicalizeBrowserCheckoutTarget, createVerifiedBrowserCheckoutDriver, Conto as default, fingerprintBrowserCheckoutTarget, isFinalPurchaseStatus, parseServerSentEvents, verifyPurchaseWebhook };
|
|
3924
|
+
export type { AdminExternalCardOverlayEnforcement, Agent, AgentCheckoutAction, AgentCheckoutActionKind, AgentExternalCard, AgentSetupResult, AgentStatus, AgentType, AgentWalletLink, ApprovedExternalCardExecution, AssignExternalCardInput, AssignedPolicy, AuthorizeCheckoutActionResult, BeginCheckoutCheckpointInput, BeginCommerceExecutionInput, BrowserActionClaimResult, BrowserActionDispatchObservationInput, BrowserActionFinalizeResult, BrowserCheckoutAction, BrowserCheckoutTargetResolver, BrowserCheckoutTargetSnapshot, BrowserCheckoutTargetVerificationCode, CancellationOutcome, CanonicalBrowserCheckoutTargetSnapshot, ChainType, CheckoutActionAuthorization, CheckoutCheckpoint, CheckoutCheckpointApproval, CheckoutCheckpointMethod, CheckoutCheckpointNextAction, CheckoutCheckpointStage, CheckoutOutcome, CheckoutPaymentReference, CommerceCheckoutMethod, CommerceContextRequirement, CommerceExecution, CommerceExecutionAdapterKind, CommerceExecutionArtifactKind, CommerceExecutionChannel, CommerceExecutionConstraint, CommerceExecutionConstraintCoverage, CommerceExecutionConstraintCoverageLevel, CommerceExecutionDeliveryMode, CommerceExecutionEvidence, CommerceExecutionProvider, CommerceExecutionResult, CommerceExecutionSourceKind, CommerceExecutionStatus, CommerceFactConfidence, CommerceFactProvenanceInput, CommerceFactSource, CommerceFulfillmentInput, CommerceLineItemInput, CommerceProposalFactKey, CommerceProposalMissingFact, CommerceProposalResolution, CommerceProposalState, CommerceSettlementRail, CommerceTotalInput, CommerceTotalType, ComparePolicyVersionsResponse, ConfirmCheckoutCheckpointInput, ConnectedCardBrief, ConnectedCardCredential, ConnectedCardDrawInput, ConnectedCardDrawMerchant, ConnectedCardDrawResult, ConnectedCardDrawable, ConnectedCardListResult, ConnectedCardMandate, ConnectedCardMandateMerchant, ConnectedCardOutcomeReport, ConnectedCardOutcomeReportResult, ConnectedCardReference, ContoAdminConfig, ContoConfig, ContoRequestOptions, ControlledExternalCardPaymentResult, CreateAgentInput, CreatePolicyInput, CreatePolicyRuleInput, CreatePurchaseInput, CreateSdkKeyInput, CreateSdkKeyResult, CreateWalletInput, CustodyType, CustomerCustodyMode, CustomerWalletControlModel, CustomerWalletKeyAccess, DelegationType, ExecuteCommerceExecutionResult, ExternalCard, ExternalCardApprovalInput, ExternalCardApprovalResult, ExternalCardConfirmationInput, ExternalCardConfirmationResult, ExternalCardExecutionClaimResult, ExternalCardExecutionResult, ExternalCardExecutor, ExternalCardOverlayEnforcement, ExternalCardRequestStatusResult, ExternalWalletApprovalInput, ExternalWalletApprovalResult, ExternalWalletConfirmationInput, ExternalWalletConfirmationResult, FreezeAgentInput, GetLinkCardInput, ContoConfig as GiroConfig, GuardCheckoutResult, GuardedBrowserDispatchResult, GuardedCheckoutInput, LinkApprovalCallback, LinkApprovalEvent, LinkCardResult, LinkWalletInput, ListAgentsParams, ListAgentsResponse, ListPoliciesParams, ListPoliciesResponse, ListPolicyVersionsResponse, ListWalletsParams, ListWalletsResponse, MppBudgetResult, MppPreAuthorizeInput, MppPreAuthorizeResult, MppRecordInput, MppRecordResult, NormalizeCommerceProposalInput, OrganizationMember, PaginatedResponse, PaginationParams, PauseExternalCardAssignmentResult, PaymentExecuteResult, PaymentRequestInput, PaymentRequestResult, PaymentStatusResult, Policy, PolicyRule, PolicyType, PolicyVersionChangeType, PolicyVersionDetail, PolicyVersionDiff, PolicyVersionFieldChange, PolicyVersionSnapshot, PolicyVersionSnapshotRule, PolicyVersionSummary, PrivilegedBrowserCheckoutDriver, ProtocolBudgetResult, ProtocolPreAuthorizeResult, ProtocolRecordGrant, ProtocolRecordGrantResult, ProtocolServiceSummary, ProtocolServicesResult, ProveWalletOwnershipInput, ProvisionWalletResult, Purchase, PurchaseAction, PurchaseActionAuthority, PurchaseActionKind, PurchaseAllowance, PurchaseBuyer, PurchaseBuyerCompanyCard, PurchaseBuyerCompanyCardLimits, PurchaseBuyerKitchenContext, PurchaseCompanyCard, PurchaseDelegation, PurchaseEvent, PurchaseEventPage, PurchaseEvidence, PurchaseGrocery, PurchaseGroceryItem, PurchaseGroceryList, PurchaseHostedLink, PurchaseItem, PurchaseKitchenContext, PurchaseKitchenInventoryItem, PurchaseKitchenListItem, PurchaseKitchenPreferences, PurchaseKitchenRecipe, PurchaseKitchenUsual, PurchaseList, PurchaseMoney, PurchasePaymentMethod, PurchasePhase, PurchaseRequest, PurchaseResponseAck, PurchaseStatus, PurchasingCapabilities, PurchasingSettings, RecurringPurchase, RecurringPurchaseCycleResult, RecurringPurchaseCycleStatus, RefreshBalanceResult, RegisterExternalCardInput, ReplaceLinkCardInput, ReportCheckoutOutcomeInput, RollbackPolicyVersionResponse, RuleAction, RuleOperator, RuleType, RunGuardedCheckoutResult, SdkKey, SdkKeyType, SetupCapabilityState, SetupCardDiagnostics, SetupDiagnosticAction, SetupDiagnosticIssue, SetupDiagnosticIssueCode, SetupDiagnostics, SetupWalletDiagnostics, TestCardCredential, TestCardDrawResult, TestCardDrawable, TestCardListResult, TestCardReceipt, TestCheckoutInput, TestCheckoutResult, TestMerchant, TestMerchantProduct, UnfreezeAgentInput, UpdateAgentInput, UpdateExternalCardAssignmentInput, UpdatePolicyInput, UpdatePolicyRuleInput, UpdateWalletInput, VerifiedBrowserCheckoutTarget, WaitForCheckoutApprovalOptions, Wallet, WalletChainBalanceSnapshot, WalletOwnershipChallenge, WalletOwnershipProof, WalletStatus, WalletType, WatchPurchaseOptions, X402Authorization, X402BudgetResult, X402PayInput, X402PayResult, X402PaymentRequirements, X402PreAuthorizeInput, X402PreAuthorizeResult, X402RecordInput, X402RecordResult };
|
package/dist/index.js
CHANGED
|
@@ -47,7 +47,7 @@ var require_package = __commonJS({
|
|
|
47
47
|
"package.json"(exports2, module2) {
|
|
48
48
|
module2.exports = {
|
|
49
49
|
name: "@conto_finance/sdk",
|
|
50
|
-
version: "0.
|
|
50
|
+
version: "0.7.1",
|
|
51
51
|
description: "Conto SDK for AI agent payment authorization",
|
|
52
52
|
main: "./dist/index.js",
|
|
53
53
|
module: "./dist/index.mjs",
|
|
@@ -80,8 +80,7 @@ var require_package = __commonJS({
|
|
|
80
80
|
}
|
|
81
81
|
},
|
|
82
82
|
publishConfig: {
|
|
83
|
-
access: "public"
|
|
84
|
-
tag: "beta"
|
|
83
|
+
access: "public"
|
|
85
84
|
},
|
|
86
85
|
engines: {
|
|
87
86
|
node: ">=20.19.0"
|
|
@@ -119,7 +118,7 @@ var require_package = __commonJS({
|
|
|
119
118
|
email: "support@conto.finance"
|
|
120
119
|
},
|
|
121
120
|
dependencies: {
|
|
122
|
-
"@sentry/node": "^
|
|
121
|
+
"@sentry/node": "^11.8.0"
|
|
123
122
|
},
|
|
124
123
|
peerDependencies: {
|
|
125
124
|
"playwright-core": ">=1.50.0"
|
|
@@ -133,10 +132,10 @@ var require_package = __commonJS({
|
|
|
133
132
|
esbuild: "0.28.1"
|
|
134
133
|
},
|
|
135
134
|
devDependencies: {
|
|
136
|
-
"@types/node": "
|
|
135
|
+
"@types/node": "26.6.5",
|
|
137
136
|
"playwright-core": "1.61.0",
|
|
138
|
-
tsup: "^
|
|
139
|
-
typescript: "^
|
|
137
|
+
tsup: "^9.0.0",
|
|
138
|
+
typescript: "^6.0.3"
|
|
140
139
|
}
|
|
141
140
|
};
|
|
142
141
|
}
|
|
@@ -198,6 +197,32 @@ var Sentry2 = __toESM(require("@sentry/node"));
|
|
|
198
197
|
var import_node_crypto3 = require("crypto");
|
|
199
198
|
var import_package_version2 = __toESM(require_package_version());
|
|
200
199
|
|
|
200
|
+
// src/link-approval.ts
|
|
201
|
+
function safeLinkApprovalUrl(value) {
|
|
202
|
+
if (typeof value !== "string" || value.length === 0 || value.length > 2048) return void 0;
|
|
203
|
+
let url;
|
|
204
|
+
try {
|
|
205
|
+
url = new URL(value);
|
|
206
|
+
} catch {
|
|
207
|
+
return void 0;
|
|
208
|
+
}
|
|
209
|
+
if (url.protocol !== "https:" || url.username !== "" || url.password !== "" || url.port !== "" || !(url.hostname === "link.com" || url.hostname.endsWith(".link.com"))) {
|
|
210
|
+
return void 0;
|
|
211
|
+
}
|
|
212
|
+
url.hash = "";
|
|
213
|
+
return url.toString();
|
|
214
|
+
}
|
|
215
|
+
function linkTime(value) {
|
|
216
|
+
let ms = Number.NaN;
|
|
217
|
+
if (typeof value === "number" && Number.isFinite(value) && value > 0) {
|
|
218
|
+
ms = value < 1e12 ? value * 1e3 : value;
|
|
219
|
+
} else if (typeof value === "string" && value.length > 0 && value.length <= 64) {
|
|
220
|
+
ms = Date.parse(value);
|
|
221
|
+
}
|
|
222
|
+
const date = new Date(ms);
|
|
223
|
+
return Number.isNaN(date.getTime()) ? void 0 : date.toISOString();
|
|
224
|
+
}
|
|
225
|
+
|
|
201
226
|
// src/purchases.ts
|
|
202
227
|
var import_node_crypto = require("crypto");
|
|
203
228
|
var TERMINAL = /* @__PURE__ */ new Set(["succeeded", "blocked", "failed", "cancelled"]);
|
|
@@ -1414,6 +1439,25 @@ var WalletsClient = class {
|
|
|
1414
1439
|
{}
|
|
1415
1440
|
);
|
|
1416
1441
|
}
|
|
1442
|
+
/**
|
|
1443
|
+
* Get a one-time message for a self-custody wallet's address to sign. It
|
|
1444
|
+
* expires after 10 minutes and replaces any earlier challenge.
|
|
1445
|
+
*/
|
|
1446
|
+
async createOwnershipChallenge(walletId) {
|
|
1447
|
+
return this.client.request(
|
|
1448
|
+
"POST",
|
|
1449
|
+
`/api/wallets/${encodeURIComponent(walletId)}/ownership-proof/challenge`,
|
|
1450
|
+
{}
|
|
1451
|
+
);
|
|
1452
|
+
}
|
|
1453
|
+
/** Prove your organization controls a self-custody wallet's address. */
|
|
1454
|
+
async proveOwnership(walletId, input) {
|
|
1455
|
+
return this.client.request(
|
|
1456
|
+
"POST",
|
|
1457
|
+
`/api/wallets/${encodeURIComponent(walletId)}/ownership-proof`,
|
|
1458
|
+
input
|
|
1459
|
+
);
|
|
1460
|
+
}
|
|
1417
1461
|
};
|
|
1418
1462
|
var PoliciesClient = class {
|
|
1419
1463
|
constructor(client) {
|
|
@@ -1666,6 +1710,8 @@ var LinkCardError = class extends ContoError {
|
|
|
1666
1710
|
this.name = "LinkCardError";
|
|
1667
1711
|
this.checkpoint = input.checkpoint;
|
|
1668
1712
|
if (input.linkRequestId) this.linkRequestId = input.linkRequestId;
|
|
1713
|
+
const approvalUrl = safeLinkApprovalUrl(input.approvalUrl);
|
|
1714
|
+
if (approvalUrl) this.approvalUrl = approvalUrl;
|
|
1669
1715
|
this.holdReleased = input.holdReleased;
|
|
1670
1716
|
}
|
|
1671
1717
|
};
|
|
@@ -2973,6 +3019,11 @@ async function closeLinkRequest(wallet, id) {
|
|
|
2973
3019
|
return status !== void 0 && LINK_CLOSED_STATUSES.has(status);
|
|
2974
3020
|
}
|
|
2975
3021
|
}
|
|
3022
|
+
function assertLinkApprovalCallback(callback) {
|
|
3023
|
+
if (callback !== void 0 && typeof callback !== "function") {
|
|
3024
|
+
throw checkoutError("onLinkApproval must be a function");
|
|
3025
|
+
}
|
|
3026
|
+
}
|
|
2976
3027
|
function linkCreatedNothing(error) {
|
|
2977
3028
|
return errorCode(error) === "LINK_WALLET_UNAVAILABLE" || errorReason(error) === "invalid_input";
|
|
2978
3029
|
}
|
|
@@ -2982,6 +3033,23 @@ var LinkFailureSignal = class extends Error {
|
|
|
2982
3033
|
this.failure = failure;
|
|
2983
3034
|
}
|
|
2984
3035
|
};
|
|
3036
|
+
function linkApprovalDetails(request) {
|
|
3037
|
+
const approvalUrl = safeLinkApprovalUrl(request.approvalUrl);
|
|
3038
|
+
const approvalExpiresAt = linkTime(request.approvalExpiresAt);
|
|
3039
|
+
return {
|
|
3040
|
+
...approvalUrl ? { approvalUrl } : {},
|
|
3041
|
+
...approvalExpiresAt ? { approvalExpiresAt } : {}
|
|
3042
|
+
};
|
|
3043
|
+
}
|
|
3044
|
+
function notifyLinkApproval(callback, event) {
|
|
3045
|
+
try {
|
|
3046
|
+
const result = callback(Object.freeze(event));
|
|
3047
|
+
if (result !== null && typeof result === "object" && "then" in result) {
|
|
3048
|
+
Promise.resolve(result).catch(() => void 0);
|
|
3049
|
+
}
|
|
3050
|
+
} catch {
|
|
3051
|
+
}
|
|
3052
|
+
}
|
|
2985
3053
|
var _client4, _CheckoutClient_instances, linkCardFor_fn;
|
|
2986
3054
|
var CheckoutClient = class {
|
|
2987
3055
|
constructor(client) {
|
|
@@ -3167,7 +3235,9 @@ var CheckoutClient = class {
|
|
|
3167
3235
|
* 1. Conto runs checkpoint 1 and holds the spend. When a rule requires the
|
|
3168
3236
|
* owner's approval, this waits for it.
|
|
3169
3237
|
* 2. Only then does the wallet ask Link for a card for exactly the approved
|
|
3170
|
-
* amount at this merchant. The person approves it in
|
|
3238
|
+
* amount at this merchant. The person approves it in Link. Pass
|
|
3239
|
+
* onLinkApproval to get Link's approval page, so they can approve on the
|
|
3240
|
+
* web without the Link app.
|
|
3171
3241
|
* 3. The card is returned. It never reaches Conto.
|
|
3172
3242
|
*
|
|
3173
3243
|
* Then fill in the card, call confirm(result.checkpoint, { amountMinor,
|
|
@@ -3183,10 +3253,18 @@ var CheckoutClient = class {
|
|
|
3183
3253
|
* Link request.
|
|
3184
3254
|
*/
|
|
3185
3255
|
async getLinkCard(input) {
|
|
3186
|
-
const {
|
|
3256
|
+
const {
|
|
3257
|
+
wallet,
|
|
3258
|
+
ownerApprovalTimeoutMs,
|
|
3259
|
+
linkApprovalTimeoutMs,
|
|
3260
|
+
onLinkApproval,
|
|
3261
|
+
signal,
|
|
3262
|
+
...beginInput
|
|
3263
|
+
} = input;
|
|
3187
3264
|
if (!wallet || typeof wallet.createCardRequest !== "function") {
|
|
3188
3265
|
throw checkoutError("wallet must be a LinkWallet, such as linkCliWallet()");
|
|
3189
3266
|
}
|
|
3267
|
+
assertLinkApprovalCallback(onLinkApproval);
|
|
3190
3268
|
let checkpoint = await this.begin({ ...beginInput, checkoutMethod: "LINK" });
|
|
3191
3269
|
if (checkpoint.stage === "AWAITING_APPROVAL") {
|
|
3192
3270
|
checkpoint = await this.waitForApproval(checkpoint, {
|
|
@@ -3194,7 +3272,11 @@ var CheckoutClient = class {
|
|
|
3194
3272
|
...signal ? { signal } : {}
|
|
3195
3273
|
});
|
|
3196
3274
|
}
|
|
3197
|
-
return __privateMethod(this, _CheckoutClient_instances, linkCardFor_fn).call(this, checkpoint, wallet,
|
|
3275
|
+
return __privateMethod(this, _CheckoutClient_instances, linkCardFor_fn).call(this, checkpoint, wallet, {
|
|
3276
|
+
linkApprovalTimeoutMs,
|
|
3277
|
+
signal,
|
|
3278
|
+
onLinkApproval
|
|
3279
|
+
});
|
|
3198
3280
|
}
|
|
3199
3281
|
/**
|
|
3200
3282
|
* The final total differs from the one the Link card covers. This cancels
|
|
@@ -3203,10 +3285,18 @@ var CheckoutClient = class {
|
|
|
3203
3285
|
* for it. Confirm the returned checkpoint with the same total.
|
|
3204
3286
|
*/
|
|
3205
3287
|
async replaceLinkCard(previous, input) {
|
|
3206
|
-
const {
|
|
3288
|
+
const {
|
|
3289
|
+
wallet,
|
|
3290
|
+
amountMinor,
|
|
3291
|
+
ownerApprovalTimeoutMs,
|
|
3292
|
+
linkApprovalTimeoutMs,
|
|
3293
|
+
onLinkApproval,
|
|
3294
|
+
signal
|
|
3295
|
+
} = input;
|
|
3207
3296
|
if (!Number.isSafeInteger(amountMinor) || amountMinor <= 0) {
|
|
3208
3297
|
throw checkoutError("amountMinor must be a positive integer number of cents");
|
|
3209
3298
|
}
|
|
3299
|
+
assertLinkApprovalCallback(onLinkApproval);
|
|
3210
3300
|
if (amountMinor === previous.checkpoint.amountMinor) return previous;
|
|
3211
3301
|
const old = previous.checkpoint;
|
|
3212
3302
|
if (!await closeLinkRequest(wallet, previous.linkRequestId)) {
|
|
@@ -3245,12 +3335,17 @@ var CheckoutClient = class {
|
|
|
3245
3335
|
...signal ? { signal } : {}
|
|
3246
3336
|
});
|
|
3247
3337
|
}
|
|
3248
|
-
return __privateMethod(this, _CheckoutClient_instances, linkCardFor_fn).call(this, checkpoint, wallet,
|
|
3338
|
+
return __privateMethod(this, _CheckoutClient_instances, linkCardFor_fn).call(this, checkpoint, wallet, {
|
|
3339
|
+
linkApprovalTimeoutMs,
|
|
3340
|
+
signal,
|
|
3341
|
+
onLinkApproval
|
|
3342
|
+
});
|
|
3249
3343
|
}
|
|
3250
3344
|
};
|
|
3251
3345
|
_client4 = new WeakMap();
|
|
3252
3346
|
_CheckoutClient_instances = new WeakSet();
|
|
3253
|
-
linkCardFor_fn = async function(checkpoint, wallet,
|
|
3347
|
+
linkCardFor_fn = async function(checkpoint, wallet, options) {
|
|
3348
|
+
const { linkApprovalTimeoutMs = 10 * 6e4, signal, onLinkApproval } = options;
|
|
3254
3349
|
if (checkpoint.stage !== "APPROVED") {
|
|
3255
3350
|
throw checkoutError(
|
|
3256
3351
|
`Conto has not approved a card for this checkpoint (stage ${checkpoint.stage}). Do not pay.`,
|
|
@@ -3260,6 +3355,7 @@ linkCardFor_fn = async function(checkpoint, wallet, linkApprovalTimeoutMs = 10 *
|
|
|
3260
3355
|
const deadline = Date.now() + linkApprovalTimeoutMs;
|
|
3261
3356
|
const call = signal ? { signal } : {};
|
|
3262
3357
|
let linkRequestId;
|
|
3358
|
+
let approvalUrl;
|
|
3263
3359
|
let createStarted = false;
|
|
3264
3360
|
try {
|
|
3265
3361
|
const cardRequest = linkCardRequest(checkpoint);
|
|
@@ -3280,6 +3376,13 @@ linkCardFor_fn = async function(checkpoint, wallet, linkApprovalTimeoutMs = 10 *
|
|
|
3280
3376
|
message: "Link returned a request for a different amount."
|
|
3281
3377
|
});
|
|
3282
3378
|
}
|
|
3379
|
+
if (LINK_WAITING_STATUSES.has(request.status)) {
|
|
3380
|
+
const details = linkApprovalDetails(request);
|
|
3381
|
+
approvalUrl = details.approvalUrl;
|
|
3382
|
+
if (onLinkApproval) {
|
|
3383
|
+
notifyLinkApproval(onLinkApproval, { checkpoint, linkRequestId: request.id, ...details });
|
|
3384
|
+
}
|
|
3385
|
+
}
|
|
3283
3386
|
while (linkRequestWaiting(request)) {
|
|
3284
3387
|
const remainingSeconds = Math.floor((deadline - Date.now()) / 1e3);
|
|
3285
3388
|
if (remainingSeconds <= 0) {
|
|
@@ -3294,6 +3397,7 @@ linkCardFor_fn = async function(checkpoint, wallet, linkApprovalTimeoutMs = 10 *
|
|
|
3294
3397
|
...call,
|
|
3295
3398
|
timeoutSeconds: remainingSeconds
|
|
3296
3399
|
});
|
|
3400
|
+
approvalUrl = LINK_WAITING_STATUSES.has(request.status) ? linkApprovalDetails(request).approvalUrl ?? approvalUrl : void 0;
|
|
3297
3401
|
if (linkRequestWaiting(request) && Date.now() - started < 1e3) {
|
|
3298
3402
|
await sleep2(1e3, signal);
|
|
3299
3403
|
}
|
|
@@ -3325,6 +3429,7 @@ linkCardFor_fn = async function(checkpoint, wallet, linkApprovalTimeoutMs = 10 *
|
|
|
3325
3429
|
code: "LINK_CARD_NOT_CANCELLED",
|
|
3326
3430
|
checkpoint,
|
|
3327
3431
|
linkRequestId,
|
|
3432
|
+
...approvalUrl ? { approvalUrl } : {},
|
|
3328
3433
|
holdReleased: false,
|
|
3329
3434
|
retryGuidance: "Retry with the same input to resume this Link request, or cancel it with wallet.cancel(error.linkRequestId) and then call checkout.cancel(error.checkpoint.id)."
|
|
3330
3435
|
});
|
|
@@ -3338,6 +3443,7 @@ linkCardFor_fn = async function(checkpoint, wallet, linkApprovalTimeoutMs = 10 *
|
|
|
3338
3443
|
code: failure.code,
|
|
3339
3444
|
checkpoint,
|
|
3340
3445
|
...linkRequestId ? { linkRequestId } : {},
|
|
3446
|
+
...linkRequestId && approvalUrl ? { approvalUrl } : {},
|
|
3341
3447
|
holdReleased
|
|
3342
3448
|
});
|
|
3343
3449
|
}
|