@primitivedotdev/sdk 1.4.0 → 1.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/README.md +56 -19
- package/dist/api/index.d.ts +2 -2
- package/dist/api/index.js +3 -3
- package/dist/{api-DoB7DrgV.js → api-ClLMDF81.js} +251 -1
- package/dist/{index-BDjVGtc8.d.ts → index-BnbrY8kp.d.ts} +885 -8
- package/dist/index.d.ts +3 -3
- package/dist/index.js +1 -1
- package/dist/openapi/index.js +1 -1
- package/dist/{operations.generated-XrEy5EtX.js → operations.generated-DQIrhCT5.js} +1856 -21
- package/dist/x402/index.d.ts +36 -4
- package/dist/x402/index.js +38 -8
- package/package.json +1 -1
package/dist/x402/index.d.ts
CHANGED
|
@@ -184,9 +184,27 @@ interface X402SpendPolicy {
|
|
|
184
184
|
/** Allowed payee org ids; null = any on-net payee, [] = deny all. */
|
|
185
185
|
allowlist: string[] | null;
|
|
186
186
|
}
|
|
187
|
-
|
|
188
|
-
|
|
187
|
+
/** A payment the org's spend policy refused (read shape). */
|
|
188
|
+
interface X402DeclinedPayment {
|
|
189
|
+
id: string;
|
|
190
|
+
challenge_id: string | null;
|
|
191
|
+
counterparty_org: string | null;
|
|
192
|
+
network: string;
|
|
189
193
|
amount: string;
|
|
194
|
+
reason: string;
|
|
195
|
+
declined_at: string;
|
|
196
|
+
}
|
|
197
|
+
interface X402ChargeInput {
|
|
198
|
+
/**
|
|
199
|
+
* Amount in token base units (USDC has 6 decimals, so "10000" = 0.01).
|
|
200
|
+
* Provide exactly one of `amount` or `amountUsdc`.
|
|
201
|
+
*/
|
|
202
|
+
amount?: string;
|
|
203
|
+
/**
|
|
204
|
+
* Amount as human USDC (e.g. "0.01"), converted to base units for you.
|
|
205
|
+
* Provide exactly one of `amount` or `amountUsdc`.
|
|
206
|
+
*/
|
|
207
|
+
amountUsdc?: string;
|
|
190
208
|
/** Defaults to "base-sepolia". */
|
|
191
209
|
network?: string;
|
|
192
210
|
/** The org id allowed to pay this challenge (on-net binding). */
|
|
@@ -196,6 +214,11 @@ interface X402ChargeInput {
|
|
|
196
214
|
resource?: string;
|
|
197
215
|
/** Seconds until the challenge expires (default 1h). */
|
|
198
216
|
expiresIn?: number;
|
|
217
|
+
/**
|
|
218
|
+
* Optional idempotency key. Retrying `charge()` with the same key returns the
|
|
219
|
+
* original challenge instead of creating a duplicate.
|
|
220
|
+
*/
|
|
221
|
+
idempotencyKey?: string;
|
|
199
222
|
}
|
|
200
223
|
declare class X402Error extends Error {
|
|
201
224
|
/** HTTP status, or 0 for a client-side / transport error that never reached the server. */
|
|
@@ -238,16 +261,25 @@ declare class X402Client {
|
|
|
238
261
|
* address becomes (or updates to) the default payout destination for the
|
|
239
262
|
* network. `charge()` resolves its `pay_to` from this directory, so a payee
|
|
240
263
|
* must register before requesting payments.
|
|
264
|
+
*
|
|
265
|
+
* `org` is optional: when omitted it is resolved from your authenticated
|
|
266
|
+
* account, so most callers never need to supply it.
|
|
241
267
|
*/
|
|
242
268
|
registerPayoutAddress(input: {
|
|
243
|
-
org
|
|
269
|
+
org?: string;
|
|
244
270
|
network?: string;
|
|
245
271
|
issuedAt?: string;
|
|
272
|
+
label?: string;
|
|
246
273
|
}, options: {
|
|
247
274
|
signer: X402Signer;
|
|
248
275
|
}): Promise<X402PayoutAddress>;
|
|
249
276
|
/** List your org's registered payout addresses. */
|
|
250
277
|
listPayoutAddresses(): Promise<X402PayoutAddress[]>;
|
|
278
|
+
/**
|
|
279
|
+
* List the most recent payments your org's spend policy declined (newest
|
|
280
|
+
* first). Use this to see why an outbound payment was refused.
|
|
281
|
+
*/
|
|
282
|
+
listDeclinedPayments(): Promise<X402DeclinedPayment[]>;
|
|
251
283
|
/** Read your org's spend policy (kill-switch + caps + allowlist). */
|
|
252
284
|
getSpendPolicy(): Promise<X402SpendPolicy>;
|
|
253
285
|
/**
|
|
@@ -260,4 +292,4 @@ declare class X402Client {
|
|
|
260
292
|
}
|
|
261
293
|
declare function createX402Client(options?: X402ClientOptions): X402Client;
|
|
262
294
|
//#endregion
|
|
263
|
-
export { NonceBinding, PayoutRegistrationMessageInput, TRANSFER_WITH_AUTHORIZATION_TYPES, TokenDomain, TransferAuthorization, TransferWithAuthorizationTypedData, X402Challenge, X402ChargeInput, X402Client, X402ClientOptions, X402Error, X402PaymentPayload, X402PaymentRequirements, X402PayoutAddress, X402Receipt, X402Signer, X402SpendPolicy, buildPayoutRegistrationMessage, createX402Client, deriveEip3009Nonce, toPaymentPayload, transferWithAuthorizationTypedData };
|
|
295
|
+
export { NonceBinding, PayoutRegistrationMessageInput, TRANSFER_WITH_AUTHORIZATION_TYPES, TokenDomain, TransferAuthorization, TransferWithAuthorizationTypedData, X402Challenge, X402ChargeInput, X402Client, X402ClientOptions, X402DeclinedPayment, X402Error, X402PaymentPayload, X402PaymentRequirements, X402PayoutAddress, X402Receipt, X402Signer, X402SpendPolicy, buildPayoutRegistrationMessage, createX402Client, deriveEip3009Nonce, toPaymentPayload, transferWithAuthorizationTypedData };
|
package/dist/x402/index.js
CHANGED
|
@@ -127,12 +127,22 @@ const SETTLEMENT_MARGIN_SEC = 300;
|
|
|
127
127
|
const DEFAULT_BASE_URL = "https://api.primitive.dev";
|
|
128
128
|
const CHARGE_INPUT_KEYS = {
|
|
129
129
|
amount: true,
|
|
130
|
+
amountUsdc: true,
|
|
130
131
|
network: true,
|
|
131
132
|
payerOrg: true,
|
|
132
133
|
description: true,
|
|
133
134
|
resource: true,
|
|
134
|
-
expiresIn: true
|
|
135
|
+
expiresIn: true,
|
|
136
|
+
idempotencyKey: true
|
|
135
137
|
};
|
|
138
|
+
function usdcToBaseUnits(human) {
|
|
139
|
+
const trimmed = human.trim();
|
|
140
|
+
if (!/^\d+(\.\d+)?$/.test(trimmed)) return null;
|
|
141
|
+
const [whole, frac = ""] = trimmed.split(".");
|
|
142
|
+
if (frac.length > 6) return null;
|
|
143
|
+
const base = BigInt(whole) * 1000000n + BigInt(frac.padEnd(6, "0"));
|
|
144
|
+
return base > 0n ? base.toString() : null;
|
|
145
|
+
}
|
|
136
146
|
var X402Error = class extends Error {
|
|
137
147
|
/** HTTP status, or 0 for a client-side / transport error that never reached the server. */
|
|
138
148
|
status;
|
|
@@ -189,7 +199,8 @@ var X402Client = class {
|
|
|
189
199
|
method,
|
|
190
200
|
headers: {
|
|
191
201
|
authorization: `Bearer ${this.#apiKey}`,
|
|
192
|
-
"content-type": "application/json"
|
|
202
|
+
"content-type": "application/json",
|
|
203
|
+
...init?.headers
|
|
193
204
|
},
|
|
194
205
|
body: body === void 0 ? void 0 : JSON.stringify(body),
|
|
195
206
|
signal
|
|
@@ -212,16 +223,18 @@ var X402Client = class {
|
|
|
212
223
|
/** Request a payment (payee side). Returns the challenge to hand to the payer. */
|
|
213
224
|
async charge(input) {
|
|
214
225
|
for (const key of Object.keys(input)) if (!(key in CHARGE_INPUT_KEYS)) throw new X402Error(`unknown charge() option "${key}"; expected one of: ${Object.keys(CHARGE_INPUT_KEYS).join(", ")}`, 0);
|
|
215
|
-
if (
|
|
226
|
+
if (input.amount !== void 0 && input.amountUsdc !== void 0) throw new X402Error("charge() takes exactly one of `amount` (base units) or `amountUsdc` (human USDC), not both", 0);
|
|
227
|
+
const amount = input.amountUsdc !== void 0 ? usdcToBaseUnits(input.amountUsdc) : input.amount ?? null;
|
|
228
|
+
if (!amount || !/^[1-9][0-9]{0,38}$/.test(amount)) throw new X402Error("charge() requires `amount` as a positive integer string in token base units (e.g. \"10000\"), or `amountUsdc` as a positive USDC amount with at most 6 decimals (e.g. \"0.01\")", 0);
|
|
216
229
|
const body = {
|
|
217
|
-
amount
|
|
230
|
+
amount,
|
|
218
231
|
network: input.network ?? "base-sepolia"
|
|
219
232
|
};
|
|
220
233
|
if (input.payerOrg) body.payer_org = input.payerOrg;
|
|
221
234
|
if (input.description) body.description = input.description;
|
|
222
235
|
if (input.resource) body.resource = input.resource;
|
|
223
236
|
if (input.expiresIn !== void 0) body.expires_in = input.expiresIn;
|
|
224
|
-
return this.#request("POST", "/v1/x402/challenges", body);
|
|
237
|
+
return this.#request("POST", "/v1/x402/challenges", body, { headers: input.idempotencyKey ? { "idempotency-key": input.idempotencyKey } : void 0 });
|
|
225
238
|
}
|
|
226
239
|
/**
|
|
227
240
|
* Pay a challenge (payer side). Derives the interaction-bound authorization,
|
|
@@ -268,21 +281,30 @@ var X402Client = class {
|
|
|
268
281
|
if (!id) throw new X402Error("getChallenge() requires a challenge id", 0);
|
|
269
282
|
return this.#request("GET", `/v1/x402/challenges/${encodeURIComponent(id)}`);
|
|
270
283
|
}
|
|
284
|
+
/** Resolve the caller's own organization id from the account endpoint. */
|
|
285
|
+
async #resolveOrgId() {
|
|
286
|
+
const account = await this.#request("GET", "/v1/account");
|
|
287
|
+
if (!account?.id) throw new X402Error("could not resolve your organization id from /v1/account; pass { org } explicitly", 0);
|
|
288
|
+
return account.id;
|
|
289
|
+
}
|
|
271
290
|
/**
|
|
272
291
|
* Register a payout address for your org (payee side). The signer proves
|
|
273
292
|
* control of its own address with an org-bound `personal_sign`; the proven
|
|
274
293
|
* address becomes (or updates to) the default payout destination for the
|
|
275
294
|
* network. `charge()` resolves its `pay_to` from this directory, so a payee
|
|
276
295
|
* must register before requesting payments.
|
|
296
|
+
*
|
|
297
|
+
* `org` is optional: when omitted it is resolved from your authenticated
|
|
298
|
+
* account, so most callers never need to supply it.
|
|
277
299
|
*/
|
|
278
300
|
async registerPayoutAddress(input, options) {
|
|
279
|
-
if (!input?.org) throw new X402Error("registerPayoutAddress() requires an org id", 0);
|
|
280
301
|
if (typeof options?.signer?.signMessage !== "function") throw new X402Error("registerPayoutAddress() requires a signer with signMessage (e.g. a viem LocalAccount)", 0);
|
|
302
|
+
const org = input.org ?? await this.#resolveOrgId();
|
|
281
303
|
const network = input.network ?? "base-sepolia";
|
|
282
304
|
const issuedAt = input.issuedAt ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
283
305
|
const address = options.signer.address;
|
|
284
306
|
const message = buildPayoutRegistrationMessage({
|
|
285
|
-
org
|
|
307
|
+
org,
|
|
286
308
|
address,
|
|
287
309
|
network,
|
|
288
310
|
issuedAt
|
|
@@ -292,13 +314,21 @@ var X402Client = class {
|
|
|
292
314
|
address,
|
|
293
315
|
network,
|
|
294
316
|
signature,
|
|
295
|
-
issued_at: issuedAt
|
|
317
|
+
issued_at: issuedAt,
|
|
318
|
+
...input.label !== void 0 ? { label: input.label } : {}
|
|
296
319
|
});
|
|
297
320
|
}
|
|
298
321
|
/** List your org's registered payout addresses. */
|
|
299
322
|
async listPayoutAddresses() {
|
|
300
323
|
return this.#request("GET", "/v1/x402/payout-addresses");
|
|
301
324
|
}
|
|
325
|
+
/**
|
|
326
|
+
* List the most recent payments your org's spend policy declined (newest
|
|
327
|
+
* first). Use this to see why an outbound payment was refused.
|
|
328
|
+
*/
|
|
329
|
+
async listDeclinedPayments() {
|
|
330
|
+
return this.#request("GET", "/v1/x402/declined-payments");
|
|
331
|
+
}
|
|
302
332
|
/** Read your org's spend policy (kill-switch + caps + allowlist). */
|
|
303
333
|
async getSpendPolicy() {
|
|
304
334
|
return this.#request("GET", "/v1/x402/spend-policy");
|
package/package.json
CHANGED