@curless/agentbank-sdk 0.1.3 → 0.3.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.
@@ -0,0 +1,139 @@
1
+ import type { SpendPolicy } from './types.js';
2
+ export type BuyerUser = {
3
+ id: string;
4
+ email: string;
5
+ name: string | null;
6
+ mode: string;
7
+ };
8
+ /** Who the session is + what it may spend. Amounts are minor units. */
9
+ export type WalletSelf = {
10
+ id: string;
11
+ email: string;
12
+ name: string | null;
13
+ mode: string;
14
+ status: string;
15
+ defaultCurrency: string;
16
+ spendPolicy: SpendPolicy;
17
+ spentToday: number;
18
+ spentMonth: number;
19
+ /** Whether a card is bound — never which card. */
20
+ cardBound: boolean;
21
+ };
22
+ /** A card reference. Never a PAN: the number lives only at Stripe. */
23
+ export type BoundCard = {
24
+ id: string;
25
+ brand: string | null;
26
+ last4: string | null;
27
+ expMonth: number | null;
28
+ expYear: number | null;
29
+ funding: string | null;
30
+ };
31
+ /**
32
+ * `unavailable` is the whole point of this shape. An empty `cards` with no
33
+ * `unavailable` means the buyer has bound none; an empty `cards` WITH it means
34
+ * we could not read them. A caller that flattens the two tells someone their
35
+ * cards are gone and watches them bind another.
36
+ */
37
+ export type BoundCards = {
38
+ cards: BoundCard[];
39
+ unavailable?: string;
40
+ };
41
+ export type WalletBalance = {
42
+ mode: string;
43
+ balances: Array<{
44
+ currency: string;
45
+ amount: number;
46
+ kind: string;
47
+ }>;
48
+ };
49
+ export type WalletOrder = {
50
+ id: string;
51
+ amount: number;
52
+ currency: string;
53
+ status: string;
54
+ createdAt: string;
55
+ };
56
+ export type WalletOrders = {
57
+ mode: string;
58
+ orders: WalletOrder[];
59
+ };
60
+ /**
61
+ * A one-off credential, not a card: one seller, one currency, one maximum,
62
+ * fifteen minutes. Hand `token` to that merchant's checkout as the payment
63
+ * token — it cannot be replayed against a different merchant or a larger sum.
64
+ */
65
+ export type PaymentCredential = {
66
+ token: string;
67
+ maxAmount: number;
68
+ currency: string;
69
+ expiresAt: string;
70
+ };
71
+ export type DeviceLogin = {
72
+ userCode: string;
73
+ verificationUri: string;
74
+ verificationUriComplete: string;
75
+ expiresIn: number;
76
+ interval: number;
77
+ };
78
+ export type BuyerSession = {
79
+ login: (email: string, password: string) => Promise<BuyerUser>;
80
+ /**
81
+ * Begin a browser sign-in for a client that has no browser.
82
+ *
83
+ * Returns where to send the person and a `wait()` that resolves when they
84
+ * finish there. The device code itself never leaves this object — it is the
85
+ * bearer credential that collects the resulting session, so handing it to a
86
+ * caller who only needs a URL would be handing out the login.
87
+ */
88
+ startDeviceLogin: () => Promise<DeviceLogin & {
89
+ wait: () => Promise<BuyerUser>;
90
+ }>;
91
+ fetch: <T>(path: string, init?: RequestInit) => Promise<T>;
92
+ /** Who this session is, and what it is allowed to spend. */
93
+ me: () => Promise<WalletSelf>;
94
+ /**
95
+ * Replace this wallet's spend policy. Sent whole, not merged: an omitted
96
+ * field CLEARS that limit, so read `me()` first and spread if you mean to
97
+ * change one. Returns the wallet as it now stands.
98
+ */
99
+ setLimits: (policy: SpendPolicy) => Promise<WalletSelf>;
100
+ balance: () => Promise<WalletBalance>;
101
+ /** Newest first. `limit` is capped at 100 server-side; default 20. */
102
+ orders: (opts?: {
103
+ limit?: number;
104
+ }) => Promise<WalletOrders>;
105
+ cards: () => Promise<BoundCards>;
106
+ /**
107
+ * Bind a card by Stripe reference (`pm_…` / `tok_…`) so it can be charged
108
+ * again — binding IS attaching it to the buyer's Stripe customer.
109
+ *
110
+ * Never pass a card number. A PAN reaching a server is a compliance
111
+ * incident, and this one refuses it rather than storing it.
112
+ */
113
+ bindCard: (paymentMethod: string) => Promise<{
114
+ card: BoundCard;
115
+ }>;
116
+ unbindCard: (paymentMethodId: string) => Promise<{
117
+ ok: true;
118
+ detached: string;
119
+ }>;
120
+ /**
121
+ * Mint a credential for one payment. The buyer's own limits are evaluated
122
+ * here — a refusal is the buyer's limit talking, not a payment failure, and
123
+ * is worth reporting to them in those words.
124
+ */
125
+ payCredential: (input: {
126
+ amount: number;
127
+ currency: string;
128
+ merchantRef?: string;
129
+ }) => Promise<PaymentCredential>;
130
+ current: () => BuyerUser | null;
131
+ /** Revoke the session server-side, then forget it. Safe to call signed out. */
132
+ logout: () => Promise<void>;
133
+ };
134
+ export declare const NOT_LOGGED_IN = "buyer_not_logged_in";
135
+ export declare const SESSION_EXPIRED = "buyer_session_expired";
136
+ export declare const createBuyerSession: (opts: {
137
+ baseUrl: string;
138
+ }) => BuyerSession;
139
+ //# sourceMappingURL=buyer-wallet.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buyer-wallet.d.ts","sourceRoot":"","sources":["../src/buyer-wallet.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,162 @@
1
+ import { AgentbankError, toError } from '@curless/agentbank-core';
2
+ // Distinct codes so the model can tell the two states apart and say the right
3
+ // thing to the person. Collapsing them is how "your session expired" gets
4
+ // rendered as "you have no orders".
5
+ export const NOT_LOGGED_IN = 'buyer_not_logged_in';
6
+ export const SESSION_EXPIRED = 'buyer_session_expired';
7
+ export const createBuyerSession = (opts) => {
8
+ let token = null;
9
+ let user = null;
10
+ // Wall-clock expiry from the server's expiresIn, so an obviously-dead token
11
+ // is reported as expired without a round-trip that would 401 anyway.
12
+ let expiresAt = 0;
13
+ const call = async (path, init = {}, bearer,
14
+ // Statuses that carry a meaningful body rather than an error. Device
15
+ // polling uses it: 202 means "not yet", which is an answer.
16
+ alsoOk) => {
17
+ let res;
18
+ try {
19
+ res = await fetch(`${opts.baseUrl}${path}`, {
20
+ ...init,
21
+ headers: {
22
+ 'content-type': 'application/json',
23
+ ...(bearer ? { authorization: `Bearer ${bearer}` } : {}),
24
+ ...(init.headers ?? {}),
25
+ },
26
+ });
27
+ }
28
+ catch (err) {
29
+ throw new AgentbankError(0, 'network_error', `agentbank API unreachable at ${opts.baseUrl}: ${err.message}`);
30
+ }
31
+ if (!res.ok && !alsoOk?.(res.status)) {
32
+ const text = await res.text().catch(() => '');
33
+ let json;
34
+ try {
35
+ json = text ? JSON.parse(text) : undefined;
36
+ }
37
+ catch {
38
+ json = undefined;
39
+ }
40
+ throw toError(res.status, json);
41
+ }
42
+ return (await res.json());
43
+ };
44
+ const adopt = (body) => {
45
+ token = body.token;
46
+ user = body.user;
47
+ expiresAt = Date.now() + body.expiresIn * 1000;
48
+ return body.user;
49
+ };
50
+ const session = {
51
+ startDeviceLogin: async () => {
52
+ const started = await call('/v1/buyer/device', {
53
+ method: 'POST',
54
+ body: '{}',
55
+ });
56
+ const deadline = Date.now() + started.expiresIn * 1000;
57
+ const wait = async () => {
58
+ // Server-driven interval, and it can raise it: a `slow_down` that the
59
+ // client ignores is a client that keeps being told to slow down.
60
+ let waitMs = started.interval * 1000;
61
+ while (Date.now() < deadline) {
62
+ await new Promise((r) => setTimeout(r, waitMs));
63
+ const res = await call('/v1/buyer/device/token', { method: 'POST', body: JSON.stringify({ deviceCode: started.deviceCode }) }, undefined,
64
+ // 202 is "not finished", not a failure — the generic error path
65
+ // would abandon a login the person is still completing.
66
+ (status) => status === 202).catch((err) => {
67
+ throw err;
68
+ });
69
+ if (res.status === 'approved' && res.token && res.user) {
70
+ return adopt({ token: res.token, expiresIn: res.expiresIn ?? 3600, user: res.user });
71
+ }
72
+ if (res.status === 'slow_down')
73
+ waitMs = Math.min(waitMs * 2, 10_000);
74
+ }
75
+ throw new AgentbankError(408, 'buyer_login_timeout', 'the sign-in was not completed in time — start it again');
76
+ };
77
+ const { deviceCode: _secret, ...publicPart } = started;
78
+ return { ...publicPart, wait };
79
+ },
80
+ login: async (email, password) => {
81
+ const body = await call('/v1/buyer/session', { method: 'POST', body: JSON.stringify({ email, password }) });
82
+ return adopt(body);
83
+ },
84
+ fetch: async (path, init = {}) => {
85
+ if (!token) {
86
+ throw new AgentbankError(401, NOT_LOGGED_IN, 'no wallet session on this server yet — call wallet_login with the buyer’s email first');
87
+ }
88
+ if (Date.now() >= expiresAt) {
89
+ // Say it plainly and drop the dead token. A stale bearer that keeps
90
+ // getting sent turns every wallet read into an opaque 401, and an
91
+ // expired session rendered as an empty balance is a lie about money.
92
+ token = null;
93
+ const who = user?.email;
94
+ user = null;
95
+ throw new AgentbankError(401, SESSION_EXPIRED, `the wallet session${who ? ` for ${who}` : ''} has expired — call wallet_login again. This is NOT a zero balance and NOT an empty order list.`);
96
+ }
97
+ try {
98
+ return await call(path, init, token);
99
+ }
100
+ catch (err) {
101
+ // The server rejected a token we believed in — revoked, or signed by a
102
+ // deployment that has since rotated its secret. Same rule: report the
103
+ // session, not the resource.
104
+ //
105
+ // ⚠️ 401 ONLY. A 403 means the server knows exactly who this is and is
106
+ // refusing the ACTION — "over the limit you set", "live mode", "this
107
+ // wallet is suspended". Treating those as an expired session signs the
108
+ // person out for hitting their own spend cap, and then they cannot even
109
+ // raise it, because raising it needs the session they just lost.
110
+ if (err instanceof AgentbankError && err.status === 401) {
111
+ token = null;
112
+ user = null;
113
+ throw new AgentbankError(err.status, SESSION_EXPIRED, `the wallet session is no longer valid — call wallet_login again. This is NOT a zero balance and NOT an empty order list. (${err.message})`);
114
+ }
115
+ throw err;
116
+ }
117
+ },
118
+ current: () => user,
119
+ logout: async () => {
120
+ // Tell the server FIRST, while the credential still works. Forgetting it
121
+ // locally and then trying to revoke would leave a live token nobody can
122
+ // reach — a sign-out in appearance only.
123
+ if (token) {
124
+ await call('/v1/buyer/session/revoke', { method: 'POST', body: '{}' }, token).catch(() => undefined);
125
+ }
126
+ token = null;
127
+ user = null;
128
+ expiresAt = 0;
129
+ },
130
+ // ── the wallet itself ──
131
+ // Each of these is `fetch` with the path and the response type filled in.
132
+ // That is the entire difference, and it is the point: an integrator writing
133
+ // `session.fetch('/v1/buyer/me/cards')` holds a string we are free to break
134
+ // and their compiler cannot check. The paths stay ours to change; these
135
+ // methods are the contract.
136
+ //
137
+ // Deliberately no client-side validation of amounts or card references. The
138
+ // server already refuses a PAN and a limit breach; a second copy of those
139
+ // rules here is a second place for them to drift out of agreement with the
140
+ // first, and the copy that runs on the caller's machine is the one that
141
+ // cannot be trusted anyway.
142
+ me: () => session.fetch('/v1/buyer/me'),
143
+ setLimits: (policy) => session.fetch('/v1/buyer/me/limits', {
144
+ method: 'PUT',
145
+ body: JSON.stringify(policy),
146
+ }),
147
+ balance: () => session.fetch('/v1/buyer/me/balance'),
148
+ orders: (opts) => session.fetch(`/v1/buyer/me/orders${opts?.limit ? `?limit=${opts.limit}` : ''}`),
149
+ cards: () => session.fetch('/v1/buyer/me/cards'),
150
+ bindCard: (paymentMethod) => session.fetch('/v1/buyer/me/cards', {
151
+ method: 'POST',
152
+ body: JSON.stringify({ paymentMethod }),
153
+ }),
154
+ unbindCard: (paymentMethodId) => session.fetch(`/v1/buyer/me/cards/${encodeURIComponent(paymentMethodId)}`, { method: 'DELETE' }),
155
+ payCredential: (input) => session.fetch('/v1/buyer/me/payment-credential', {
156
+ method: 'POST',
157
+ body: JSON.stringify(input),
158
+ }),
159
+ };
160
+ return session;
161
+ };
162
+ //# sourceMappingURL=buyer-wallet.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buyer-wallet.js","sourceRoot":"","sources":["../src/buyer-wallet.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AA6IlE,8EAA8E;AAC9E,0EAA0E;AAC1E,oCAAoC;AACpC,MAAM,CAAC,MAAM,aAAa,GAAG,qBAAqB,CAAC;AACnD,MAAM,CAAC,MAAM,eAAe,GAAG,uBAAuB,CAAC;AAEvD,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,IAAyB,EAAgB,EAAE;IAC5E,IAAI,KAAK,GAAkB,IAAI,CAAC;IAChC,IAAI,IAAI,GAAqB,IAAI,CAAC;IAClC,4EAA4E;IAC5E,qEAAqE;IACrE,IAAI,SAAS,GAAG,CAAC,CAAC;IAElB,MAAM,IAAI,GAAG,KAAK,EAChB,IAAY,EACZ,OAAoB,EAAE,EACtB,MAAe;IACf,qEAAqE;IACrE,4DAA4D;IAC5D,MAAoC,EACxB,EAAE;QACd,IAAI,GAAa,CAAC;QAClB,IAAI,CAAC;YACH,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,EAAE,EAAE;gBAC1C,GAAG,IAAI;gBACP,OAAO,EAAE;oBACP,cAAc,EAAE,kBAAkB;oBAClC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,UAAU,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBACxD,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC;iBACxB;aACF,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,cAAc,CACtB,CAAC,EACD,eAAe,EACf,gCAAgC,IAAI,CAAC,OAAO,KAAM,GAAa,CAAC,OAAO,EAAE,CAC1E,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACrC,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;YAC9C,IAAI,IAAa,CAAC;YAClB,IAAI,CAAC;gBACH,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YAC7C,CAAC;YAAC,MAAM,CAAC;gBACP,IAAI,GAAG,SAAS,CAAC;YACnB,CAAC;YACD,MAAM,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAClC,CAAC;QACD,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAM,CAAC;IACjC,CAAC,CAAC;IAEF,MAAM,KAAK,GAAG,CAAC,IAA2D,EAAa,EAAE;QACvF,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QACnB,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACjB,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QAC/C,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC,CAAC;IAEF,MAAM,OAAO,GAAiB;QAC5B,gBAAgB,EAAE,KAAK,IAAI,EAAE;YAC3B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAuC,kBAAkB,EAAE;gBACnF,MAAM,EAAE,MAAM;gBACd,IAAI,EAAE,IAAI;aACX,CAAC,CAAC;YACH,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;YAEvD,MAAM,IAAI,GAAG,KAAK,IAAwB,EAAE;gBAC1C,sEAAsE;gBACtE,iEAAiE;gBACjE,IAAI,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;gBACrC,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;oBAC7B,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;oBAChD,MAAM,GAAG,GAAG,MAAM,IAAI,CAMpB,wBAAwB,EACxB,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC,EAAE,EAC5E,SAAS;oBACT,gEAAgE;oBAChE,wDAAwD;oBACxD,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,KAAK,GAAG,CAC3B,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;wBACd,MAAM,GAAG,CAAC;oBACZ,CAAC,CAAC,CAAC;oBACH,IAAI,GAAG,CAAC,MAAM,KAAK,UAAU,IAAI,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;wBACvD,OAAO,KAAK,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,IAAI,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;oBACvF,CAAC;oBACD,IAAI,GAAG,CAAC,MAAM,KAAK,WAAW;wBAAE,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;gBACxE,CAAC;gBACD,MAAM,IAAI,cAAc,CACtB,GAAG,EACH,qBAAqB,EACrB,wDAAwD,CACzD,CAAC;YACJ,CAAC,CAAC;YAEF,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,UAAU,EAAE,GAAG,OAAO,CAAC;YACvD,OAAO,EAAE,GAAG,UAAU,EAAE,IAAI,EAAE,CAAC;QACjC,CAAC;QAED,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE;YAC/B,MAAM,IAAI,GAAG,MAAM,IAAI,CACrB,mBAAmB,EACnB,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE,CAC9D,CAAC;YACF,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC;QACrB,CAAC;QAED,KAAK,EAAE,KAAK,EAAK,IAAY,EAAE,OAAoB,EAAE,EAAc,EAAE;YACnE,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,MAAM,IAAI,cAAc,CACtB,GAAG,EACH,aAAa,EACb,uFAAuF,CACxF,CAAC;YACJ,CAAC;YACD,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,SAAS,EAAE,CAAC;gBAC5B,oEAAoE;gBACpE,kEAAkE;gBAClE,qEAAqE;gBACrE,KAAK,GAAG,IAAI,CAAC;gBACb,MAAM,GAAG,GAAG,IAAI,EAAE,KAAK,CAAC;gBACxB,IAAI,GAAG,IAAI,CAAC;gBACZ,MAAM,IAAI,cAAc,CACtB,GAAG,EACH,eAAe,EACf,qBAAqB,GAAG,CAAC,CAAC,CAAC,QAAQ,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,iGAAiG,CAC/I,CAAC;YACJ,CAAC;YACD,IAAI,CAAC;gBACH,OAAO,MAAM,IAAI,CAAI,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;YAC1C,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,uEAAuE;gBACvE,sEAAsE;gBACtE,6BAA6B;gBAC7B,EAAE;gBACF,uEAAuE;gBACvE,qEAAqE;gBACrE,uEAAuE;gBACvE,wEAAwE;gBACxE,iEAAiE;gBACjE,IAAI,GAAG,YAAY,cAAc,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;oBACxD,KAAK,GAAG,IAAI,CAAC;oBACb,IAAI,GAAG,IAAI,CAAC;oBACZ,MAAM,IAAI,cAAc,CACtB,GAAG,CAAC,MAAM,EACV,eAAe,EACf,6HAA6H,GAAG,CAAC,OAAO,GAAG,CAC5I,CAAC;gBACJ,CAAC;gBACD,MAAM,GAAG,CAAC;YACZ,CAAC;QACH,CAAC;QAED,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI;QACnB,MAAM,EAAE,KAAK,IAAI,EAAE;YACjB,yEAAyE;YACzE,wEAAwE;YACxE,yCAAyC;YACzC,IAAI,KAAK,EAAE,CAAC;gBACV,MAAM,IAAI,CAAC,0BAA0B,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,KAAK,CAAC,CAAC,KAAK,CACjF,GAAG,EAAE,CAAC,SAAS,CAChB,CAAC;YACJ,CAAC;YACD,KAAK,GAAG,IAAI,CAAC;YACb,IAAI,GAAG,IAAI,CAAC;YACZ,SAAS,GAAG,CAAC,CAAC;QAChB,CAAC;QAED,0BAA0B;QAC1B,0EAA0E;QAC1E,4EAA4E;QAC5E,4EAA4E;QAC5E,wEAAwE;QACxE,4BAA4B;QAC5B,EAAE;QACF,4EAA4E;QAC5E,0EAA0E;QAC1E,2EAA2E;QAC3E,wEAAwE;QACxE,4BAA4B;QAC5B,EAAE,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAa,cAAc,CAAC;QACnD,SAAS,EAAE,CAAC,MAAM,EAAE,EAAE,CACpB,OAAO,CAAC,KAAK,CAAa,qBAAqB,EAAE;YAC/C,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;SAC7B,CAAC;QACJ,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAgB,sBAAsB,CAAC;QACnE,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CACf,OAAO,CAAC,KAAK,CACX,sBAAsB,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAClE;QACH,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAa,oBAAoB,CAAC;QAC5D,QAAQ,EAAE,CAAC,aAAa,EAAE,EAAE,CAC1B,OAAO,CAAC,KAAK,CAAsB,oBAAoB,EAAE;YACvD,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,aAAa,EAAE,CAAC;SACxC,CAAC;QACJ,UAAU,EAAE,CAAC,eAAe,EAAE,EAAE,CAC9B,OAAO,CAAC,KAAK,CACX,sBAAsB,kBAAkB,CAAC,eAAe,CAAC,EAAE,EAC3D,EAAE,MAAM,EAAE,QAAQ,EAAE,CACrB;QACH,aAAa,EAAE,CAAC,KAAK,EAAE,EAAE,CACvB,OAAO,CAAC,KAAK,CAAoB,iCAAiC,EAAE;YAClE,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;SAC5B,CAAC;KACL,CAAC;IAEF,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,15 @@
1
1
  export { Agentbank } from './client.js';
2
2
  export type { AgentbankOptions, FetchLike, RequestOptions } from './client.js';
3
- export { AgentbankError } from '@curless/agentbank-core';
3
+ export { AgentbankError, toError } from '@curless/agentbank-core';
4
+ /**
5
+ * The buyer's wallet session — the face an integrator actually uses.
6
+ *
7
+ * It lives HERE, not in @curless/agentbank-core: core is the shared kernel
8
+ * (crypto, errors, HTTP) that every package builds on, and nobody outside this
9
+ * repo should be importing it directly. This is the official buyer SDK, so this
10
+ * is where a buyer-side capability belongs.
11
+ */
12
+ export { NOT_LOGGED_IN, SESSION_EXPIRED, type BoundCard, type BoundCards, type BuyerSession, type BuyerUser, type DeviceLogin, type PaymentCredential, type WalletBalance, type WalletOrder, type WalletOrders, type WalletSelf, createBuyerSession, } from './buyer-wallet.js';
4
13
  export type { CreateAgentInput, UpdateAgentInput, AgentCredentialScope, } from './resources/agents.js';
5
14
  export type { CreateCustomerInput, UpdateCustomerInput } from './resources/customers.js';
6
15
  export type { CatalogItem, Merchant } from './resources/merchants.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,gBAAgB,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC/E,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,YAAY,EACV,gBAAgB,EAChB,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AACzF,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACtE,YAAY,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,YAAY,EACV,KAAK,EACL,eAAe,EACf,sBAAsB,EACtB,WAAW,EACX,kBAAkB,EAClB,QAAQ,EACR,cAAc,EACd,eAAe,EACf,QAAQ,EACR,SAAS,EACT,aAAa,EACb,mBAAmB,EACnB,mBAAmB,EACnB,WAAW,EACX,iBAAiB,EACjB,eAAe,EACf,kBAAkB,EAClB,wBAAwB,EACxB,WAAW,EACX,aAAa,GACd,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,gBAAgB,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC/E,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAElE;;;;;;;GAOG;AACH,OAAO,EACL,aAAa,EACb,eAAe,EACf,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,KAAK,SAAS,EACd,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,kBAAkB,GACnB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,gBAAgB,EAChB,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AACzF,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACtE,YAAY,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,YAAY,EACV,KAAK,EACL,eAAe,EACf,sBAAsB,EACtB,WAAW,EACX,kBAAkB,EAClB,QAAQ,EACR,cAAc,EACd,eAAe,EACf,QAAQ,EACR,SAAS,EACT,aAAa,EACb,mBAAmB,EACnB,mBAAmB,EACnB,WAAW,EACX,iBAAiB,EACjB,eAAe,EACf,kBAAkB,EAClB,wBAAwB,EACxB,WAAW,EACX,aAAa,GACd,MAAM,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -1,3 +1,12 @@
1
1
  export { Agentbank } from './client.js';
2
- export { AgentbankError } from '@curless/agentbank-core';
2
+ export { AgentbankError, toError } from '@curless/agentbank-core';
3
+ /**
4
+ * The buyer's wallet session — the face an integrator actually uses.
5
+ *
6
+ * It lives HERE, not in @curless/agentbank-core: core is the shared kernel
7
+ * (crypto, errors, HTTP) that every package builds on, and nobody outside this
8
+ * repo should be importing it directly. This is the official buyer SDK, so this
9
+ * is where a buyer-side capability belongs.
10
+ */
11
+ export { NOT_LOGGED_IN, SESSION_EXPIRED, createBuyerSession, } from './buyer-wallet.js';
3
12
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAElE;;;;;;;GAOG;AACH,OAAO,EACL,aAAa,EACb,eAAe,EAWf,kBAAkB,GACnB,MAAM,mBAAmB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@curless/agentbank-sdk",
3
- "version": "0.1.3",
3
+ "version": "0.3.0",
4
4
  "description": "Official buyer/agent SDK for agentbank — OAuth, agent + customer management, Wallets, and the Pay spend-control plane.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -17,7 +17,7 @@
17
17
  "README.md"
18
18
  ],
19
19
  "dependencies": {
20
- "@curless/agentbank-core": "^0.2.1"
20
+ "@curless/agentbank-core": "^0.7.0"
21
21
  },
22
22
  "devDependencies": {
23
23
  "@types/node": "^22.10.1",