primcli 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 +40 -1
- package/dist/oclif/index.js +2628 -148
- package/package.json +7 -2
package/dist/oclif/index.js
CHANGED
|
@@ -7,6 +7,8 @@ import process$1 from "node:process";
|
|
|
7
7
|
import { createInterface } from "node:readline/promises";
|
|
8
8
|
import { hostname } from "node:os";
|
|
9
9
|
import { spawn } from "node:child_process";
|
|
10
|
+
import { X402Error, createX402Client } from "@primitivedotdev/sdk/x402";
|
|
11
|
+
import { privateKeyToAccount } from "viem/accounts";
|
|
10
12
|
//#region \0rolldown/runtime.js
|
|
11
13
|
var __defProp = Object.defineProperty;
|
|
12
14
|
var __exportAll = (all, no_symbols) => {
|
|
@@ -28,21 +30,25 @@ var sdk_gen_exports = /* @__PURE__ */ __exportAll({
|
|
|
28
30
|
cliLogout: () => cliLogout,
|
|
29
31
|
createAgentAccount: () => createAgentAccount,
|
|
30
32
|
createAgentClaimLink: () => createAgentClaimLink,
|
|
33
|
+
createChallenge: () => createChallenge,
|
|
31
34
|
createEndpoint: () => createEndpoint,
|
|
32
35
|
createFilter: () => createFilter,
|
|
33
36
|
createFunction: () => createFunction,
|
|
34
37
|
createFunctionSecret: () => createFunctionSecret,
|
|
38
|
+
createOrgSecret: () => createOrgSecret,
|
|
35
39
|
deleteDomain: () => deleteDomain,
|
|
36
40
|
deleteEmail: () => deleteEmail,
|
|
37
41
|
deleteEndpoint: () => deleteEndpoint,
|
|
38
42
|
deleteFilter: () => deleteFilter,
|
|
39
43
|
deleteFunction: () => deleteFunction,
|
|
40
44
|
deleteFunctionSecret: () => deleteFunctionSecret,
|
|
45
|
+
deleteOrgSecret: () => deleteOrgSecret,
|
|
41
46
|
discardEmailContent: () => discardEmailContent,
|
|
42
47
|
downloadAttachments: () => downloadAttachments,
|
|
43
48
|
downloadDomainZoneFile: () => downloadDomainZoneFile,
|
|
44
49
|
downloadRawEmail: () => downloadRawEmail,
|
|
45
50
|
getAccount: () => getAccount,
|
|
51
|
+
getChallenge: () => getChallenge,
|
|
46
52
|
getConversation: () => getConversation,
|
|
47
53
|
getEmail: () => getEmail,
|
|
48
54
|
getFunction: () => getFunction,
|
|
@@ -52,9 +58,11 @@ var sdk_gen_exports = /* @__PURE__ */ __exportAll({
|
|
|
52
58
|
getOrgRoutingTopology: () => getOrgRoutingTopology,
|
|
53
59
|
getSendPermissions: () => getSendPermissions,
|
|
54
60
|
getSentEmail: () => getSentEmail,
|
|
61
|
+
getSpendPolicy: () => getSpendPolicy,
|
|
55
62
|
getStorageStats: () => getStorageStats,
|
|
56
63
|
getThread: () => getThread,
|
|
57
64
|
getWebhookSecret: () => getWebhookSecret,
|
|
65
|
+
listDeclinedPayments: () => listDeclinedPayments,
|
|
58
66
|
listDeliveries: () => listDeliveries,
|
|
59
67
|
listDomains: () => listDomains,
|
|
60
68
|
listEmails: () => listEmails,
|
|
@@ -63,8 +71,12 @@ var sdk_gen_exports = /* @__PURE__ */ __exportAll({
|
|
|
63
71
|
listFunctionLogs: () => listFunctionLogs,
|
|
64
72
|
listFunctionSecrets: () => listFunctionSecrets,
|
|
65
73
|
listFunctions: () => listFunctions,
|
|
74
|
+
listOrgSecrets: () => listOrgSecrets,
|
|
75
|
+
listPayoutAddresses: () => listPayoutAddresses,
|
|
66
76
|
listSentEmails: () => listSentEmails,
|
|
77
|
+
payChallenge: () => payChallenge,
|
|
67
78
|
pollCliLogin: () => pollCliLogin,
|
|
79
|
+
registerPayoutAddress: () => registerPayoutAddress,
|
|
68
80
|
replayDelivery: () => replayDelivery,
|
|
69
81
|
replayEmailWebhooks: () => replayEmailWebhooks,
|
|
70
82
|
replyToEmail: () => replyToEmail,
|
|
@@ -76,6 +88,7 @@ var sdk_gen_exports = /* @__PURE__ */ __exportAll({
|
|
|
76
88
|
sendEmail: () => sendEmail,
|
|
77
89
|
setFunctionRoute: () => setFunctionRoute,
|
|
78
90
|
setFunctionSecret: () => setFunctionSecret,
|
|
91
|
+
setOrgSecret: () => setOrgSecret,
|
|
79
92
|
startAgentClaim: () => startAgentClaim,
|
|
80
93
|
startAgentSignup: () => startAgentSignup,
|
|
81
94
|
startCliLogin: () => startCliLogin,
|
|
@@ -88,6 +101,7 @@ var sdk_gen_exports = /* @__PURE__ */ __exportAll({
|
|
|
88
101
|
updateEndpoint: () => updateEndpoint,
|
|
89
102
|
updateFilter: () => updateFilter,
|
|
90
103
|
updateFunction: () => updateFunction,
|
|
104
|
+
updateSpendPolicy: () => updateSpendPolicy,
|
|
91
105
|
verifyAgentClaim: () => verifyAgentClaim,
|
|
92
106
|
verifyAgentSignup: () => verifyAgentSignup,
|
|
93
107
|
verifyCliSignup: () => verifyCliSignup,
|
|
@@ -1517,6 +1531,85 @@ const setFunctionSecret = (options) => (options.client ?? client).put({
|
|
|
1517
1531
|
}
|
|
1518
1532
|
});
|
|
1519
1533
|
/**
|
|
1534
|
+
* List org-level (global) secrets
|
|
1535
|
+
*
|
|
1536
|
+
* Returns metadata for every org-level secret. Org secrets apply
|
|
1537
|
+
* to every function in the org and are read as `env.<KEY>` in
|
|
1538
|
+
* handlers. **Values are never returned.** Secret writes are
|
|
1539
|
+
* write-only. A function-level secret of the same name overrides
|
|
1540
|
+
* the org-level value for that function.
|
|
1541
|
+
*
|
|
1542
|
+
*/
|
|
1543
|
+
const listOrgSecrets = (options) => (options?.client ?? client).get({
|
|
1544
|
+
security: [{
|
|
1545
|
+
scheme: "bearer",
|
|
1546
|
+
type: "http"
|
|
1547
|
+
}],
|
|
1548
|
+
url: "/org/secrets",
|
|
1549
|
+
...options
|
|
1550
|
+
});
|
|
1551
|
+
/**
|
|
1552
|
+
* Create or update an org secret
|
|
1553
|
+
*
|
|
1554
|
+
* Idempotent insert-or-update keyed on `(org_id, key)`. Returns
|
|
1555
|
+
* 201 the first time the key is set, 200 on subsequent updates.
|
|
1556
|
+
* Values are encrypted at rest. A changed value lands in a
|
|
1557
|
+
* function only on that function's next deploy.
|
|
1558
|
+
*
|
|
1559
|
+
* Keys must match `^[A-Z_][A-Z0-9_]*$` (uppercase letters,
|
|
1560
|
+
* digits, underscores; first character is a letter or
|
|
1561
|
+
* underscore). Values are at most 4096 UTF-8 bytes. System-
|
|
1562
|
+
* managed keys are reserved and rejected.
|
|
1563
|
+
*
|
|
1564
|
+
*/
|
|
1565
|
+
const createOrgSecret = (options) => (options.client ?? client).post({
|
|
1566
|
+
security: [{
|
|
1567
|
+
scheme: "bearer",
|
|
1568
|
+
type: "http"
|
|
1569
|
+
}],
|
|
1570
|
+
url: "/org/secrets",
|
|
1571
|
+
...options,
|
|
1572
|
+
headers: {
|
|
1573
|
+
...options.body !== void 0 && { "Content-Type": "application/json" },
|
|
1574
|
+
...options.headers
|
|
1575
|
+
}
|
|
1576
|
+
});
|
|
1577
|
+
/**
|
|
1578
|
+
* Delete an org secret
|
|
1579
|
+
*
|
|
1580
|
+
* Removes the org secret. Functions keep the previous value until
|
|
1581
|
+
* each is redeployed. Returns 404 if the key did not exist.
|
|
1582
|
+
*
|
|
1583
|
+
*/
|
|
1584
|
+
const deleteOrgSecret = (options) => (options.client ?? client).delete({
|
|
1585
|
+
security: [{
|
|
1586
|
+
scheme: "bearer",
|
|
1587
|
+
type: "http"
|
|
1588
|
+
}],
|
|
1589
|
+
url: "/org/secrets/{key}",
|
|
1590
|
+
...options
|
|
1591
|
+
});
|
|
1592
|
+
/**
|
|
1593
|
+
* Set an org secret by key
|
|
1594
|
+
*
|
|
1595
|
+
* Path-keyed companion to `POST /org/secrets`. Idempotent:
|
|
1596
|
+
* returns 201 the first time the key is set, 200 on subsequent
|
|
1597
|
+
* updates. Same validation and write-only guarantees as POST.
|
|
1598
|
+
*
|
|
1599
|
+
*/
|
|
1600
|
+
const setOrgSecret = (options) => (options.client ?? client).put({
|
|
1601
|
+
security: [{
|
|
1602
|
+
scheme: "bearer",
|
|
1603
|
+
type: "http"
|
|
1604
|
+
}],
|
|
1605
|
+
url: "/org/secrets/{key}",
|
|
1606
|
+
...options,
|
|
1607
|
+
headers: {
|
|
1608
|
+
...options.body !== void 0 && { "Content-Type": "application/json" },
|
|
1609
|
+
...options.headers
|
|
1610
|
+
}
|
|
1611
|
+
});
|
|
1612
|
+
/**
|
|
1520
1613
|
* List a function's execution logs
|
|
1521
1614
|
*
|
|
1522
1615
|
* Returns the most recent `function_logs` rows for the function,
|
|
@@ -1538,6 +1631,165 @@ const listFunctionLogs = (options) => (options.client ?? client).get({
|
|
|
1538
1631
|
url: "/functions/{id}/logs",
|
|
1539
1632
|
...options
|
|
1540
1633
|
});
|
|
1634
|
+
/**
|
|
1635
|
+
* List payout addresses
|
|
1636
|
+
*
|
|
1637
|
+
* List your org's registered payout addresses, newest first.
|
|
1638
|
+
*/
|
|
1639
|
+
const listPayoutAddresses = (options) => (options?.client ?? client).get({
|
|
1640
|
+
security: [{
|
|
1641
|
+
scheme: "bearer",
|
|
1642
|
+
type: "http"
|
|
1643
|
+
}],
|
|
1644
|
+
url: "/x402/payout-addresses",
|
|
1645
|
+
...options
|
|
1646
|
+
});
|
|
1647
|
+
/**
|
|
1648
|
+
* Register a payout address
|
|
1649
|
+
*
|
|
1650
|
+
* Register (or update) the default payout address your org receives x402
|
|
1651
|
+
* payments at, for a given network. You prove control of the address with
|
|
1652
|
+
* an org-bound `personal_sign` signature over the message produced by the
|
|
1653
|
+
* SDK helper `buildPayoutRegistrationMessage`. The org id is taken from your
|
|
1654
|
+
* authenticated key, never the body, so a captured signature can't register
|
|
1655
|
+
* an address under another org. Exactly one default address exists per
|
|
1656
|
+
* (org, network); registering again replaces it. A payee MUST register a
|
|
1657
|
+
* payout address before calling `createChallenge`, because the challenge's
|
|
1658
|
+
* `pay_to` is resolved from this directory.
|
|
1659
|
+
*
|
|
1660
|
+
*/
|
|
1661
|
+
const registerPayoutAddress = (options) => (options.client ?? client).post({
|
|
1662
|
+
security: [{
|
|
1663
|
+
scheme: "bearer",
|
|
1664
|
+
type: "http"
|
|
1665
|
+
}],
|
|
1666
|
+
url: "/x402/payout-addresses",
|
|
1667
|
+
...options,
|
|
1668
|
+
headers: {
|
|
1669
|
+
...options.body !== void 0 && { "Content-Type": "application/json" },
|
|
1670
|
+
...options.headers
|
|
1671
|
+
}
|
|
1672
|
+
});
|
|
1673
|
+
/**
|
|
1674
|
+
* Create a payment challenge
|
|
1675
|
+
*
|
|
1676
|
+
* Create an x402 payment challenge (the payee side of a payment). The
|
|
1677
|
+
* `pay_to` address is resolved server-side from your registered default
|
|
1678
|
+
* payout address for the network, never from the request. The response
|
|
1679
|
+
* carries the `nonce_binding` and `payment_requirements` the payer needs to
|
|
1680
|
+
* sign; hand the whole challenge object to the payer (for example in an
|
|
1681
|
+
* email reply). Amounts are in token base units (USDC has 6 decimals, so
|
|
1682
|
+
* `"10000"` is 0.01 USDC).
|
|
1683
|
+
*
|
|
1684
|
+
*/
|
|
1685
|
+
const createChallenge = (options) => (options.client ?? client).post({
|
|
1686
|
+
security: [{
|
|
1687
|
+
scheme: "bearer",
|
|
1688
|
+
type: "http"
|
|
1689
|
+
}],
|
|
1690
|
+
url: "/x402/challenges",
|
|
1691
|
+
...options,
|
|
1692
|
+
headers: {
|
|
1693
|
+
...options.body !== void 0 && { "Content-Type": "application/json" },
|
|
1694
|
+
...options.headers
|
|
1695
|
+
}
|
|
1696
|
+
});
|
|
1697
|
+
/**
|
|
1698
|
+
* Get a payment challenge
|
|
1699
|
+
*
|
|
1700
|
+
* Fetch a challenge you created, to poll its `status` and settlement
|
|
1701
|
+
* receipt (`settle_tx`). Scoped to the challenger org that created it.
|
|
1702
|
+
*
|
|
1703
|
+
*/
|
|
1704
|
+
const getChallenge = (options) => (options.client ?? client).get({
|
|
1705
|
+
security: [{
|
|
1706
|
+
scheme: "bearer",
|
|
1707
|
+
type: "http"
|
|
1708
|
+
}],
|
|
1709
|
+
url: "/x402/challenges/{id}",
|
|
1710
|
+
...options
|
|
1711
|
+
});
|
|
1712
|
+
/**
|
|
1713
|
+
* Pay a payment challenge
|
|
1714
|
+
*
|
|
1715
|
+
* Settle a challenge addressed to your org as payer. The request body
|
|
1716
|
+
* carries a signed x402 `PaymentPayload`: an EIP-3009
|
|
1717
|
+
* `transferWithAuthorization` signed locally with your own key, whose nonce
|
|
1718
|
+
* is bound to the challenge via the SDK's `deriveEip3009Nonce`. The platform
|
|
1719
|
+
* verifies every signed field against its own record of the challenge,
|
|
1720
|
+
* applies your spend policy, and settles on-chain through a facilitator.
|
|
1721
|
+
* Settlement is non-custodial; Primitive never holds funds. Idempotent:
|
|
1722
|
+
* paying an already-settled challenge returns the original receipt. Most
|
|
1723
|
+
* callers use the SDK `pay()` helper rather than building the payload by
|
|
1724
|
+
* hand.
|
|
1725
|
+
*
|
|
1726
|
+
*/
|
|
1727
|
+
const payChallenge = (options) => (options.client ?? client).post({
|
|
1728
|
+
security: [{
|
|
1729
|
+
scheme: "bearer",
|
|
1730
|
+
type: "http"
|
|
1731
|
+
}],
|
|
1732
|
+
url: "/x402/challenges/{id}/pay",
|
|
1733
|
+
...options,
|
|
1734
|
+
headers: {
|
|
1735
|
+
...options.body !== void 0 && { "Content-Type": "application/json" },
|
|
1736
|
+
...options.headers
|
|
1737
|
+
}
|
|
1738
|
+
});
|
|
1739
|
+
/**
|
|
1740
|
+
* Get your spend policy
|
|
1741
|
+
*
|
|
1742
|
+
* Read your org's outbound spend policy: the kill-switch, per-payment and
|
|
1743
|
+
* per-day caps, and the payee allowlist. Returns the defaults (no limits,
|
|
1744
|
+
* not paused) when no policy has been set.
|
|
1745
|
+
*
|
|
1746
|
+
*/
|
|
1747
|
+
const getSpendPolicy = (options) => (options?.client ?? client).get({
|
|
1748
|
+
security: [{
|
|
1749
|
+
scheme: "bearer",
|
|
1750
|
+
type: "http"
|
|
1751
|
+
}],
|
|
1752
|
+
url: "/x402/spend-policy",
|
|
1753
|
+
...options
|
|
1754
|
+
});
|
|
1755
|
+
/**
|
|
1756
|
+
* Update your spend policy
|
|
1757
|
+
*
|
|
1758
|
+
* Update your org's spend policy. Applied as a merge: only the fields you
|
|
1759
|
+
* include change, and omitted fields keep their current value, so a partial
|
|
1760
|
+
* update can't silently reset the kill-switch. Send an explicit `null` to
|
|
1761
|
+
* clear a cap. Caps are in token base units.
|
|
1762
|
+
*
|
|
1763
|
+
*/
|
|
1764
|
+
const updateSpendPolicy = (options) => (options.client ?? client).put({
|
|
1765
|
+
security: [{
|
|
1766
|
+
scheme: "bearer",
|
|
1767
|
+
type: "http"
|
|
1768
|
+
}],
|
|
1769
|
+
url: "/x402/spend-policy",
|
|
1770
|
+
...options,
|
|
1771
|
+
headers: {
|
|
1772
|
+
...options.body !== void 0 && { "Content-Type": "application/json" },
|
|
1773
|
+
...options.headers
|
|
1774
|
+
}
|
|
1775
|
+
});
|
|
1776
|
+
/**
|
|
1777
|
+
* List declined payments
|
|
1778
|
+
*
|
|
1779
|
+
* The 50 most recent payments your org's spend policy declined, newest
|
|
1780
|
+
* first. Use this to see why an outbound payment was refused (a cap, the
|
|
1781
|
+
* payee allowlist, or the kill-switch) instead of only reading the
|
|
1782
|
+
* dashboard.
|
|
1783
|
+
*
|
|
1784
|
+
*/
|
|
1785
|
+
const listDeclinedPayments = (options) => (options?.client ?? client).get({
|
|
1786
|
+
security: [{
|
|
1787
|
+
scheme: "bearer",
|
|
1788
|
+
type: "http"
|
|
1789
|
+
}],
|
|
1790
|
+
url: "/x402/declined-payments",
|
|
1791
|
+
...options
|
|
1792
|
+
});
|
|
1541
1793
|
//#endregion
|
|
1542
1794
|
//#region ../packages/api-core/src/openapi/openapi.generated.ts
|
|
1543
1795
|
/**
|
|
@@ -1614,6 +1866,10 @@ const openapiDocument = {
|
|
|
1614
1866
|
"name": "Filters",
|
|
1615
1867
|
"description": "Manage whitelist and blocklist filter rules"
|
|
1616
1868
|
},
|
|
1869
|
+
{
|
|
1870
|
+
"name": "Payments",
|
|
1871
|
+
"description": "Collect and pay stablecoin (USDC) payments with x402. Settlement is\nnon-custodial: funds move directly from payer to payee on-chain via an\nEIP-3009 authorization the payer signs with their own key, and Primitive\nnever holds funds. The payee registers a payout address and creates a\nchallenge; the payer signs and settles it under a configurable spend\npolicy (kill-switch, per-payment and per-day caps, payee allowlist).\n"
|
|
1872
|
+
},
|
|
1617
1873
|
{
|
|
1618
1874
|
"name": "Webhook Deliveries",
|
|
1619
1875
|
"description": "View and replay webhook delivery attempts"
|
|
@@ -3709,6 +3965,111 @@ const openapiDocument = {
|
|
|
3709
3965
|
}
|
|
3710
3966
|
}
|
|
3711
3967
|
},
|
|
3968
|
+
"/org/secrets": {
|
|
3969
|
+
"get": {
|
|
3970
|
+
"operationId": "listOrgSecrets",
|
|
3971
|
+
"summary": "List org-level (global) secrets",
|
|
3972
|
+
"description": "Returns metadata for every org-level secret. Org secrets apply\nto every function in the org and are read as `env.<KEY>` in\nhandlers. **Values are never returned.** Secret writes are\nwrite-only. A function-level secret of the same name overrides\nthe org-level value for that function.\n",
|
|
3973
|
+
"tags": ["Functions"],
|
|
3974
|
+
"responses": {
|
|
3975
|
+
"200": {
|
|
3976
|
+
"description": "List of org secrets (metadata only, no values)",
|
|
3977
|
+
"content": { "application/json": { "schema": { "allOf": [{ "$ref": "#/components/schemas/SuccessEnvelope" }, {
|
|
3978
|
+
"type": "object",
|
|
3979
|
+
"properties": { "data": {
|
|
3980
|
+
"type": "object",
|
|
3981
|
+
"properties": { "items": {
|
|
3982
|
+
"type": "array",
|
|
3983
|
+
"items": { "$ref": "#/components/schemas/OrgSecretListItem" }
|
|
3984
|
+
} },
|
|
3985
|
+
"required": ["items"]
|
|
3986
|
+
} }
|
|
3987
|
+
}] } } }
|
|
3988
|
+
},
|
|
3989
|
+
"401": { "$ref": "#/components/responses/Unauthorized" }
|
|
3990
|
+
}
|
|
3991
|
+
},
|
|
3992
|
+
"post": {
|
|
3993
|
+
"operationId": "createOrgSecret",
|
|
3994
|
+
"summary": "Create or update an org secret",
|
|
3995
|
+
"description": "Idempotent insert-or-update keyed on `(org_id, key)`. Returns\n201 the first time the key is set, 200 on subsequent updates.\nValues are encrypted at rest. A changed value lands in a\nfunction only on that function's next deploy.\n\nKeys must match `^[A-Z_][A-Z0-9_]*$` (uppercase letters,\ndigits, underscores; first character is a letter or\nunderscore). Values are at most 4096 UTF-8 bytes. System-\nmanaged keys are reserved and rejected.\n",
|
|
3996
|
+
"tags": ["Functions"],
|
|
3997
|
+
"requestBody": {
|
|
3998
|
+
"required": true,
|
|
3999
|
+
"content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateOrgSecretInput" } } }
|
|
4000
|
+
},
|
|
4001
|
+
"responses": {
|
|
4002
|
+
"200": {
|
|
4003
|
+
"description": "Secret updated",
|
|
4004
|
+
"content": { "application/json": { "schema": { "allOf": [{ "$ref": "#/components/schemas/SuccessEnvelope" }, {
|
|
4005
|
+
"type": "object",
|
|
4006
|
+
"properties": { "data": { "$ref": "#/components/schemas/OrgSecretWriteResult" } }
|
|
4007
|
+
}] } } }
|
|
4008
|
+
},
|
|
4009
|
+
"201": {
|
|
4010
|
+
"description": "Secret created",
|
|
4011
|
+
"content": { "application/json": { "schema": { "allOf": [{ "$ref": "#/components/schemas/SuccessEnvelope" }, {
|
|
4012
|
+
"type": "object",
|
|
4013
|
+
"properties": { "data": { "$ref": "#/components/schemas/OrgSecretWriteResult" } }
|
|
4014
|
+
}] } } }
|
|
4015
|
+
},
|
|
4016
|
+
"400": { "$ref": "#/components/responses/ValidationError" },
|
|
4017
|
+
"401": { "$ref": "#/components/responses/Unauthorized" }
|
|
4018
|
+
}
|
|
4019
|
+
}
|
|
4020
|
+
},
|
|
4021
|
+
"/org/secrets/{key}": {
|
|
4022
|
+
"parameters": [{
|
|
4023
|
+
"name": "key",
|
|
4024
|
+
"in": "path",
|
|
4025
|
+
"required": true,
|
|
4026
|
+
"description": "Secret key. Must match `^[A-Z_][A-Z0-9_]*$`.",
|
|
4027
|
+
"schema": {
|
|
4028
|
+
"type": "string",
|
|
4029
|
+
"pattern": "^[A-Z_][A-Z0-9_]*$"
|
|
4030
|
+
}
|
|
4031
|
+
}],
|
|
4032
|
+
"put": {
|
|
4033
|
+
"operationId": "setOrgSecret",
|
|
4034
|
+
"summary": "Set an org secret by key",
|
|
4035
|
+
"description": "Path-keyed companion to `POST /org/secrets`. Idempotent:\nreturns 201 the first time the key is set, 200 on subsequent\nupdates. Same validation and write-only guarantees as POST.\n",
|
|
4036
|
+
"tags": ["Functions"],
|
|
4037
|
+
"requestBody": {
|
|
4038
|
+
"required": true,
|
|
4039
|
+
"content": { "application/json": { "schema": { "$ref": "#/components/schemas/SetOrgSecretInput" } } }
|
|
4040
|
+
},
|
|
4041
|
+
"responses": {
|
|
4042
|
+
"200": {
|
|
4043
|
+
"description": "Secret updated",
|
|
4044
|
+
"content": { "application/json": { "schema": { "allOf": [{ "$ref": "#/components/schemas/SuccessEnvelope" }, {
|
|
4045
|
+
"type": "object",
|
|
4046
|
+
"properties": { "data": { "$ref": "#/components/schemas/OrgSecretWriteResult" } }
|
|
4047
|
+
}] } } }
|
|
4048
|
+
},
|
|
4049
|
+
"201": {
|
|
4050
|
+
"description": "Secret created",
|
|
4051
|
+
"content": { "application/json": { "schema": { "allOf": [{ "$ref": "#/components/schemas/SuccessEnvelope" }, {
|
|
4052
|
+
"type": "object",
|
|
4053
|
+
"properties": { "data": { "$ref": "#/components/schemas/OrgSecretWriteResult" } }
|
|
4054
|
+
}] } } }
|
|
4055
|
+
},
|
|
4056
|
+
"400": { "$ref": "#/components/responses/ValidationError" },
|
|
4057
|
+
"401": { "$ref": "#/components/responses/Unauthorized" }
|
|
4058
|
+
}
|
|
4059
|
+
},
|
|
4060
|
+
"delete": {
|
|
4061
|
+
"operationId": "deleteOrgSecret",
|
|
4062
|
+
"summary": "Delete an org secret",
|
|
4063
|
+
"description": "Removes the org secret. Functions keep the previous value until\neach is redeployed. Returns 404 if the key did not exist.\n",
|
|
4064
|
+
"tags": ["Functions"],
|
|
4065
|
+
"responses": {
|
|
4066
|
+
"204": { "description": "Secret deleted" },
|
|
4067
|
+
"400": { "$ref": "#/components/responses/ValidationError" },
|
|
4068
|
+
"401": { "$ref": "#/components/responses/Unauthorized" },
|
|
4069
|
+
"404": { "$ref": "#/components/responses/NotFound" }
|
|
4070
|
+
}
|
|
4071
|
+
}
|
|
4072
|
+
},
|
|
3712
4073
|
"/functions/{id}/logs": {
|
|
3713
4074
|
"parameters": [{ "$ref": "#/components/parameters/ResourceId" }],
|
|
3714
4075
|
"get": {
|
|
@@ -3761,30 +4122,222 @@ const openapiDocument = {
|
|
|
3761
4122
|
"404": { "$ref": "#/components/responses/NotFound" }
|
|
3762
4123
|
}
|
|
3763
4124
|
}
|
|
3764
|
-
}
|
|
3765
|
-
},
|
|
3766
|
-
"components": {
|
|
3767
|
-
"securitySchemes": {
|
|
3768
|
-
"BearerAuth": {
|
|
3769
|
-
"type": "http",
|
|
3770
|
-
"scheme": "bearer",
|
|
3771
|
-
"description": "API key with `prim_` prefix: `Authorization: Bearer prim_<key>`"
|
|
3772
|
-
},
|
|
3773
|
-
"DownloadToken": {
|
|
3774
|
-
"type": "apiKey",
|
|
3775
|
-
"in": "query",
|
|
3776
|
-
"name": "token",
|
|
3777
|
-
"description": "Signed download token provided in webhook payloads"
|
|
3778
|
-
}
|
|
3779
4125
|
},
|
|
3780
|
-
"
|
|
3781
|
-
"
|
|
3782
|
-
"
|
|
3783
|
-
"
|
|
3784
|
-
"
|
|
3785
|
-
"
|
|
3786
|
-
|
|
3787
|
-
|
|
4126
|
+
"/x402/payout-addresses": {
|
|
4127
|
+
"post": {
|
|
4128
|
+
"operationId": "registerPayoutAddress",
|
|
4129
|
+
"summary": "Register a payout address",
|
|
4130
|
+
"description": "Register (or update) the default payout address your org receives x402\npayments at, for a given network. You prove control of the address with\nan org-bound `personal_sign` signature over the message produced by the\nSDK helper `buildPayoutRegistrationMessage`. The org id is taken from your\nauthenticated key, never the body, so a captured signature can't register\nan address under another org. Exactly one default address exists per\n(org, network); registering again replaces it. A payee MUST register a\npayout address before calling `createChallenge`, because the challenge's\n`pay_to` is resolved from this directory.\n",
|
|
4131
|
+
"tags": ["Payments"],
|
|
4132
|
+
"security": [{ "BearerAuth": [] }],
|
|
4133
|
+
"requestBody": {
|
|
4134
|
+
"required": true,
|
|
4135
|
+
"content": { "application/json": { "schema": { "$ref": "#/components/schemas/RegisterPayoutAddressInput" } } }
|
|
4136
|
+
},
|
|
4137
|
+
"responses": {
|
|
4138
|
+
"201": {
|
|
4139
|
+
"description": "Payout address registered (or updated) and set as default",
|
|
4140
|
+
"content": { "application/json": { "schema": { "allOf": [{ "$ref": "#/components/schemas/SuccessEnvelope" }, {
|
|
4141
|
+
"type": "object",
|
|
4142
|
+
"properties": { "data": { "$ref": "#/components/schemas/X402PayoutAddress" } }
|
|
4143
|
+
}] } } }
|
|
4144
|
+
},
|
|
4145
|
+
"400": { "$ref": "#/components/responses/ValidationError" },
|
|
4146
|
+
"401": { "$ref": "#/components/responses/Unauthorized" },
|
|
4147
|
+
"403": { "$ref": "#/components/responses/Forbidden" },
|
|
4148
|
+
"422": { "$ref": "#/components/responses/UnprocessableEntity" },
|
|
4149
|
+
"429": { "$ref": "#/components/responses/RateLimited" }
|
|
4150
|
+
}
|
|
4151
|
+
},
|
|
4152
|
+
"get": {
|
|
4153
|
+
"operationId": "listPayoutAddresses",
|
|
4154
|
+
"summary": "List payout addresses",
|
|
4155
|
+
"description": "List your org's registered payout addresses, newest first.",
|
|
4156
|
+
"tags": ["Payments"],
|
|
4157
|
+
"security": [{ "BearerAuth": [] }],
|
|
4158
|
+
"responses": {
|
|
4159
|
+
"200": {
|
|
4160
|
+
"description": "Your registered payout addresses",
|
|
4161
|
+
"content": { "application/json": { "schema": { "allOf": [{ "$ref": "#/components/schemas/SuccessEnvelope" }, {
|
|
4162
|
+
"type": "object",
|
|
4163
|
+
"properties": { "data": {
|
|
4164
|
+
"type": "array",
|
|
4165
|
+
"items": { "$ref": "#/components/schemas/X402PayoutAddress" }
|
|
4166
|
+
} }
|
|
4167
|
+
}] } } }
|
|
4168
|
+
},
|
|
4169
|
+
"401": { "$ref": "#/components/responses/Unauthorized" },
|
|
4170
|
+
"403": { "$ref": "#/components/responses/Forbidden" },
|
|
4171
|
+
"429": { "$ref": "#/components/responses/RateLimited" }
|
|
4172
|
+
}
|
|
4173
|
+
}
|
|
4174
|
+
},
|
|
4175
|
+
"/x402/challenges": { "post": {
|
|
4176
|
+
"operationId": "createChallenge",
|
|
4177
|
+
"summary": "Create a payment challenge",
|
|
4178
|
+
"description": "Create an x402 payment challenge (the payee side of a payment). The\n`pay_to` address is resolved server-side from your registered default\npayout address for the network, never from the request. The response\ncarries the `nonce_binding` and `payment_requirements` the payer needs to\nsign; hand the whole challenge object to the payer (for example in an\nemail reply). Amounts are in token base units (USDC has 6 decimals, so\n`\"10000\"` is 0.01 USDC).\n",
|
|
4179
|
+
"tags": ["Payments"],
|
|
4180
|
+
"security": [{ "BearerAuth": [] }],
|
|
4181
|
+
"requestBody": {
|
|
4182
|
+
"required": true,
|
|
4183
|
+
"content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateChallengeInput" } } }
|
|
4184
|
+
},
|
|
4185
|
+
"responses": {
|
|
4186
|
+
"201": {
|
|
4187
|
+
"description": "Challenge created",
|
|
4188
|
+
"content": { "application/json": { "schema": { "allOf": [{ "$ref": "#/components/schemas/SuccessEnvelope" }, {
|
|
4189
|
+
"type": "object",
|
|
4190
|
+
"properties": { "data": { "$ref": "#/components/schemas/X402Challenge" } }
|
|
4191
|
+
}] } } }
|
|
4192
|
+
},
|
|
4193
|
+
"400": { "$ref": "#/components/responses/ValidationError" },
|
|
4194
|
+
"401": { "$ref": "#/components/responses/Unauthorized" },
|
|
4195
|
+
"403": { "$ref": "#/components/responses/Forbidden" },
|
|
4196
|
+
"422": { "$ref": "#/components/responses/UnprocessableEntity" },
|
|
4197
|
+
"429": { "$ref": "#/components/responses/RateLimited" }
|
|
4198
|
+
}
|
|
4199
|
+
} },
|
|
4200
|
+
"/x402/challenges/{id}": { "get": {
|
|
4201
|
+
"operationId": "getChallenge",
|
|
4202
|
+
"summary": "Get a payment challenge",
|
|
4203
|
+
"description": "Fetch a challenge you created, to poll its `status` and settlement\nreceipt (`settle_tx`). Scoped to the challenger org that created it.\n",
|
|
4204
|
+
"tags": ["Payments"],
|
|
4205
|
+
"security": [{ "BearerAuth": [] }],
|
|
4206
|
+
"parameters": [{ "$ref": "#/components/parameters/ResourceId" }],
|
|
4207
|
+
"responses": {
|
|
4208
|
+
"200": {
|
|
4209
|
+
"description": "The challenge",
|
|
4210
|
+
"content": { "application/json": { "schema": { "allOf": [{ "$ref": "#/components/schemas/SuccessEnvelope" }, {
|
|
4211
|
+
"type": "object",
|
|
4212
|
+
"properties": { "data": { "$ref": "#/components/schemas/X402Challenge" } }
|
|
4213
|
+
}] } } }
|
|
4214
|
+
},
|
|
4215
|
+
"400": { "$ref": "#/components/responses/ValidationError" },
|
|
4216
|
+
"401": { "$ref": "#/components/responses/Unauthorized" },
|
|
4217
|
+
"403": { "$ref": "#/components/responses/Forbidden" },
|
|
4218
|
+
"404": { "$ref": "#/components/responses/NotFound" },
|
|
4219
|
+
"429": { "$ref": "#/components/responses/RateLimited" }
|
|
4220
|
+
}
|
|
4221
|
+
} },
|
|
4222
|
+
"/x402/challenges/{id}/pay": { "post": {
|
|
4223
|
+
"operationId": "payChallenge",
|
|
4224
|
+
"summary": "Pay a payment challenge",
|
|
4225
|
+
"description": "Settle a challenge addressed to your org as payer. The request body\ncarries a signed x402 `PaymentPayload`: an EIP-3009\n`transferWithAuthorization` signed locally with your own key, whose nonce\nis bound to the challenge via the SDK's `deriveEip3009Nonce`. The platform\nverifies every signed field against its own record of the challenge,\napplies your spend policy, and settles on-chain through a facilitator.\nSettlement is non-custodial; Primitive never holds funds. Idempotent:\npaying an already-settled challenge returns the original receipt. Most\ncallers use the SDK `pay()` helper rather than building the payload by\nhand.\n",
|
|
4226
|
+
"tags": ["Payments"],
|
|
4227
|
+
"security": [{ "BearerAuth": [] }],
|
|
4228
|
+
"parameters": [{ "$ref": "#/components/parameters/ResourceId" }],
|
|
4229
|
+
"requestBody": {
|
|
4230
|
+
"required": true,
|
|
4231
|
+
"content": { "application/json": { "schema": { "$ref": "#/components/schemas/PayChallengeInput" } } }
|
|
4232
|
+
},
|
|
4233
|
+
"responses": {
|
|
4234
|
+
"200": {
|
|
4235
|
+
"description": "Challenge settled (or already settled)",
|
|
4236
|
+
"content": { "application/json": { "schema": { "allOf": [{ "$ref": "#/components/schemas/SuccessEnvelope" }, {
|
|
4237
|
+
"type": "object",
|
|
4238
|
+
"properties": { "data": { "$ref": "#/components/schemas/X402Receipt" } }
|
|
4239
|
+
}] } } }
|
|
4240
|
+
},
|
|
4241
|
+
"400": { "$ref": "#/components/responses/ValidationError" },
|
|
4242
|
+
"401": { "$ref": "#/components/responses/Unauthorized" },
|
|
4243
|
+
"403": { "$ref": "#/components/responses/Forbidden" },
|
|
4244
|
+
"404": { "$ref": "#/components/responses/NotFound" },
|
|
4245
|
+
"409": { "$ref": "#/components/responses/Conflict" },
|
|
4246
|
+
"422": { "$ref": "#/components/responses/UnprocessableEntity" },
|
|
4247
|
+
"429": { "$ref": "#/components/responses/RateLimited" },
|
|
4248
|
+
"502": { "$ref": "#/components/responses/BadGateway" }
|
|
4249
|
+
}
|
|
4250
|
+
} },
|
|
4251
|
+
"/x402/spend-policy": {
|
|
4252
|
+
"get": {
|
|
4253
|
+
"operationId": "getSpendPolicy",
|
|
4254
|
+
"summary": "Get your spend policy",
|
|
4255
|
+
"description": "Read your org's outbound spend policy: the kill-switch, per-payment and\nper-day caps, and the payee allowlist. Returns the defaults (no limits,\nnot paused) when no policy has been set.\n",
|
|
4256
|
+
"tags": ["Payments"],
|
|
4257
|
+
"security": [{ "BearerAuth": [] }],
|
|
4258
|
+
"responses": {
|
|
4259
|
+
"200": {
|
|
4260
|
+
"description": "The spend policy",
|
|
4261
|
+
"content": { "application/json": { "schema": { "allOf": [{ "$ref": "#/components/schemas/SuccessEnvelope" }, {
|
|
4262
|
+
"type": "object",
|
|
4263
|
+
"properties": { "data": { "$ref": "#/components/schemas/X402SpendPolicy" } }
|
|
4264
|
+
}] } } }
|
|
4265
|
+
},
|
|
4266
|
+
"401": { "$ref": "#/components/responses/Unauthorized" },
|
|
4267
|
+
"403": { "$ref": "#/components/responses/Forbidden" },
|
|
4268
|
+
"429": { "$ref": "#/components/responses/RateLimited" }
|
|
4269
|
+
}
|
|
4270
|
+
},
|
|
4271
|
+
"put": {
|
|
4272
|
+
"operationId": "updateSpendPolicy",
|
|
4273
|
+
"summary": "Update your spend policy",
|
|
4274
|
+
"description": "Update your org's spend policy. Applied as a merge: only the fields you\ninclude change, and omitted fields keep their current value, so a partial\nupdate can't silently reset the kill-switch. Send an explicit `null` to\nclear a cap. Caps are in token base units.\n",
|
|
4275
|
+
"tags": ["Payments"],
|
|
4276
|
+
"security": [{ "BearerAuth": [] }],
|
|
4277
|
+
"requestBody": {
|
|
4278
|
+
"required": true,
|
|
4279
|
+
"content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateSpendPolicyInput" } } }
|
|
4280
|
+
},
|
|
4281
|
+
"responses": {
|
|
4282
|
+
"200": {
|
|
4283
|
+
"description": "The updated spend policy",
|
|
4284
|
+
"content": { "application/json": { "schema": { "allOf": [{ "$ref": "#/components/schemas/SuccessEnvelope" }, {
|
|
4285
|
+
"type": "object",
|
|
4286
|
+
"properties": { "data": { "$ref": "#/components/schemas/X402SpendPolicy" } }
|
|
4287
|
+
}] } } }
|
|
4288
|
+
},
|
|
4289
|
+
"400": { "$ref": "#/components/responses/ValidationError" },
|
|
4290
|
+
"401": { "$ref": "#/components/responses/Unauthorized" },
|
|
4291
|
+
"403": { "$ref": "#/components/responses/Forbidden" },
|
|
4292
|
+
"429": { "$ref": "#/components/responses/RateLimited" }
|
|
4293
|
+
}
|
|
4294
|
+
}
|
|
4295
|
+
},
|
|
4296
|
+
"/x402/declined-payments": { "get": {
|
|
4297
|
+
"operationId": "listDeclinedPayments",
|
|
4298
|
+
"summary": "List declined payments",
|
|
4299
|
+
"description": "The 50 most recent payments your org's spend policy declined, newest\nfirst. Use this to see why an outbound payment was refused (a cap, the\npayee allowlist, or the kill-switch) instead of only reading the\ndashboard.\n",
|
|
4300
|
+
"tags": ["Payments"],
|
|
4301
|
+
"security": [{ "BearerAuth": [] }],
|
|
4302
|
+
"responses": {
|
|
4303
|
+
"200": {
|
|
4304
|
+
"description": "Recently declined payments",
|
|
4305
|
+
"content": { "application/json": { "schema": { "allOf": [{ "$ref": "#/components/schemas/SuccessEnvelope" }, {
|
|
4306
|
+
"type": "object",
|
|
4307
|
+
"properties": { "data": {
|
|
4308
|
+
"type": "array",
|
|
4309
|
+
"items": { "$ref": "#/components/schemas/X402DeclinedPayment" }
|
|
4310
|
+
} }
|
|
4311
|
+
}] } } }
|
|
4312
|
+
},
|
|
4313
|
+
"401": { "$ref": "#/components/responses/Unauthorized" },
|
|
4314
|
+
"403": { "$ref": "#/components/responses/Forbidden" },
|
|
4315
|
+
"429": { "$ref": "#/components/responses/RateLimited" }
|
|
4316
|
+
}
|
|
4317
|
+
} }
|
|
4318
|
+
},
|
|
4319
|
+
"components": {
|
|
4320
|
+
"securitySchemes": {
|
|
4321
|
+
"BearerAuth": {
|
|
4322
|
+
"type": "http",
|
|
4323
|
+
"scheme": "bearer",
|
|
4324
|
+
"description": "API key with `prim_` prefix: `Authorization: Bearer prim_<key>`"
|
|
4325
|
+
},
|
|
4326
|
+
"DownloadToken": {
|
|
4327
|
+
"type": "apiKey",
|
|
4328
|
+
"in": "query",
|
|
4329
|
+
"name": "token",
|
|
4330
|
+
"description": "Signed download token provided in webhook payloads"
|
|
4331
|
+
}
|
|
4332
|
+
},
|
|
4333
|
+
"parameters": {
|
|
4334
|
+
"ResourceId": {
|
|
4335
|
+
"name": "id",
|
|
4336
|
+
"in": "path",
|
|
4337
|
+
"required": true,
|
|
4338
|
+
"schema": {
|
|
4339
|
+
"type": "string",
|
|
4340
|
+
"format": "uuid"
|
|
3788
4341
|
},
|
|
3789
4342
|
"description": "Resource UUID"
|
|
3790
4343
|
},
|
|
@@ -3928,6 +4481,32 @@ const openapiDocument = {
|
|
|
3928
4481
|
}
|
|
3929
4482
|
} }
|
|
3930
4483
|
},
|
|
4484
|
+
"Conflict": {
|
|
4485
|
+
"description": "The request conflicts with the current state of the resource",
|
|
4486
|
+
"content": { "application/json": {
|
|
4487
|
+
"schema": { "$ref": "#/components/schemas/ErrorResponse" },
|
|
4488
|
+
"example": {
|
|
4489
|
+
"success": false,
|
|
4490
|
+
"error": {
|
|
4491
|
+
"code": "conflict",
|
|
4492
|
+
"message": "settlement already in progress"
|
|
4493
|
+
}
|
|
4494
|
+
}
|
|
4495
|
+
} }
|
|
4496
|
+
},
|
|
4497
|
+
"UnprocessableEntity": {
|
|
4498
|
+
"description": "The request was well-formed but could not be processed. For Payments\nthis covers a missing payout address, a failed payment verification, a\nspend-policy decline, or an expired challenge; `error.code` distinguishes\nthem.\n",
|
|
4499
|
+
"content": { "application/json": {
|
|
4500
|
+
"schema": { "$ref": "#/components/schemas/ErrorResponse" },
|
|
4501
|
+
"example": {
|
|
4502
|
+
"success": false,
|
|
4503
|
+
"error": {
|
|
4504
|
+
"code": "payment_declined",
|
|
4505
|
+
"message": "payment exceeds the per-payment cap"
|
|
4506
|
+
}
|
|
4507
|
+
}
|
|
4508
|
+
} }
|
|
4509
|
+
},
|
|
3931
4510
|
"Deleted": {
|
|
3932
4511
|
"description": "Resource deleted",
|
|
3933
4512
|
"content": { "application/json": { "schema": { "allOf": [{ "$ref": "#/components/schemas/SuccessEnvelope" }, {
|
|
@@ -3944,60 +4523,500 @@ const openapiDocument = {
|
|
|
3944
4523
|
}
|
|
3945
4524
|
},
|
|
3946
4525
|
"schemas": {
|
|
3947
|
-
"
|
|
4526
|
+
"RegisterPayoutAddressInput": {
|
|
3948
4527
|
"type": "object",
|
|
3949
|
-
"
|
|
3950
|
-
|
|
3951
|
-
"
|
|
3952
|
-
|
|
3953
|
-
|
|
4528
|
+
"additionalProperties": false,
|
|
4529
|
+
"properties": {
|
|
4530
|
+
"address": {
|
|
4531
|
+
"type": "string",
|
|
4532
|
+
"pattern": "^0x[0-9a-fA-F]{40}$",
|
|
4533
|
+
"description": "The payout address (your signer's own EVM address), 0x-prefixed."
|
|
4534
|
+
},
|
|
4535
|
+
"network": {
|
|
4536
|
+
"type": "string",
|
|
4537
|
+
"enum": ["base", "base-sepolia"],
|
|
4538
|
+
"description": "The chain the address receives on."
|
|
4539
|
+
},
|
|
4540
|
+
"signature": {
|
|
4541
|
+
"type": "string",
|
|
4542
|
+
"pattern": "^0x[0-9a-fA-F]+$",
|
|
4543
|
+
"description": "A `personal_sign` signature over the org-bound message produced by\nthe SDK helper `buildPayoutRegistrationMessage`. Recovered and\nchecked against `address`; the org id is bound into the signed bytes.\n"
|
|
4544
|
+
},
|
|
4545
|
+
"issued_at": {
|
|
4546
|
+
"type": "string",
|
|
4547
|
+
"format": "date-time",
|
|
4548
|
+
"description": "ISO-8601 timestamp embedded in the signed message. Must be within a\nshort freshness window (about 10 minutes) of server time.\n"
|
|
4549
|
+
},
|
|
4550
|
+
"label": {
|
|
4551
|
+
"type": "string",
|
|
4552
|
+
"maxLength": 80,
|
|
4553
|
+
"description": "Optional human-readable label."
|
|
4554
|
+
}
|
|
4555
|
+
},
|
|
4556
|
+
"required": [
|
|
4557
|
+
"address",
|
|
4558
|
+
"network",
|
|
4559
|
+
"signature",
|
|
4560
|
+
"issued_at"
|
|
4561
|
+
]
|
|
3954
4562
|
},
|
|
3955
|
-
"
|
|
4563
|
+
"X402PayoutAddress": {
|
|
3956
4564
|
"type": "object",
|
|
3957
4565
|
"properties": {
|
|
3958
|
-
"
|
|
4566
|
+
"id": {
|
|
4567
|
+
"type": "string",
|
|
4568
|
+
"format": "uuid"
|
|
4569
|
+
},
|
|
4570
|
+
"address": {
|
|
4571
|
+
"type": "string",
|
|
4572
|
+
"description": "The checksummed payout address."
|
|
4573
|
+
},
|
|
4574
|
+
"network": {
|
|
4575
|
+
"type": "string",
|
|
4576
|
+
"enum": ["base", "base-sepolia"]
|
|
4577
|
+
},
|
|
4578
|
+
"label": { "type": ["string", "null"] },
|
|
4579
|
+
"is_default": {
|
|
3959
4580
|
"type": "boolean",
|
|
3960
|
-
"
|
|
4581
|
+
"description": "Exactly one address per (org, network) is the default."
|
|
3961
4582
|
},
|
|
3962
|
-
"
|
|
4583
|
+
"verified_at": {
|
|
4584
|
+
"type": "string",
|
|
4585
|
+
"format": "date-time",
|
|
4586
|
+
"description": "When ownership of the address was last proven."
|
|
4587
|
+
},
|
|
4588
|
+
"created_at": {
|
|
4589
|
+
"type": "string",
|
|
4590
|
+
"format": "date-time"
|
|
4591
|
+
}
|
|
3963
4592
|
},
|
|
3964
4593
|
"required": [
|
|
3965
|
-
"
|
|
3966
|
-
"
|
|
3967
|
-
"
|
|
4594
|
+
"id",
|
|
4595
|
+
"address",
|
|
4596
|
+
"network",
|
|
4597
|
+
"label",
|
|
4598
|
+
"is_default",
|
|
4599
|
+
"verified_at"
|
|
3968
4600
|
]
|
|
3969
4601
|
},
|
|
3970
|
-
"
|
|
4602
|
+
"CreateChallengeInput": {
|
|
3971
4603
|
"type": "object",
|
|
4604
|
+
"additionalProperties": false,
|
|
3972
4605
|
"properties": {
|
|
3973
|
-
"
|
|
3974
|
-
"type": "
|
|
3975
|
-
"
|
|
4606
|
+
"amount": {
|
|
4607
|
+
"type": "string",
|
|
4608
|
+
"pattern": "^[1-9][0-9]{0,38}$",
|
|
4609
|
+
"description": "Amount to collect, in token base units. USDC has 6 decimals, so\n`\"10000\"` is 0.01 USDC.\n"
|
|
3976
4610
|
},
|
|
3977
|
-
"
|
|
4611
|
+
"network": {
|
|
4612
|
+
"type": "string",
|
|
4613
|
+
"enum": ["base", "base-sepolia"]
|
|
4614
|
+
},
|
|
4615
|
+
"payer_org": {
|
|
4616
|
+
"type": "string",
|
|
4617
|
+
"format": "uuid",
|
|
4618
|
+
"description": "The org id allowed to pay this challenge (on-net binding). Optional.\n"
|
|
4619
|
+
},
|
|
4620
|
+
"expires_in": {
|
|
3978
4621
|
"type": "integer",
|
|
3979
|
-
"
|
|
4622
|
+
"minimum": 60,
|
|
4623
|
+
"maximum": 86400,
|
|
4624
|
+
"description": "Seconds until the challenge expires. Defaults to 3600."
|
|
3980
4625
|
},
|
|
3981
|
-
"
|
|
3982
|
-
"type":
|
|
3983
|
-
"
|
|
4626
|
+
"resource": {
|
|
4627
|
+
"type": "string",
|
|
4628
|
+
"format": "uri",
|
|
4629
|
+
"maxLength": 2048,
|
|
4630
|
+
"description": "Optional URL identifying what is being paid for. Defaults to a\nsynthetic `x402:challenge:<id>` identifier.\n"
|
|
4631
|
+
},
|
|
4632
|
+
"description": {
|
|
4633
|
+
"type": "string",
|
|
4634
|
+
"maxLength": 512,
|
|
4635
|
+
"description": "Optional human-readable description of the payment."
|
|
4636
|
+
}
|
|
4637
|
+
},
|
|
4638
|
+
"required": ["amount", "network"]
|
|
4639
|
+
},
|
|
4640
|
+
"X402NonceBinding": {
|
|
4641
|
+
"type": "object",
|
|
4642
|
+
"description": "The interaction binding the payer hashes into the EIP-3009 nonce\n(`deriveEip3009Nonce`). Pinning the nonce to this binding is what lets an\nx402 payment ride asynchronous transports safely: a replayed challenge\ncan't redirect funds and a signed payment can't settle twice.\n",
|
|
4643
|
+
"properties": {
|
|
4644
|
+
"interaction_id": {
|
|
4645
|
+
"type": "string",
|
|
4646
|
+
"description": "Interaction id, including its `@domain` part."
|
|
4647
|
+
},
|
|
4648
|
+
"challenge_step_id": {
|
|
4649
|
+
"type": "string",
|
|
4650
|
+
"format": "uuid"
|
|
4651
|
+
},
|
|
4652
|
+
"challenge_nonce": {
|
|
4653
|
+
"type": "string",
|
|
4654
|
+
"pattern": "^[0-9a-f]{64}$",
|
|
4655
|
+
"description": "32 random bytes as 64 lowercase hex chars."
|
|
3984
4656
|
}
|
|
3985
4657
|
},
|
|
3986
4658
|
"required": [
|
|
3987
|
-
"
|
|
3988
|
-
"
|
|
3989
|
-
"
|
|
4659
|
+
"interaction_id",
|
|
4660
|
+
"challenge_step_id",
|
|
4661
|
+
"challenge_nonce"
|
|
3990
4662
|
]
|
|
3991
4663
|
},
|
|
3992
|
-
"
|
|
4664
|
+
"X402PaymentRequirements": {
|
|
3993
4665
|
"type": "object",
|
|
4666
|
+
"description": "The x402 `PaymentRequirements` the payer signs over. Field names are\nx402's native camelCase, preserved byte-for-byte.\n",
|
|
3994
4667
|
"properties": {
|
|
3995
|
-
"
|
|
3996
|
-
"type": "
|
|
3997
|
-
"
|
|
4668
|
+
"scheme": {
|
|
4669
|
+
"type": "string",
|
|
4670
|
+
"description": "The x402 settlement scheme. Always `exact` for v1.",
|
|
4671
|
+
"example": "exact"
|
|
3998
4672
|
},
|
|
3999
|
-
"
|
|
4000
|
-
"type": "
|
|
4673
|
+
"network": {
|
|
4674
|
+
"type": "string",
|
|
4675
|
+
"enum": ["base", "base-sepolia"]
|
|
4676
|
+
},
|
|
4677
|
+
"maxAmountRequired": {
|
|
4678
|
+
"type": "string",
|
|
4679
|
+
"description": "Amount in token base units."
|
|
4680
|
+
},
|
|
4681
|
+
"payTo": {
|
|
4682
|
+
"type": "string",
|
|
4683
|
+
"description": "The payee's resolved payout address (checksummed)."
|
|
4684
|
+
},
|
|
4685
|
+
"asset": {
|
|
4686
|
+
"type": "string",
|
|
4687
|
+
"description": "The token contract address (checksummed). USDC."
|
|
4688
|
+
},
|
|
4689
|
+
"resource": { "type": "string" },
|
|
4690
|
+
"description": { "type": "string" },
|
|
4691
|
+
"maxTimeoutSeconds": { "type": "integer" },
|
|
4692
|
+
"extra": {
|
|
4693
|
+
"type": "object",
|
|
4694
|
+
"description": "The token's load-bearing EIP-712 domain params. `name` differs by\nchain (Base mainnet USDC is `USD Coin`, Base Sepolia is `USDC`); a\nwrong value produces a signature the verifier rejects.\n",
|
|
4695
|
+
"properties": {
|
|
4696
|
+
"name": { "type": "string" },
|
|
4697
|
+
"version": { "type": "string" }
|
|
4698
|
+
},
|
|
4699
|
+
"required": ["name", "version"]
|
|
4700
|
+
}
|
|
4701
|
+
},
|
|
4702
|
+
"required": [
|
|
4703
|
+
"scheme",
|
|
4704
|
+
"network",
|
|
4705
|
+
"maxAmountRequired",
|
|
4706
|
+
"payTo",
|
|
4707
|
+
"asset",
|
|
4708
|
+
"extra"
|
|
4709
|
+
]
|
|
4710
|
+
},
|
|
4711
|
+
"X402Challenge": {
|
|
4712
|
+
"type": "object",
|
|
4713
|
+
"properties": {
|
|
4714
|
+
"id": {
|
|
4715
|
+
"type": "string",
|
|
4716
|
+
"format": "uuid"
|
|
4717
|
+
},
|
|
4718
|
+
"status": {
|
|
4719
|
+
"type": "string",
|
|
4720
|
+
"enum": [
|
|
4721
|
+
"pending",
|
|
4722
|
+
"settling",
|
|
4723
|
+
"settled",
|
|
4724
|
+
"failed",
|
|
4725
|
+
"expired"
|
|
4726
|
+
]
|
|
4727
|
+
},
|
|
4728
|
+
"network": {
|
|
4729
|
+
"type": "string",
|
|
4730
|
+
"enum": ["base", "base-sepolia"]
|
|
4731
|
+
},
|
|
4732
|
+
"asset": {
|
|
4733
|
+
"type": "string",
|
|
4734
|
+
"description": "Token contract address (checksummed)."
|
|
4735
|
+
},
|
|
4736
|
+
"amount": {
|
|
4737
|
+
"type": "string",
|
|
4738
|
+
"description": "Amount in token base units."
|
|
4739
|
+
},
|
|
4740
|
+
"pay_to": {
|
|
4741
|
+
"type": "string",
|
|
4742
|
+
"description": "The payee's resolved payout address (checksummed)."
|
|
4743
|
+
},
|
|
4744
|
+
"payer_org": {
|
|
4745
|
+
"type": ["string", "null"],
|
|
4746
|
+
"description": "The org id bound as payer, if one was set at creation."
|
|
4747
|
+
},
|
|
4748
|
+
"resource": { "type": ["string", "null"] },
|
|
4749
|
+
"description": { "type": ["string", "null"] },
|
|
4750
|
+
"nonce_binding": { "$ref": "#/components/schemas/X402NonceBinding" },
|
|
4751
|
+
"settle_tx": {
|
|
4752
|
+
"type": ["string", "null"],
|
|
4753
|
+
"description": "On-chain settlement transaction hash once settled."
|
|
4754
|
+
},
|
|
4755
|
+
"settled_at": {
|
|
4756
|
+
"type": ["string", "null"],
|
|
4757
|
+
"format": "date-time"
|
|
4758
|
+
},
|
|
4759
|
+
"failure_reason": { "type": ["string", "null"] },
|
|
4760
|
+
"expires_at": {
|
|
4761
|
+
"type": "string",
|
|
4762
|
+
"format": "date-time"
|
|
4763
|
+
},
|
|
4764
|
+
"created_at": {
|
|
4765
|
+
"type": "string",
|
|
4766
|
+
"format": "date-time"
|
|
4767
|
+
},
|
|
4768
|
+
"payment_requirements": {
|
|
4769
|
+
"description": "Present on the create response. Hand the whole challenge (including\nthis) to the payer; `getChallenge` omits it (it is for status polling\nby the challenger).\n",
|
|
4770
|
+
"allOf": [{ "$ref": "#/components/schemas/X402PaymentRequirements" }]
|
|
4771
|
+
}
|
|
4772
|
+
},
|
|
4773
|
+
"required": [
|
|
4774
|
+
"id",
|
|
4775
|
+
"status",
|
|
4776
|
+
"network",
|
|
4777
|
+
"asset",
|
|
4778
|
+
"amount",
|
|
4779
|
+
"pay_to",
|
|
4780
|
+
"nonce_binding",
|
|
4781
|
+
"expires_at"
|
|
4782
|
+
]
|
|
4783
|
+
},
|
|
4784
|
+
"X402PaymentPayload": {
|
|
4785
|
+
"type": "object",
|
|
4786
|
+
"description": "A signed x402 v1 `PaymentPayload`. The SDK `pay()` helper builds this;\ncallers rarely construct it by hand. Field names are x402-native.\n",
|
|
4787
|
+
"properties": {
|
|
4788
|
+
"x402Version": {
|
|
4789
|
+
"type": "integer",
|
|
4790
|
+
"const": 1
|
|
4791
|
+
},
|
|
4792
|
+
"scheme": {
|
|
4793
|
+
"type": "string",
|
|
4794
|
+
"const": "exact"
|
|
4795
|
+
},
|
|
4796
|
+
"network": {
|
|
4797
|
+
"type": "string",
|
|
4798
|
+
"enum": ["base", "base-sepolia"]
|
|
4799
|
+
},
|
|
4800
|
+
"payload": {
|
|
4801
|
+
"type": "object",
|
|
4802
|
+
"properties": {
|
|
4803
|
+
"signature": {
|
|
4804
|
+
"type": "string",
|
|
4805
|
+
"pattern": "^0x[0-9a-fA-F]+$",
|
|
4806
|
+
"description": "The EIP-712 signature over the authorization."
|
|
4807
|
+
},
|
|
4808
|
+
"authorization": {
|
|
4809
|
+
"type": "object",
|
|
4810
|
+
"description": "The EIP-3009 `transferWithAuthorization` fields, as strings.",
|
|
4811
|
+
"properties": {
|
|
4812
|
+
"from": { "type": "string" },
|
|
4813
|
+
"to": { "type": "string" },
|
|
4814
|
+
"value": { "type": "string" },
|
|
4815
|
+
"validAfter": { "type": "string" },
|
|
4816
|
+
"validBefore": { "type": "string" },
|
|
4817
|
+
"nonce": { "type": "string" }
|
|
4818
|
+
},
|
|
4819
|
+
"required": [
|
|
4820
|
+
"from",
|
|
4821
|
+
"to",
|
|
4822
|
+
"value",
|
|
4823
|
+
"validAfter",
|
|
4824
|
+
"validBefore",
|
|
4825
|
+
"nonce"
|
|
4826
|
+
]
|
|
4827
|
+
}
|
|
4828
|
+
},
|
|
4829
|
+
"required": ["signature", "authorization"]
|
|
4830
|
+
}
|
|
4831
|
+
},
|
|
4832
|
+
"required": [
|
|
4833
|
+
"x402Version",
|
|
4834
|
+
"scheme",
|
|
4835
|
+
"network",
|
|
4836
|
+
"payload"
|
|
4837
|
+
]
|
|
4838
|
+
},
|
|
4839
|
+
"PayChallengeInput": {
|
|
4840
|
+
"type": "object",
|
|
4841
|
+
"additionalProperties": false,
|
|
4842
|
+
"properties": { "payment": { "$ref": "#/components/schemas/X402PaymentPayload" } },
|
|
4843
|
+
"required": ["payment"]
|
|
4844
|
+
},
|
|
4845
|
+
"X402Receipt": {
|
|
4846
|
+
"type": "object",
|
|
4847
|
+
"properties": {
|
|
4848
|
+
"id": {
|
|
4849
|
+
"type": "string",
|
|
4850
|
+
"format": "uuid"
|
|
4851
|
+
},
|
|
4852
|
+
"status": {
|
|
4853
|
+
"type": "string",
|
|
4854
|
+
"enum": ["settled"]
|
|
4855
|
+
},
|
|
4856
|
+
"settle_tx": {
|
|
4857
|
+
"type": ["string", "null"],
|
|
4858
|
+
"description": "On-chain settlement transaction hash."
|
|
4859
|
+
}
|
|
4860
|
+
},
|
|
4861
|
+
"required": [
|
|
4862
|
+
"id",
|
|
4863
|
+
"status",
|
|
4864
|
+
"settle_tx"
|
|
4865
|
+
]
|
|
4866
|
+
},
|
|
4867
|
+
"X402SpendPolicy": {
|
|
4868
|
+
"type": "object",
|
|
4869
|
+
"description": "The payer's outbound spend policy. Returned with defaults (not paused,\nno caps, any on-net payee) when none is set.\n",
|
|
4870
|
+
"properties": {
|
|
4871
|
+
"paused": {
|
|
4872
|
+
"type": "boolean",
|
|
4873
|
+
"description": "Kill-switch. When true, all outbound payments are refused."
|
|
4874
|
+
},
|
|
4875
|
+
"max_per_payment": {
|
|
4876
|
+
"type": ["string", "null"],
|
|
4877
|
+
"description": "Per-payment cap in token base units, or null for no cap."
|
|
4878
|
+
},
|
|
4879
|
+
"max_per_day": {
|
|
4880
|
+
"type": ["string", "null"],
|
|
4881
|
+
"description": "Rolling-day cap in token base units, or null for no cap."
|
|
4882
|
+
},
|
|
4883
|
+
"allowlist": {
|
|
4884
|
+
"type": ["array", "null"],
|
|
4885
|
+
"items": {
|
|
4886
|
+
"type": "string",
|
|
4887
|
+
"format": "uuid"
|
|
4888
|
+
},
|
|
4889
|
+
"description": "Allowed payee org ids. `null` allows any on-net payee; `[]` denies\nall.\n"
|
|
4890
|
+
}
|
|
4891
|
+
},
|
|
4892
|
+
"required": [
|
|
4893
|
+
"paused",
|
|
4894
|
+
"max_per_payment",
|
|
4895
|
+
"max_per_day",
|
|
4896
|
+
"allowlist"
|
|
4897
|
+
]
|
|
4898
|
+
},
|
|
4899
|
+
"UpdateSpendPolicyInput": {
|
|
4900
|
+
"type": "object",
|
|
4901
|
+
"additionalProperties": false,
|
|
4902
|
+
"description": "Merge update: only the fields you include change; omit a field to keep\nits current value; send `null` to clear a cap.\n",
|
|
4903
|
+
"properties": {
|
|
4904
|
+
"paused": { "type": "boolean" },
|
|
4905
|
+
"max_per_payment": {
|
|
4906
|
+
"type": ["string", "null"],
|
|
4907
|
+
"pattern": "^[1-9][0-9]{0,38}$"
|
|
4908
|
+
},
|
|
4909
|
+
"max_per_day": {
|
|
4910
|
+
"type": ["string", "null"],
|
|
4911
|
+
"pattern": "^[1-9][0-9]{0,38}$"
|
|
4912
|
+
},
|
|
4913
|
+
"allowlist": {
|
|
4914
|
+
"type": ["array", "null"],
|
|
4915
|
+
"maxItems": 1e3,
|
|
4916
|
+
"items": {
|
|
4917
|
+
"type": "string",
|
|
4918
|
+
"format": "uuid"
|
|
4919
|
+
}
|
|
4920
|
+
}
|
|
4921
|
+
}
|
|
4922
|
+
},
|
|
4923
|
+
"X402DeclinedPayment": {
|
|
4924
|
+
"type": "object",
|
|
4925
|
+
"description": "A payment the org's spend policy refused.",
|
|
4926
|
+
"properties": {
|
|
4927
|
+
"id": {
|
|
4928
|
+
"type": "string",
|
|
4929
|
+
"format": "uuid"
|
|
4930
|
+
},
|
|
4931
|
+
"challenge_id": {
|
|
4932
|
+
"type": ["string", "null"],
|
|
4933
|
+
"format": "uuid",
|
|
4934
|
+
"description": "The challenge that was declined, if still present."
|
|
4935
|
+
},
|
|
4936
|
+
"counterparty_org": {
|
|
4937
|
+
"type": ["string", "null"],
|
|
4938
|
+
"format": "uuid",
|
|
4939
|
+
"description": "The payee (challenger) org, when known."
|
|
4940
|
+
},
|
|
4941
|
+
"network": {
|
|
4942
|
+
"type": "string",
|
|
4943
|
+
"enum": ["base", "base-sepolia"]
|
|
4944
|
+
},
|
|
4945
|
+
"amount": {
|
|
4946
|
+
"type": "string",
|
|
4947
|
+
"description": "Amount in token base units."
|
|
4948
|
+
},
|
|
4949
|
+
"reason": {
|
|
4950
|
+
"type": "string",
|
|
4951
|
+
"description": "Why the payment was declined (cap, allowlist, paused)."
|
|
4952
|
+
},
|
|
4953
|
+
"declined_at": {
|
|
4954
|
+
"type": "string",
|
|
4955
|
+
"format": "date-time"
|
|
4956
|
+
}
|
|
4957
|
+
},
|
|
4958
|
+
"required": [
|
|
4959
|
+
"id",
|
|
4960
|
+
"network",
|
|
4961
|
+
"amount",
|
|
4962
|
+
"reason",
|
|
4963
|
+
"declined_at"
|
|
4964
|
+
]
|
|
4965
|
+
},
|
|
4966
|
+
"SuccessEnvelope": {
|
|
4967
|
+
"type": "object",
|
|
4968
|
+
"properties": { "success": {
|
|
4969
|
+
"type": "boolean",
|
|
4970
|
+
"const": true
|
|
4971
|
+
} },
|
|
4972
|
+
"required": ["success", "data"]
|
|
4973
|
+
},
|
|
4974
|
+
"ListEnvelope": {
|
|
4975
|
+
"type": "object",
|
|
4976
|
+
"properties": {
|
|
4977
|
+
"success": {
|
|
4978
|
+
"type": "boolean",
|
|
4979
|
+
"const": true
|
|
4980
|
+
},
|
|
4981
|
+
"meta": { "$ref": "#/components/schemas/PaginationMeta" }
|
|
4982
|
+
},
|
|
4983
|
+
"required": [
|
|
4984
|
+
"success",
|
|
4985
|
+
"data",
|
|
4986
|
+
"meta"
|
|
4987
|
+
]
|
|
4988
|
+
},
|
|
4989
|
+
"PaginationMeta": {
|
|
4990
|
+
"type": "object",
|
|
4991
|
+
"properties": {
|
|
4992
|
+
"total": {
|
|
4993
|
+
"type": "integer",
|
|
4994
|
+
"description": "Total number of matching records"
|
|
4995
|
+
},
|
|
4996
|
+
"limit": {
|
|
4997
|
+
"type": "integer",
|
|
4998
|
+
"description": "Page size used for this request"
|
|
4999
|
+
},
|
|
5000
|
+
"cursor": {
|
|
5001
|
+
"type": ["string", "null"],
|
|
5002
|
+
"description": "Cursor for the next page, or null if no more results"
|
|
5003
|
+
}
|
|
5004
|
+
},
|
|
5005
|
+
"required": [
|
|
5006
|
+
"total",
|
|
5007
|
+
"limit",
|
|
5008
|
+
"cursor"
|
|
5009
|
+
]
|
|
5010
|
+
},
|
|
5011
|
+
"ErrorResponse": {
|
|
5012
|
+
"type": "object",
|
|
5013
|
+
"properties": {
|
|
5014
|
+
"success": {
|
|
5015
|
+
"type": "boolean",
|
|
5016
|
+
"const": false
|
|
5017
|
+
},
|
|
5018
|
+
"error": {
|
|
5019
|
+
"type": "object",
|
|
4001
5020
|
"properties": {
|
|
4002
5021
|
"code": {
|
|
4003
5022
|
"type": "string",
|
|
@@ -4033,7 +5052,14 @@ const openapiDocument = {
|
|
|
4033
5052
|
"email_delivery_failed",
|
|
4034
5053
|
"clerk_signup_failed",
|
|
4035
5054
|
"no_orgs_for_user",
|
|
4036
|
-
"org_not_accessible"
|
|
5055
|
+
"org_not_accessible",
|
|
5056
|
+
"feature_disabled",
|
|
5057
|
+
"no_payout_address",
|
|
5058
|
+
"ownership_proof_failed",
|
|
5059
|
+
"payment_verification_failed",
|
|
5060
|
+
"payment_declined",
|
|
5061
|
+
"challenge_expired",
|
|
5062
|
+
"settlement_failed"
|
|
4037
5063
|
]
|
|
4038
5064
|
},
|
|
4039
5065
|
"message": { "type": "string" },
|
|
@@ -7920,31 +8946,106 @@ const openapiDocument = {
|
|
|
7920
8946
|
"updated_at",
|
|
7921
8947
|
"created"
|
|
7922
8948
|
]
|
|
7923
|
-
}
|
|
7924
|
-
|
|
7925
|
-
|
|
7926
|
-
|
|
7927
|
-
|
|
7928
|
-
|
|
7929
|
-
|
|
7930
|
-
|
|
7931
|
-
|
|
7932
|
-
|
|
7933
|
-
|
|
7934
|
-
|
|
7935
|
-
|
|
7936
|
-
|
|
7937
|
-
|
|
7938
|
-
|
|
7939
|
-
|
|
7940
|
-
|
|
7941
|
-
|
|
7942
|
-
|
|
7943
|
-
|
|
7944
|
-
"
|
|
7945
|
-
"
|
|
7946
|
-
|
|
7947
|
-
|
|
8949
|
+
},
|
|
8950
|
+
"OrgSecretListItem": {
|
|
8951
|
+
"type": "object",
|
|
8952
|
+
"description": "One row from GET /org/secrets. Org secrets are always user-set\n(there are no managed org secrets), so `created_at` /\n`updated_at` are always present.\n",
|
|
8953
|
+
"properties": {
|
|
8954
|
+
"key": { "type": "string" },
|
|
8955
|
+
"created_at": {
|
|
8956
|
+
"type": "string",
|
|
8957
|
+
"format": "date-time"
|
|
8958
|
+
},
|
|
8959
|
+
"updated_at": {
|
|
8960
|
+
"type": "string",
|
|
8961
|
+
"format": "date-time"
|
|
8962
|
+
}
|
|
8963
|
+
},
|
|
8964
|
+
"required": [
|
|
8965
|
+
"key",
|
|
8966
|
+
"created_at",
|
|
8967
|
+
"updated_at"
|
|
8968
|
+
]
|
|
8969
|
+
},
|
|
8970
|
+
"CreateOrgSecretInput": {
|
|
8971
|
+
"type": "object",
|
|
8972
|
+
"additionalProperties": false,
|
|
8973
|
+
"description": "Body for POST /org/secrets.",
|
|
8974
|
+
"properties": {
|
|
8975
|
+
"key": {
|
|
8976
|
+
"type": "string",
|
|
8977
|
+
"pattern": "^[A-Z_][A-Z0-9_]*$",
|
|
8978
|
+
"description": "Uppercase letters, digits, and underscores. Must start with\na letter or underscore. System-managed keys are reserved.\n"
|
|
8979
|
+
},
|
|
8980
|
+
"value": {
|
|
8981
|
+
"type": "string",
|
|
8982
|
+
"minLength": 1,
|
|
8983
|
+
"maxLength": 4096,
|
|
8984
|
+
"description": "Secret value, up to 4096 UTF-8 bytes. Encrypted at rest.\nNever returned by any read endpoint.\n"
|
|
8985
|
+
}
|
|
8986
|
+
},
|
|
8987
|
+
"required": ["key", "value"]
|
|
8988
|
+
},
|
|
8989
|
+
"SetOrgSecretInput": {
|
|
8990
|
+
"type": "object",
|
|
8991
|
+
"additionalProperties": false,
|
|
8992
|
+
"description": "Body for PUT /org/secrets/{key}. Key comes from the path.",
|
|
8993
|
+
"properties": { "value": {
|
|
8994
|
+
"type": "string",
|
|
8995
|
+
"minLength": 1,
|
|
8996
|
+
"maxLength": 4096
|
|
8997
|
+
} },
|
|
8998
|
+
"required": ["value"]
|
|
8999
|
+
},
|
|
9000
|
+
"OrgSecretWriteResult": {
|
|
9001
|
+
"type": "object",
|
|
9002
|
+
"description": "Returned by POST and PUT org secret routes.",
|
|
9003
|
+
"properties": {
|
|
9004
|
+
"key": { "type": "string" },
|
|
9005
|
+
"created_at": {
|
|
9006
|
+
"type": "string",
|
|
9007
|
+
"format": "date-time"
|
|
9008
|
+
},
|
|
9009
|
+
"updated_at": {
|
|
9010
|
+
"type": "string",
|
|
9011
|
+
"format": "date-time"
|
|
9012
|
+
},
|
|
9013
|
+
"created": {
|
|
9014
|
+
"type": "boolean",
|
|
9015
|
+
"description": "True if this call inserted a new row, false if it updated an existing one."
|
|
9016
|
+
}
|
|
9017
|
+
},
|
|
9018
|
+
"required": [
|
|
9019
|
+
"key",
|
|
9020
|
+
"created_at",
|
|
9021
|
+
"updated_at",
|
|
9022
|
+
"created"
|
|
9023
|
+
]
|
|
9024
|
+
}
|
|
9025
|
+
}
|
|
9026
|
+
}
|
|
9027
|
+
};
|
|
9028
|
+
//#endregion
|
|
9029
|
+
//#region ../packages/api-core/src/openapi/operations.generated.ts
|
|
9030
|
+
const operationManifest = [
|
|
9031
|
+
{
|
|
9032
|
+
"binaryResponse": false,
|
|
9033
|
+
"bodyRequired": false,
|
|
9034
|
+
"command": "get-account",
|
|
9035
|
+
"description": null,
|
|
9036
|
+
"hasJsonBody": false,
|
|
9037
|
+
"method": "GET",
|
|
9038
|
+
"operationId": "getAccount",
|
|
9039
|
+
"path": "/account",
|
|
9040
|
+
"pathParams": [],
|
|
9041
|
+
"queryParams": [],
|
|
9042
|
+
"requestSchema": null,
|
|
9043
|
+
"responseSchema": {
|
|
9044
|
+
"type": "object",
|
|
9045
|
+
"properties": {
|
|
9046
|
+
"id": {
|
|
9047
|
+
"type": "string",
|
|
9048
|
+
"format": "uuid"
|
|
7948
9049
|
},
|
|
7949
9050
|
"email": { "type": "string" },
|
|
7950
9051
|
"plan": { "type": "string" },
|
|
@@ -11624,6 +12725,66 @@ const operationManifest = [
|
|
|
11624
12725
|
"tag": "Functions",
|
|
11625
12726
|
"tagCommand": "functions"
|
|
11626
12727
|
},
|
|
12728
|
+
{
|
|
12729
|
+
"binaryResponse": false,
|
|
12730
|
+
"bodyRequired": true,
|
|
12731
|
+
"command": "create-org-secret",
|
|
12732
|
+
"description": "Idempotent insert-or-update keyed on `(org_id, key)`. Returns\n201 the first time the key is set, 200 on subsequent updates.\nValues are encrypted at rest. A changed value lands in a\nfunction only on that function's next deploy.\n\nKeys must match `^[A-Z_][A-Z0-9_]*$` (uppercase letters,\ndigits, underscores; first character is a letter or\nunderscore). Values are at most 4096 UTF-8 bytes. System-\nmanaged keys are reserved and rejected.\n",
|
|
12733
|
+
"hasJsonBody": true,
|
|
12734
|
+
"method": "POST",
|
|
12735
|
+
"operationId": "createOrgSecret",
|
|
12736
|
+
"path": "/org/secrets",
|
|
12737
|
+
"pathParams": [],
|
|
12738
|
+
"queryParams": [],
|
|
12739
|
+
"requestSchema": {
|
|
12740
|
+
"type": "object",
|
|
12741
|
+
"additionalProperties": false,
|
|
12742
|
+
"description": "Body for POST /org/secrets.",
|
|
12743
|
+
"properties": {
|
|
12744
|
+
"key": {
|
|
12745
|
+
"type": "string",
|
|
12746
|
+
"pattern": "^[A-Z_][A-Z0-9_]*$",
|
|
12747
|
+
"description": "Uppercase letters, digits, and underscores. Must start with\na letter or underscore. System-managed keys are reserved.\n"
|
|
12748
|
+
},
|
|
12749
|
+
"value": {
|
|
12750
|
+
"type": "string",
|
|
12751
|
+
"minLength": 1,
|
|
12752
|
+
"maxLength": 4096,
|
|
12753
|
+
"description": "Secret value, up to 4096 UTF-8 bytes. Encrypted at rest.\nNever returned by any read endpoint.\n"
|
|
12754
|
+
}
|
|
12755
|
+
},
|
|
12756
|
+
"required": ["key", "value"]
|
|
12757
|
+
},
|
|
12758
|
+
"responseSchema": {
|
|
12759
|
+
"type": "object",
|
|
12760
|
+
"description": "Returned by POST and PUT org secret routes.",
|
|
12761
|
+
"properties": {
|
|
12762
|
+
"key": { "type": "string" },
|
|
12763
|
+
"created_at": {
|
|
12764
|
+
"type": "string",
|
|
12765
|
+
"format": "date-time"
|
|
12766
|
+
},
|
|
12767
|
+
"updated_at": {
|
|
12768
|
+
"type": "string",
|
|
12769
|
+
"format": "date-time"
|
|
12770
|
+
},
|
|
12771
|
+
"created": {
|
|
12772
|
+
"type": "boolean",
|
|
12773
|
+
"description": "True if this call inserted a new row, false if it updated an existing one."
|
|
12774
|
+
}
|
|
12775
|
+
},
|
|
12776
|
+
"required": [
|
|
12777
|
+
"key",
|
|
12778
|
+
"created_at",
|
|
12779
|
+
"updated_at",
|
|
12780
|
+
"created"
|
|
12781
|
+
]
|
|
12782
|
+
},
|
|
12783
|
+
"sdkName": "createOrgSecret",
|
|
12784
|
+
"summary": "Create or update an org secret",
|
|
12785
|
+
"tag": "Functions",
|
|
12786
|
+
"tagCommand": "functions"
|
|
12787
|
+
},
|
|
11627
12788
|
{
|
|
11628
12789
|
"binaryResponse": false,
|
|
11629
12790
|
"bodyRequired": false,
|
|
@@ -11678,6 +12839,30 @@ const operationManifest = [
|
|
|
11678
12839
|
"tag": "Functions",
|
|
11679
12840
|
"tagCommand": "functions"
|
|
11680
12841
|
},
|
|
12842
|
+
{
|
|
12843
|
+
"binaryResponse": false,
|
|
12844
|
+
"bodyRequired": false,
|
|
12845
|
+
"command": "delete-org-secret",
|
|
12846
|
+
"description": "Removes the org secret. Functions keep the previous value until\neach is redeployed. Returns 404 if the key did not exist.\n",
|
|
12847
|
+
"hasJsonBody": false,
|
|
12848
|
+
"method": "DELETE",
|
|
12849
|
+
"operationId": "deleteOrgSecret",
|
|
12850
|
+
"path": "/org/secrets/{key}",
|
|
12851
|
+
"pathParams": [{
|
|
12852
|
+
"description": "Secret key. Must match `^[A-Z_][A-Z0-9_]*$`.",
|
|
12853
|
+
"enum": null,
|
|
12854
|
+
"name": "key",
|
|
12855
|
+
"required": true,
|
|
12856
|
+
"type": "string"
|
|
12857
|
+
}],
|
|
12858
|
+
"queryParams": [],
|
|
12859
|
+
"requestSchema": null,
|
|
12860
|
+
"responseSchema": null,
|
|
12861
|
+
"sdkName": "deleteOrgSecret",
|
|
12862
|
+
"summary": "Delete an org secret",
|
|
12863
|
+
"tag": "Functions",
|
|
12864
|
+
"tagCommand": "functions"
|
|
12865
|
+
},
|
|
11681
12866
|
{
|
|
11682
12867
|
"binaryResponse": false,
|
|
11683
12868
|
"bodyRequired": false,
|
|
@@ -12558,6 +13743,50 @@ const operationManifest = [
|
|
|
12558
13743
|
"tag": "Functions",
|
|
12559
13744
|
"tagCommand": "functions"
|
|
12560
13745
|
},
|
|
13746
|
+
{
|
|
13747
|
+
"binaryResponse": false,
|
|
13748
|
+
"bodyRequired": false,
|
|
13749
|
+
"command": "list-org-secrets",
|
|
13750
|
+
"description": "Returns metadata for every org-level secret. Org secrets apply\nto every function in the org and are read as `env.<KEY>` in\nhandlers. **Values are never returned.** Secret writes are\nwrite-only. A function-level secret of the same name overrides\nthe org-level value for that function.\n",
|
|
13751
|
+
"hasJsonBody": false,
|
|
13752
|
+
"method": "GET",
|
|
13753
|
+
"operationId": "listOrgSecrets",
|
|
13754
|
+
"path": "/org/secrets",
|
|
13755
|
+
"pathParams": [],
|
|
13756
|
+
"queryParams": [],
|
|
13757
|
+
"requestSchema": null,
|
|
13758
|
+
"responseSchema": {
|
|
13759
|
+
"type": "object",
|
|
13760
|
+
"properties": { "items": {
|
|
13761
|
+
"type": "array",
|
|
13762
|
+
"items": {
|
|
13763
|
+
"type": "object",
|
|
13764
|
+
"description": "One row from GET /org/secrets. Org secrets are always user-set\n(there are no managed org secrets), so `created_at` /\n`updated_at` are always present.\n",
|
|
13765
|
+
"properties": {
|
|
13766
|
+
"key": { "type": "string" },
|
|
13767
|
+
"created_at": {
|
|
13768
|
+
"type": "string",
|
|
13769
|
+
"format": "date-time"
|
|
13770
|
+
},
|
|
13771
|
+
"updated_at": {
|
|
13772
|
+
"type": "string",
|
|
13773
|
+
"format": "date-time"
|
|
13774
|
+
}
|
|
13775
|
+
},
|
|
13776
|
+
"required": [
|
|
13777
|
+
"key",
|
|
13778
|
+
"created_at",
|
|
13779
|
+
"updated_at"
|
|
13780
|
+
]
|
|
13781
|
+
}
|
|
13782
|
+
} },
|
|
13783
|
+
"required": ["items"]
|
|
13784
|
+
},
|
|
13785
|
+
"sdkName": "listOrgSecrets",
|
|
13786
|
+
"summary": "List org-level (global) secrets",
|
|
13787
|
+
"tag": "Functions",
|
|
13788
|
+
"tagCommand": "functions"
|
|
13789
|
+
},
|
|
12561
13790
|
{
|
|
12562
13791
|
"binaryResponse": false,
|
|
12563
13792
|
"bodyRequired": true,
|
|
@@ -12746,6 +13975,64 @@ const operationManifest = [
|
|
|
12746
13975
|
"tag": "Functions",
|
|
12747
13976
|
"tagCommand": "functions"
|
|
12748
13977
|
},
|
|
13978
|
+
{
|
|
13979
|
+
"binaryResponse": false,
|
|
13980
|
+
"bodyRequired": true,
|
|
13981
|
+
"command": "set-org-secret",
|
|
13982
|
+
"description": "Path-keyed companion to `POST /org/secrets`. Idempotent:\nreturns 201 the first time the key is set, 200 on subsequent\nupdates. Same validation and write-only guarantees as POST.\n",
|
|
13983
|
+
"hasJsonBody": true,
|
|
13984
|
+
"method": "PUT",
|
|
13985
|
+
"operationId": "setOrgSecret",
|
|
13986
|
+
"path": "/org/secrets/{key}",
|
|
13987
|
+
"pathParams": [{
|
|
13988
|
+
"description": "Secret key. Must match `^[A-Z_][A-Z0-9_]*$`.",
|
|
13989
|
+
"enum": null,
|
|
13990
|
+
"name": "key",
|
|
13991
|
+
"required": true,
|
|
13992
|
+
"type": "string"
|
|
13993
|
+
}],
|
|
13994
|
+
"queryParams": [],
|
|
13995
|
+
"requestSchema": {
|
|
13996
|
+
"type": "object",
|
|
13997
|
+
"additionalProperties": false,
|
|
13998
|
+
"description": "Body for PUT /org/secrets/{key}. Key comes from the path.",
|
|
13999
|
+
"properties": { "value": {
|
|
14000
|
+
"type": "string",
|
|
14001
|
+
"minLength": 1,
|
|
14002
|
+
"maxLength": 4096
|
|
14003
|
+
} },
|
|
14004
|
+
"required": ["value"]
|
|
14005
|
+
},
|
|
14006
|
+
"responseSchema": {
|
|
14007
|
+
"type": "object",
|
|
14008
|
+
"description": "Returned by POST and PUT org secret routes.",
|
|
14009
|
+
"properties": {
|
|
14010
|
+
"key": { "type": "string" },
|
|
14011
|
+
"created_at": {
|
|
14012
|
+
"type": "string",
|
|
14013
|
+
"format": "date-time"
|
|
14014
|
+
},
|
|
14015
|
+
"updated_at": {
|
|
14016
|
+
"type": "string",
|
|
14017
|
+
"format": "date-time"
|
|
14018
|
+
},
|
|
14019
|
+
"created": {
|
|
14020
|
+
"type": "boolean",
|
|
14021
|
+
"description": "True if this call inserted a new row, false if it updated an existing one."
|
|
14022
|
+
}
|
|
14023
|
+
},
|
|
14024
|
+
"required": [
|
|
14025
|
+
"key",
|
|
14026
|
+
"created_at",
|
|
14027
|
+
"updated_at",
|
|
14028
|
+
"created"
|
|
14029
|
+
]
|
|
14030
|
+
},
|
|
14031
|
+
"sdkName": "setOrgSecret",
|
|
14032
|
+
"summary": "Set an org secret by key",
|
|
14033
|
+
"tag": "Functions",
|
|
14034
|
+
"tagCommand": "functions"
|
|
14035
|
+
},
|
|
12749
14036
|
{
|
|
12750
14037
|
"binaryResponse": false,
|
|
12751
14038
|
"bodyRequired": false,
|
|
@@ -13073,78 +14360,878 @@ const operationManifest = [
|
|
|
13073
14360
|
]
|
|
13074
14361
|
}
|
|
13075
14362
|
},
|
|
13076
|
-
"endpoints": {
|
|
13077
|
-
"type": "object",
|
|
13078
|
-
"additionalProperties": false,
|
|
13079
|
-
"properties": {
|
|
13080
|
-
"total": { "type": "integer" },
|
|
13081
|
-
"enabled": { "type": "integer" },
|
|
13082
|
-
"disabled": { "type": "integer" },
|
|
13083
|
-
"fallback_enabled": { "type": "integer" },
|
|
13084
|
-
"domain_scoped_enabled": { "type": "integer" },
|
|
13085
|
-
"http_enabled": { "type": "integer" },
|
|
13086
|
-
"function_enabled": { "type": "integer" }
|
|
13087
|
-
},
|
|
13088
|
-
"required": [
|
|
13089
|
-
"total",
|
|
13090
|
-
"enabled",
|
|
13091
|
-
"disabled",
|
|
13092
|
-
"fallback_enabled",
|
|
13093
|
-
"domain_scoped_enabled",
|
|
13094
|
-
"http_enabled",
|
|
13095
|
-
"function_enabled"
|
|
13096
|
-
]
|
|
14363
|
+
"endpoints": {
|
|
14364
|
+
"type": "object",
|
|
14365
|
+
"additionalProperties": false,
|
|
14366
|
+
"properties": {
|
|
14367
|
+
"total": { "type": "integer" },
|
|
14368
|
+
"enabled": { "type": "integer" },
|
|
14369
|
+
"disabled": { "type": "integer" },
|
|
14370
|
+
"fallback_enabled": { "type": "integer" },
|
|
14371
|
+
"domain_scoped_enabled": { "type": "integer" },
|
|
14372
|
+
"http_enabled": { "type": "integer" },
|
|
14373
|
+
"function_enabled": { "type": "integer" }
|
|
14374
|
+
},
|
|
14375
|
+
"required": [
|
|
14376
|
+
"total",
|
|
14377
|
+
"enabled",
|
|
14378
|
+
"disabled",
|
|
14379
|
+
"fallback_enabled",
|
|
14380
|
+
"domain_scoped_enabled",
|
|
14381
|
+
"http_enabled",
|
|
14382
|
+
"function_enabled"
|
|
14383
|
+
]
|
|
14384
|
+
},
|
|
14385
|
+
"functions": {
|
|
14386
|
+
"type": "object",
|
|
14387
|
+
"additionalProperties": false,
|
|
14388
|
+
"properties": {
|
|
14389
|
+
"total": { "type": "integer" },
|
|
14390
|
+
"deployed": { "type": "integer" },
|
|
14391
|
+
"pending": { "type": "integer" },
|
|
14392
|
+
"failed": { "type": "integer" }
|
|
14393
|
+
},
|
|
14394
|
+
"required": [
|
|
14395
|
+
"total",
|
|
14396
|
+
"deployed",
|
|
14397
|
+
"pending",
|
|
14398
|
+
"failed"
|
|
14399
|
+
]
|
|
14400
|
+
},
|
|
14401
|
+
"recent_emails": {
|
|
14402
|
+
"type": "object",
|
|
14403
|
+
"description": "Inbound email activity from the last 30 days.",
|
|
14404
|
+
"additionalProperties": false,
|
|
14405
|
+
"properties": {
|
|
14406
|
+
"total": {
|
|
14407
|
+
"type": "integer",
|
|
14408
|
+
"description": "Number of inbound emails received in the last 30 days."
|
|
14409
|
+
},
|
|
14410
|
+
"latest_received_at": {
|
|
14411
|
+
"type": ["string", "null"],
|
|
14412
|
+
"format": "date-time",
|
|
14413
|
+
"description": "Most recent inbound email received in the last 30 days."
|
|
14414
|
+
}
|
|
14415
|
+
},
|
|
14416
|
+
"required": ["total", "latest_received_at"]
|
|
14417
|
+
}
|
|
14418
|
+
},
|
|
14419
|
+
"required": [
|
|
14420
|
+
"ready",
|
|
14421
|
+
"receiving_ready",
|
|
14422
|
+
"processing_ready",
|
|
14423
|
+
"summary",
|
|
14424
|
+
"next_actions",
|
|
14425
|
+
"domains",
|
|
14426
|
+
"endpoints",
|
|
14427
|
+
"functions",
|
|
14428
|
+
"recent_emails"
|
|
14429
|
+
]
|
|
14430
|
+
},
|
|
14431
|
+
"sdkName": "getInboxStatus",
|
|
14432
|
+
"summary": "Get inbound inbox readiness",
|
|
14433
|
+
"tag": "Inbox",
|
|
14434
|
+
"tagCommand": "inbox"
|
|
14435
|
+
},
|
|
14436
|
+
{
|
|
14437
|
+
"binaryResponse": false,
|
|
14438
|
+
"bodyRequired": true,
|
|
14439
|
+
"command": "create-challenge",
|
|
14440
|
+
"description": "Create an x402 payment challenge (the payee side of a payment). The\n`pay_to` address is resolved server-side from your registered default\npayout address for the network, never from the request. The response\ncarries the `nonce_binding` and `payment_requirements` the payer needs to\nsign; hand the whole challenge object to the payer (for example in an\nemail reply). Amounts are in token base units (USDC has 6 decimals, so\n`\"10000\"` is 0.01 USDC).\n",
|
|
14441
|
+
"hasJsonBody": true,
|
|
14442
|
+
"method": "POST",
|
|
14443
|
+
"operationId": "createChallenge",
|
|
14444
|
+
"path": "/x402/challenges",
|
|
14445
|
+
"pathParams": [],
|
|
14446
|
+
"queryParams": [],
|
|
14447
|
+
"requestSchema": {
|
|
14448
|
+
"type": "object",
|
|
14449
|
+
"additionalProperties": false,
|
|
14450
|
+
"properties": {
|
|
14451
|
+
"amount": {
|
|
14452
|
+
"type": "string",
|
|
14453
|
+
"pattern": "^[1-9][0-9]{0,38}$",
|
|
14454
|
+
"description": "Amount to collect, in token base units. USDC has 6 decimals, so\n`\"10000\"` is 0.01 USDC.\n"
|
|
14455
|
+
},
|
|
14456
|
+
"network": {
|
|
14457
|
+
"type": "string",
|
|
14458
|
+
"enum": ["base", "base-sepolia"]
|
|
14459
|
+
},
|
|
14460
|
+
"payer_org": {
|
|
14461
|
+
"type": "string",
|
|
14462
|
+
"format": "uuid",
|
|
14463
|
+
"description": "The org id allowed to pay this challenge (on-net binding). Optional.\n"
|
|
14464
|
+
},
|
|
14465
|
+
"expires_in": {
|
|
14466
|
+
"type": "integer",
|
|
14467
|
+
"minimum": 60,
|
|
14468
|
+
"maximum": 86400,
|
|
14469
|
+
"description": "Seconds until the challenge expires. Defaults to 3600."
|
|
14470
|
+
},
|
|
14471
|
+
"resource": {
|
|
14472
|
+
"type": "string",
|
|
14473
|
+
"format": "uri",
|
|
14474
|
+
"maxLength": 2048,
|
|
14475
|
+
"description": "Optional URL identifying what is being paid for. Defaults to a\nsynthetic `x402:challenge:<id>` identifier.\n"
|
|
14476
|
+
},
|
|
14477
|
+
"description": {
|
|
14478
|
+
"type": "string",
|
|
14479
|
+
"maxLength": 512,
|
|
14480
|
+
"description": "Optional human-readable description of the payment."
|
|
14481
|
+
}
|
|
14482
|
+
},
|
|
14483
|
+
"required": ["amount", "network"]
|
|
14484
|
+
},
|
|
14485
|
+
"responseSchema": {
|
|
14486
|
+
"type": "object",
|
|
14487
|
+
"properties": {
|
|
14488
|
+
"id": {
|
|
14489
|
+
"type": "string",
|
|
14490
|
+
"format": "uuid"
|
|
14491
|
+
},
|
|
14492
|
+
"status": {
|
|
14493
|
+
"type": "string",
|
|
14494
|
+
"enum": [
|
|
14495
|
+
"pending",
|
|
14496
|
+
"settling",
|
|
14497
|
+
"settled",
|
|
14498
|
+
"failed",
|
|
14499
|
+
"expired"
|
|
14500
|
+
]
|
|
14501
|
+
},
|
|
14502
|
+
"network": {
|
|
14503
|
+
"type": "string",
|
|
14504
|
+
"enum": ["base", "base-sepolia"]
|
|
14505
|
+
},
|
|
14506
|
+
"asset": {
|
|
14507
|
+
"type": "string",
|
|
14508
|
+
"description": "Token contract address (checksummed)."
|
|
14509
|
+
},
|
|
14510
|
+
"amount": {
|
|
14511
|
+
"type": "string",
|
|
14512
|
+
"description": "Amount in token base units."
|
|
14513
|
+
},
|
|
14514
|
+
"pay_to": {
|
|
14515
|
+
"type": "string",
|
|
14516
|
+
"description": "The payee's resolved payout address (checksummed)."
|
|
14517
|
+
},
|
|
14518
|
+
"payer_org": {
|
|
14519
|
+
"type": ["string", "null"],
|
|
14520
|
+
"description": "The org id bound as payer, if one was set at creation."
|
|
14521
|
+
},
|
|
14522
|
+
"resource": { "type": ["string", "null"] },
|
|
14523
|
+
"description": { "type": ["string", "null"] },
|
|
14524
|
+
"nonce_binding": {
|
|
14525
|
+
"type": "object",
|
|
14526
|
+
"description": "The interaction binding the payer hashes into the EIP-3009 nonce\n(`deriveEip3009Nonce`). Pinning the nonce to this binding is what lets an\nx402 payment ride asynchronous transports safely: a replayed challenge\ncan't redirect funds and a signed payment can't settle twice.\n",
|
|
14527
|
+
"properties": {
|
|
14528
|
+
"interaction_id": {
|
|
14529
|
+
"type": "string",
|
|
14530
|
+
"description": "Interaction id, including its `@domain` part."
|
|
14531
|
+
},
|
|
14532
|
+
"challenge_step_id": {
|
|
14533
|
+
"type": "string",
|
|
14534
|
+
"format": "uuid"
|
|
14535
|
+
},
|
|
14536
|
+
"challenge_nonce": {
|
|
14537
|
+
"type": "string",
|
|
14538
|
+
"pattern": "^[0-9a-f]{64}$",
|
|
14539
|
+
"description": "32 random bytes as 64 lowercase hex chars."
|
|
14540
|
+
}
|
|
14541
|
+
},
|
|
14542
|
+
"required": [
|
|
14543
|
+
"interaction_id",
|
|
14544
|
+
"challenge_step_id",
|
|
14545
|
+
"challenge_nonce"
|
|
14546
|
+
]
|
|
14547
|
+
},
|
|
14548
|
+
"settle_tx": {
|
|
14549
|
+
"type": ["string", "null"],
|
|
14550
|
+
"description": "On-chain settlement transaction hash once settled."
|
|
14551
|
+
},
|
|
14552
|
+
"settled_at": {
|
|
14553
|
+
"type": ["string", "null"],
|
|
14554
|
+
"format": "date-time"
|
|
14555
|
+
},
|
|
14556
|
+
"failure_reason": { "type": ["string", "null"] },
|
|
14557
|
+
"expires_at": {
|
|
14558
|
+
"type": "string",
|
|
14559
|
+
"format": "date-time"
|
|
14560
|
+
},
|
|
14561
|
+
"created_at": {
|
|
14562
|
+
"type": "string",
|
|
14563
|
+
"format": "date-time"
|
|
14564
|
+
},
|
|
14565
|
+
"payment_requirements": {
|
|
14566
|
+
"description": "Present on the create response. Hand the whole challenge (including\nthis) to the payer; `getChallenge` omits it (it is for status polling\nby the challenger).\n",
|
|
14567
|
+
"allOf": [{
|
|
14568
|
+
"type": "object",
|
|
14569
|
+
"description": "The x402 `PaymentRequirements` the payer signs over. Field names are\nx402's native camelCase, preserved byte-for-byte.\n",
|
|
14570
|
+
"properties": {
|
|
14571
|
+
"scheme": {
|
|
14572
|
+
"type": "string",
|
|
14573
|
+
"description": "The x402 settlement scheme. Always `exact` for v1.",
|
|
14574
|
+
"example": "exact"
|
|
14575
|
+
},
|
|
14576
|
+
"network": {
|
|
14577
|
+
"type": "string",
|
|
14578
|
+
"enum": ["base", "base-sepolia"]
|
|
14579
|
+
},
|
|
14580
|
+
"maxAmountRequired": {
|
|
14581
|
+
"type": "string",
|
|
14582
|
+
"description": "Amount in token base units."
|
|
14583
|
+
},
|
|
14584
|
+
"payTo": {
|
|
14585
|
+
"type": "string",
|
|
14586
|
+
"description": "The payee's resolved payout address (checksummed)."
|
|
14587
|
+
},
|
|
14588
|
+
"asset": {
|
|
14589
|
+
"type": "string",
|
|
14590
|
+
"description": "The token contract address (checksummed). USDC."
|
|
14591
|
+
},
|
|
14592
|
+
"resource": { "type": "string" },
|
|
14593
|
+
"description": { "type": "string" },
|
|
14594
|
+
"maxTimeoutSeconds": { "type": "integer" },
|
|
14595
|
+
"extra": {
|
|
14596
|
+
"type": "object",
|
|
14597
|
+
"description": "The token's load-bearing EIP-712 domain params. `name` differs by\nchain (Base mainnet USDC is `USD Coin`, Base Sepolia is `USDC`); a\nwrong value produces a signature the verifier rejects.\n",
|
|
14598
|
+
"properties": {
|
|
14599
|
+
"name": { "type": "string" },
|
|
14600
|
+
"version": { "type": "string" }
|
|
14601
|
+
},
|
|
14602
|
+
"required": ["name", "version"]
|
|
14603
|
+
}
|
|
14604
|
+
},
|
|
14605
|
+
"required": [
|
|
14606
|
+
"scheme",
|
|
14607
|
+
"network",
|
|
14608
|
+
"maxAmountRequired",
|
|
14609
|
+
"payTo",
|
|
14610
|
+
"asset",
|
|
14611
|
+
"extra"
|
|
14612
|
+
]
|
|
14613
|
+
}]
|
|
14614
|
+
}
|
|
14615
|
+
},
|
|
14616
|
+
"required": [
|
|
14617
|
+
"id",
|
|
14618
|
+
"status",
|
|
14619
|
+
"network",
|
|
14620
|
+
"asset",
|
|
14621
|
+
"amount",
|
|
14622
|
+
"pay_to",
|
|
14623
|
+
"nonce_binding",
|
|
14624
|
+
"expires_at"
|
|
14625
|
+
]
|
|
14626
|
+
},
|
|
14627
|
+
"sdkName": "createChallenge",
|
|
14628
|
+
"summary": "Create a payment challenge",
|
|
14629
|
+
"tag": "Payments",
|
|
14630
|
+
"tagCommand": "payments"
|
|
14631
|
+
},
|
|
14632
|
+
{
|
|
14633
|
+
"binaryResponse": false,
|
|
14634
|
+
"bodyRequired": false,
|
|
14635
|
+
"command": "get-challenge",
|
|
14636
|
+
"description": "Fetch a challenge you created, to poll its `status` and settlement\nreceipt (`settle_tx`). Scoped to the challenger org that created it.\n",
|
|
14637
|
+
"hasJsonBody": false,
|
|
14638
|
+
"method": "GET",
|
|
14639
|
+
"operationId": "getChallenge",
|
|
14640
|
+
"path": "/x402/challenges/{id}",
|
|
14641
|
+
"pathParams": [{
|
|
14642
|
+
"description": "Resource UUID",
|
|
14643
|
+
"enum": null,
|
|
14644
|
+
"name": "id",
|
|
14645
|
+
"required": true,
|
|
14646
|
+
"type": "string"
|
|
14647
|
+
}],
|
|
14648
|
+
"queryParams": [],
|
|
14649
|
+
"requestSchema": null,
|
|
14650
|
+
"responseSchema": {
|
|
14651
|
+
"type": "object",
|
|
14652
|
+
"properties": {
|
|
14653
|
+
"id": {
|
|
14654
|
+
"type": "string",
|
|
14655
|
+
"format": "uuid"
|
|
14656
|
+
},
|
|
14657
|
+
"status": {
|
|
14658
|
+
"type": "string",
|
|
14659
|
+
"enum": [
|
|
14660
|
+
"pending",
|
|
14661
|
+
"settling",
|
|
14662
|
+
"settled",
|
|
14663
|
+
"failed",
|
|
14664
|
+
"expired"
|
|
14665
|
+
]
|
|
14666
|
+
},
|
|
14667
|
+
"network": {
|
|
14668
|
+
"type": "string",
|
|
14669
|
+
"enum": ["base", "base-sepolia"]
|
|
14670
|
+
},
|
|
14671
|
+
"asset": {
|
|
14672
|
+
"type": "string",
|
|
14673
|
+
"description": "Token contract address (checksummed)."
|
|
14674
|
+
},
|
|
14675
|
+
"amount": {
|
|
14676
|
+
"type": "string",
|
|
14677
|
+
"description": "Amount in token base units."
|
|
14678
|
+
},
|
|
14679
|
+
"pay_to": {
|
|
14680
|
+
"type": "string",
|
|
14681
|
+
"description": "The payee's resolved payout address (checksummed)."
|
|
14682
|
+
},
|
|
14683
|
+
"payer_org": {
|
|
14684
|
+
"type": ["string", "null"],
|
|
14685
|
+
"description": "The org id bound as payer, if one was set at creation."
|
|
14686
|
+
},
|
|
14687
|
+
"resource": { "type": ["string", "null"] },
|
|
14688
|
+
"description": { "type": ["string", "null"] },
|
|
14689
|
+
"nonce_binding": {
|
|
14690
|
+
"type": "object",
|
|
14691
|
+
"description": "The interaction binding the payer hashes into the EIP-3009 nonce\n(`deriveEip3009Nonce`). Pinning the nonce to this binding is what lets an\nx402 payment ride asynchronous transports safely: a replayed challenge\ncan't redirect funds and a signed payment can't settle twice.\n",
|
|
14692
|
+
"properties": {
|
|
14693
|
+
"interaction_id": {
|
|
14694
|
+
"type": "string",
|
|
14695
|
+
"description": "Interaction id, including its `@domain` part."
|
|
14696
|
+
},
|
|
14697
|
+
"challenge_step_id": {
|
|
14698
|
+
"type": "string",
|
|
14699
|
+
"format": "uuid"
|
|
14700
|
+
},
|
|
14701
|
+
"challenge_nonce": {
|
|
14702
|
+
"type": "string",
|
|
14703
|
+
"pattern": "^[0-9a-f]{64}$",
|
|
14704
|
+
"description": "32 random bytes as 64 lowercase hex chars."
|
|
14705
|
+
}
|
|
14706
|
+
},
|
|
14707
|
+
"required": [
|
|
14708
|
+
"interaction_id",
|
|
14709
|
+
"challenge_step_id",
|
|
14710
|
+
"challenge_nonce"
|
|
14711
|
+
]
|
|
14712
|
+
},
|
|
14713
|
+
"settle_tx": {
|
|
14714
|
+
"type": ["string", "null"],
|
|
14715
|
+
"description": "On-chain settlement transaction hash once settled."
|
|
14716
|
+
},
|
|
14717
|
+
"settled_at": {
|
|
14718
|
+
"type": ["string", "null"],
|
|
14719
|
+
"format": "date-time"
|
|
14720
|
+
},
|
|
14721
|
+
"failure_reason": { "type": ["string", "null"] },
|
|
14722
|
+
"expires_at": {
|
|
14723
|
+
"type": "string",
|
|
14724
|
+
"format": "date-time"
|
|
14725
|
+
},
|
|
14726
|
+
"created_at": {
|
|
14727
|
+
"type": "string",
|
|
14728
|
+
"format": "date-time"
|
|
14729
|
+
},
|
|
14730
|
+
"payment_requirements": {
|
|
14731
|
+
"description": "Present on the create response. Hand the whole challenge (including\nthis) to the payer; `getChallenge` omits it (it is for status polling\nby the challenger).\n",
|
|
14732
|
+
"allOf": [{
|
|
14733
|
+
"type": "object",
|
|
14734
|
+
"description": "The x402 `PaymentRequirements` the payer signs over. Field names are\nx402's native camelCase, preserved byte-for-byte.\n",
|
|
14735
|
+
"properties": {
|
|
14736
|
+
"scheme": {
|
|
14737
|
+
"type": "string",
|
|
14738
|
+
"description": "The x402 settlement scheme. Always `exact` for v1.",
|
|
14739
|
+
"example": "exact"
|
|
14740
|
+
},
|
|
14741
|
+
"network": {
|
|
14742
|
+
"type": "string",
|
|
14743
|
+
"enum": ["base", "base-sepolia"]
|
|
14744
|
+
},
|
|
14745
|
+
"maxAmountRequired": {
|
|
14746
|
+
"type": "string",
|
|
14747
|
+
"description": "Amount in token base units."
|
|
14748
|
+
},
|
|
14749
|
+
"payTo": {
|
|
14750
|
+
"type": "string",
|
|
14751
|
+
"description": "The payee's resolved payout address (checksummed)."
|
|
14752
|
+
},
|
|
14753
|
+
"asset": {
|
|
14754
|
+
"type": "string",
|
|
14755
|
+
"description": "The token contract address (checksummed). USDC."
|
|
14756
|
+
},
|
|
14757
|
+
"resource": { "type": "string" },
|
|
14758
|
+
"description": { "type": "string" },
|
|
14759
|
+
"maxTimeoutSeconds": { "type": "integer" },
|
|
14760
|
+
"extra": {
|
|
14761
|
+
"type": "object",
|
|
14762
|
+
"description": "The token's load-bearing EIP-712 domain params. `name` differs by\nchain (Base mainnet USDC is `USD Coin`, Base Sepolia is `USDC`); a\nwrong value produces a signature the verifier rejects.\n",
|
|
14763
|
+
"properties": {
|
|
14764
|
+
"name": { "type": "string" },
|
|
14765
|
+
"version": { "type": "string" }
|
|
14766
|
+
},
|
|
14767
|
+
"required": ["name", "version"]
|
|
14768
|
+
}
|
|
14769
|
+
},
|
|
14770
|
+
"required": [
|
|
14771
|
+
"scheme",
|
|
14772
|
+
"network",
|
|
14773
|
+
"maxAmountRequired",
|
|
14774
|
+
"payTo",
|
|
14775
|
+
"asset",
|
|
14776
|
+
"extra"
|
|
14777
|
+
]
|
|
14778
|
+
}]
|
|
14779
|
+
}
|
|
14780
|
+
},
|
|
14781
|
+
"required": [
|
|
14782
|
+
"id",
|
|
14783
|
+
"status",
|
|
14784
|
+
"network",
|
|
14785
|
+
"asset",
|
|
14786
|
+
"amount",
|
|
14787
|
+
"pay_to",
|
|
14788
|
+
"nonce_binding",
|
|
14789
|
+
"expires_at"
|
|
14790
|
+
]
|
|
14791
|
+
},
|
|
14792
|
+
"sdkName": "getChallenge",
|
|
14793
|
+
"summary": "Get a payment challenge",
|
|
14794
|
+
"tag": "Payments",
|
|
14795
|
+
"tagCommand": "payments"
|
|
14796
|
+
},
|
|
14797
|
+
{
|
|
14798
|
+
"binaryResponse": false,
|
|
14799
|
+
"bodyRequired": false,
|
|
14800
|
+
"command": "get-spend-policy",
|
|
14801
|
+
"description": "Read your org's outbound spend policy: the kill-switch, per-payment and\nper-day caps, and the payee allowlist. Returns the defaults (no limits,\nnot paused) when no policy has been set.\n",
|
|
14802
|
+
"hasJsonBody": false,
|
|
14803
|
+
"method": "GET",
|
|
14804
|
+
"operationId": "getSpendPolicy",
|
|
14805
|
+
"path": "/x402/spend-policy",
|
|
14806
|
+
"pathParams": [],
|
|
14807
|
+
"queryParams": [],
|
|
14808
|
+
"requestSchema": null,
|
|
14809
|
+
"responseSchema": {
|
|
14810
|
+
"type": "object",
|
|
14811
|
+
"description": "The payer's outbound spend policy. Returned with defaults (not paused,\nno caps, any on-net payee) when none is set.\n",
|
|
14812
|
+
"properties": {
|
|
14813
|
+
"paused": {
|
|
14814
|
+
"type": "boolean",
|
|
14815
|
+
"description": "Kill-switch. When true, all outbound payments are refused."
|
|
14816
|
+
},
|
|
14817
|
+
"max_per_payment": {
|
|
14818
|
+
"type": ["string", "null"],
|
|
14819
|
+
"description": "Per-payment cap in token base units, or null for no cap."
|
|
14820
|
+
},
|
|
14821
|
+
"max_per_day": {
|
|
14822
|
+
"type": ["string", "null"],
|
|
14823
|
+
"description": "Rolling-day cap in token base units, or null for no cap."
|
|
14824
|
+
},
|
|
14825
|
+
"allowlist": {
|
|
14826
|
+
"type": ["array", "null"],
|
|
14827
|
+
"items": {
|
|
14828
|
+
"type": "string",
|
|
14829
|
+
"format": "uuid"
|
|
14830
|
+
},
|
|
14831
|
+
"description": "Allowed payee org ids. `null` allows any on-net payee; `[]` denies\nall.\n"
|
|
14832
|
+
}
|
|
14833
|
+
},
|
|
14834
|
+
"required": [
|
|
14835
|
+
"paused",
|
|
14836
|
+
"max_per_payment",
|
|
14837
|
+
"max_per_day",
|
|
14838
|
+
"allowlist"
|
|
14839
|
+
]
|
|
14840
|
+
},
|
|
14841
|
+
"sdkName": "getSpendPolicy",
|
|
14842
|
+
"summary": "Get your spend policy",
|
|
14843
|
+
"tag": "Payments",
|
|
14844
|
+
"tagCommand": "payments"
|
|
14845
|
+
},
|
|
14846
|
+
{
|
|
14847
|
+
"binaryResponse": false,
|
|
14848
|
+
"bodyRequired": false,
|
|
14849
|
+
"command": "list-declined-payments",
|
|
14850
|
+
"description": "The 50 most recent payments your org's spend policy declined, newest\nfirst. Use this to see why an outbound payment was refused (a cap, the\npayee allowlist, or the kill-switch) instead of only reading the\ndashboard.\n",
|
|
14851
|
+
"hasJsonBody": false,
|
|
14852
|
+
"method": "GET",
|
|
14853
|
+
"operationId": "listDeclinedPayments",
|
|
14854
|
+
"path": "/x402/declined-payments",
|
|
14855
|
+
"pathParams": [],
|
|
14856
|
+
"queryParams": [],
|
|
14857
|
+
"requestSchema": null,
|
|
14858
|
+
"responseSchema": {
|
|
14859
|
+
"type": "array",
|
|
14860
|
+
"items": {
|
|
14861
|
+
"type": "object",
|
|
14862
|
+
"description": "A payment the org's spend policy refused.",
|
|
14863
|
+
"properties": {
|
|
14864
|
+
"id": {
|
|
14865
|
+
"type": "string",
|
|
14866
|
+
"format": "uuid"
|
|
14867
|
+
},
|
|
14868
|
+
"challenge_id": {
|
|
14869
|
+
"type": ["string", "null"],
|
|
14870
|
+
"format": "uuid",
|
|
14871
|
+
"description": "The challenge that was declined, if still present."
|
|
14872
|
+
},
|
|
14873
|
+
"counterparty_org": {
|
|
14874
|
+
"type": ["string", "null"],
|
|
14875
|
+
"format": "uuid",
|
|
14876
|
+
"description": "The payee (challenger) org, when known."
|
|
14877
|
+
},
|
|
14878
|
+
"network": {
|
|
14879
|
+
"type": "string",
|
|
14880
|
+
"enum": ["base", "base-sepolia"]
|
|
14881
|
+
},
|
|
14882
|
+
"amount": {
|
|
14883
|
+
"type": "string",
|
|
14884
|
+
"description": "Amount in token base units."
|
|
14885
|
+
},
|
|
14886
|
+
"reason": {
|
|
14887
|
+
"type": "string",
|
|
14888
|
+
"description": "Why the payment was declined (cap, allowlist, paused)."
|
|
14889
|
+
},
|
|
14890
|
+
"declined_at": {
|
|
14891
|
+
"type": "string",
|
|
14892
|
+
"format": "date-time"
|
|
14893
|
+
}
|
|
14894
|
+
},
|
|
14895
|
+
"required": [
|
|
14896
|
+
"id",
|
|
14897
|
+
"network",
|
|
14898
|
+
"amount",
|
|
14899
|
+
"reason",
|
|
14900
|
+
"declined_at"
|
|
14901
|
+
]
|
|
14902
|
+
}
|
|
14903
|
+
},
|
|
14904
|
+
"sdkName": "listDeclinedPayments",
|
|
14905
|
+
"summary": "List declined payments",
|
|
14906
|
+
"tag": "Payments",
|
|
14907
|
+
"tagCommand": "payments"
|
|
14908
|
+
},
|
|
14909
|
+
{
|
|
14910
|
+
"binaryResponse": false,
|
|
14911
|
+
"bodyRequired": false,
|
|
14912
|
+
"command": "list-payout-addresses",
|
|
14913
|
+
"description": "List your org's registered payout addresses, newest first.",
|
|
14914
|
+
"hasJsonBody": false,
|
|
14915
|
+
"method": "GET",
|
|
14916
|
+
"operationId": "listPayoutAddresses",
|
|
14917
|
+
"path": "/x402/payout-addresses",
|
|
14918
|
+
"pathParams": [],
|
|
14919
|
+
"queryParams": [],
|
|
14920
|
+
"requestSchema": null,
|
|
14921
|
+
"responseSchema": {
|
|
14922
|
+
"type": "array",
|
|
14923
|
+
"items": {
|
|
14924
|
+
"type": "object",
|
|
14925
|
+
"properties": {
|
|
14926
|
+
"id": {
|
|
14927
|
+
"type": "string",
|
|
14928
|
+
"format": "uuid"
|
|
14929
|
+
},
|
|
14930
|
+
"address": {
|
|
14931
|
+
"type": "string",
|
|
14932
|
+
"description": "The checksummed payout address."
|
|
14933
|
+
},
|
|
14934
|
+
"network": {
|
|
14935
|
+
"type": "string",
|
|
14936
|
+
"enum": ["base", "base-sepolia"]
|
|
14937
|
+
},
|
|
14938
|
+
"label": { "type": ["string", "null"] },
|
|
14939
|
+
"is_default": {
|
|
14940
|
+
"type": "boolean",
|
|
14941
|
+
"description": "Exactly one address per (org, network) is the default."
|
|
14942
|
+
},
|
|
14943
|
+
"verified_at": {
|
|
14944
|
+
"type": "string",
|
|
14945
|
+
"format": "date-time",
|
|
14946
|
+
"description": "When ownership of the address was last proven."
|
|
14947
|
+
},
|
|
14948
|
+
"created_at": {
|
|
14949
|
+
"type": "string",
|
|
14950
|
+
"format": "date-time"
|
|
14951
|
+
}
|
|
14952
|
+
},
|
|
14953
|
+
"required": [
|
|
14954
|
+
"id",
|
|
14955
|
+
"address",
|
|
14956
|
+
"network",
|
|
14957
|
+
"label",
|
|
14958
|
+
"is_default",
|
|
14959
|
+
"verified_at"
|
|
14960
|
+
]
|
|
14961
|
+
}
|
|
14962
|
+
},
|
|
14963
|
+
"sdkName": "listPayoutAddresses",
|
|
14964
|
+
"summary": "List payout addresses",
|
|
14965
|
+
"tag": "Payments",
|
|
14966
|
+
"tagCommand": "payments"
|
|
14967
|
+
},
|
|
14968
|
+
{
|
|
14969
|
+
"binaryResponse": false,
|
|
14970
|
+
"bodyRequired": true,
|
|
14971
|
+
"command": "pay-challenge",
|
|
14972
|
+
"description": "Settle a challenge addressed to your org as payer. The request body\ncarries a signed x402 `PaymentPayload`: an EIP-3009\n`transferWithAuthorization` signed locally with your own key, whose nonce\nis bound to the challenge via the SDK's `deriveEip3009Nonce`. The platform\nverifies every signed field against its own record of the challenge,\napplies your spend policy, and settles on-chain through a facilitator.\nSettlement is non-custodial; Primitive never holds funds. Idempotent:\npaying an already-settled challenge returns the original receipt. Most\ncallers use the SDK `pay()` helper rather than building the payload by\nhand.\n",
|
|
14973
|
+
"hasJsonBody": true,
|
|
14974
|
+
"method": "POST",
|
|
14975
|
+
"operationId": "payChallenge",
|
|
14976
|
+
"path": "/x402/challenges/{id}/pay",
|
|
14977
|
+
"pathParams": [{
|
|
14978
|
+
"description": "Resource UUID",
|
|
14979
|
+
"enum": null,
|
|
14980
|
+
"name": "id",
|
|
14981
|
+
"required": true,
|
|
14982
|
+
"type": "string"
|
|
14983
|
+
}],
|
|
14984
|
+
"queryParams": [],
|
|
14985
|
+
"requestSchema": {
|
|
14986
|
+
"type": "object",
|
|
14987
|
+
"additionalProperties": false,
|
|
14988
|
+
"properties": { "payment": {
|
|
14989
|
+
"type": "object",
|
|
14990
|
+
"description": "A signed x402 v1 `PaymentPayload`. The SDK `pay()` helper builds this;\ncallers rarely construct it by hand. Field names are x402-native.\n",
|
|
14991
|
+
"properties": {
|
|
14992
|
+
"x402Version": {
|
|
14993
|
+
"type": "integer",
|
|
14994
|
+
"const": 1
|
|
14995
|
+
},
|
|
14996
|
+
"scheme": {
|
|
14997
|
+
"type": "string",
|
|
14998
|
+
"const": "exact"
|
|
14999
|
+
},
|
|
15000
|
+
"network": {
|
|
15001
|
+
"type": "string",
|
|
15002
|
+
"enum": ["base", "base-sepolia"]
|
|
15003
|
+
},
|
|
15004
|
+
"payload": {
|
|
15005
|
+
"type": "object",
|
|
15006
|
+
"properties": {
|
|
15007
|
+
"signature": {
|
|
15008
|
+
"type": "string",
|
|
15009
|
+
"pattern": "^0x[0-9a-fA-F]+$",
|
|
15010
|
+
"description": "The EIP-712 signature over the authorization."
|
|
15011
|
+
},
|
|
15012
|
+
"authorization": {
|
|
15013
|
+
"type": "object",
|
|
15014
|
+
"description": "The EIP-3009 `transferWithAuthorization` fields, as strings.",
|
|
15015
|
+
"properties": {
|
|
15016
|
+
"from": { "type": "string" },
|
|
15017
|
+
"to": { "type": "string" },
|
|
15018
|
+
"value": { "type": "string" },
|
|
15019
|
+
"validAfter": { "type": "string" },
|
|
15020
|
+
"validBefore": { "type": "string" },
|
|
15021
|
+
"nonce": { "type": "string" }
|
|
15022
|
+
},
|
|
15023
|
+
"required": [
|
|
15024
|
+
"from",
|
|
15025
|
+
"to",
|
|
15026
|
+
"value",
|
|
15027
|
+
"validAfter",
|
|
15028
|
+
"validBefore",
|
|
15029
|
+
"nonce"
|
|
15030
|
+
]
|
|
15031
|
+
}
|
|
15032
|
+
},
|
|
15033
|
+
"required": ["signature", "authorization"]
|
|
15034
|
+
}
|
|
15035
|
+
},
|
|
15036
|
+
"required": [
|
|
15037
|
+
"x402Version",
|
|
15038
|
+
"scheme",
|
|
15039
|
+
"network",
|
|
15040
|
+
"payload"
|
|
15041
|
+
]
|
|
15042
|
+
} },
|
|
15043
|
+
"required": ["payment"]
|
|
15044
|
+
},
|
|
15045
|
+
"responseSchema": {
|
|
15046
|
+
"type": "object",
|
|
15047
|
+
"properties": {
|
|
15048
|
+
"id": {
|
|
15049
|
+
"type": "string",
|
|
15050
|
+
"format": "uuid"
|
|
15051
|
+
},
|
|
15052
|
+
"status": {
|
|
15053
|
+
"type": "string",
|
|
15054
|
+
"enum": ["settled"]
|
|
15055
|
+
},
|
|
15056
|
+
"settle_tx": {
|
|
15057
|
+
"type": ["string", "null"],
|
|
15058
|
+
"description": "On-chain settlement transaction hash."
|
|
15059
|
+
}
|
|
15060
|
+
},
|
|
15061
|
+
"required": [
|
|
15062
|
+
"id",
|
|
15063
|
+
"status",
|
|
15064
|
+
"settle_tx"
|
|
15065
|
+
]
|
|
15066
|
+
},
|
|
15067
|
+
"sdkName": "payChallenge",
|
|
15068
|
+
"summary": "Pay a payment challenge",
|
|
15069
|
+
"tag": "Payments",
|
|
15070
|
+
"tagCommand": "payments"
|
|
15071
|
+
},
|
|
15072
|
+
{
|
|
15073
|
+
"binaryResponse": false,
|
|
15074
|
+
"bodyRequired": true,
|
|
15075
|
+
"command": "register-payout-address",
|
|
15076
|
+
"description": "Register (or update) the default payout address your org receives x402\npayments at, for a given network. You prove control of the address with\nan org-bound `personal_sign` signature over the message produced by the\nSDK helper `buildPayoutRegistrationMessage`. The org id is taken from your\nauthenticated key, never the body, so a captured signature can't register\nan address under another org. Exactly one default address exists per\n(org, network); registering again replaces it. A payee MUST register a\npayout address before calling `createChallenge`, because the challenge's\n`pay_to` is resolved from this directory.\n",
|
|
15077
|
+
"hasJsonBody": true,
|
|
15078
|
+
"method": "POST",
|
|
15079
|
+
"operationId": "registerPayoutAddress",
|
|
15080
|
+
"path": "/x402/payout-addresses",
|
|
15081
|
+
"pathParams": [],
|
|
15082
|
+
"queryParams": [],
|
|
15083
|
+
"requestSchema": {
|
|
15084
|
+
"type": "object",
|
|
15085
|
+
"additionalProperties": false,
|
|
15086
|
+
"properties": {
|
|
15087
|
+
"address": {
|
|
15088
|
+
"type": "string",
|
|
15089
|
+
"pattern": "^0x[0-9a-fA-F]{40}$",
|
|
15090
|
+
"description": "The payout address (your signer's own EVM address), 0x-prefixed."
|
|
15091
|
+
},
|
|
15092
|
+
"network": {
|
|
15093
|
+
"type": "string",
|
|
15094
|
+
"enum": ["base", "base-sepolia"],
|
|
15095
|
+
"description": "The chain the address receives on."
|
|
15096
|
+
},
|
|
15097
|
+
"signature": {
|
|
15098
|
+
"type": "string",
|
|
15099
|
+
"pattern": "^0x[0-9a-fA-F]+$",
|
|
15100
|
+
"description": "A `personal_sign` signature over the org-bound message produced by\nthe SDK helper `buildPayoutRegistrationMessage`. Recovered and\nchecked against `address`; the org id is bound into the signed bytes.\n"
|
|
15101
|
+
},
|
|
15102
|
+
"issued_at": {
|
|
15103
|
+
"type": "string",
|
|
15104
|
+
"format": "date-time",
|
|
15105
|
+
"description": "ISO-8601 timestamp embedded in the signed message. Must be within a\nshort freshness window (about 10 minutes) of server time.\n"
|
|
15106
|
+
},
|
|
15107
|
+
"label": {
|
|
15108
|
+
"type": "string",
|
|
15109
|
+
"maxLength": 80,
|
|
15110
|
+
"description": "Optional human-readable label."
|
|
15111
|
+
}
|
|
15112
|
+
},
|
|
15113
|
+
"required": [
|
|
15114
|
+
"address",
|
|
15115
|
+
"network",
|
|
15116
|
+
"signature",
|
|
15117
|
+
"issued_at"
|
|
15118
|
+
]
|
|
15119
|
+
},
|
|
15120
|
+
"responseSchema": {
|
|
15121
|
+
"type": "object",
|
|
15122
|
+
"properties": {
|
|
15123
|
+
"id": {
|
|
15124
|
+
"type": "string",
|
|
15125
|
+
"format": "uuid"
|
|
15126
|
+
},
|
|
15127
|
+
"address": {
|
|
15128
|
+
"type": "string",
|
|
15129
|
+
"description": "The checksummed payout address."
|
|
15130
|
+
},
|
|
15131
|
+
"network": {
|
|
15132
|
+
"type": "string",
|
|
15133
|
+
"enum": ["base", "base-sepolia"]
|
|
15134
|
+
},
|
|
15135
|
+
"label": { "type": ["string", "null"] },
|
|
15136
|
+
"is_default": {
|
|
15137
|
+
"type": "boolean",
|
|
15138
|
+
"description": "Exactly one address per (org, network) is the default."
|
|
15139
|
+
},
|
|
15140
|
+
"verified_at": {
|
|
15141
|
+
"type": "string",
|
|
15142
|
+
"format": "date-time",
|
|
15143
|
+
"description": "When ownership of the address was last proven."
|
|
15144
|
+
},
|
|
15145
|
+
"created_at": {
|
|
15146
|
+
"type": "string",
|
|
15147
|
+
"format": "date-time"
|
|
15148
|
+
}
|
|
15149
|
+
},
|
|
15150
|
+
"required": [
|
|
15151
|
+
"id",
|
|
15152
|
+
"address",
|
|
15153
|
+
"network",
|
|
15154
|
+
"label",
|
|
15155
|
+
"is_default",
|
|
15156
|
+
"verified_at"
|
|
15157
|
+
]
|
|
15158
|
+
},
|
|
15159
|
+
"sdkName": "registerPayoutAddress",
|
|
15160
|
+
"summary": "Register a payout address",
|
|
15161
|
+
"tag": "Payments",
|
|
15162
|
+
"tagCommand": "payments"
|
|
15163
|
+
},
|
|
15164
|
+
{
|
|
15165
|
+
"binaryResponse": false,
|
|
15166
|
+
"bodyRequired": true,
|
|
15167
|
+
"command": "update-spend-policy",
|
|
15168
|
+
"description": "Update your org's spend policy. Applied as a merge: only the fields you\ninclude change, and omitted fields keep their current value, so a partial\nupdate can't silently reset the kill-switch. Send an explicit `null` to\nclear a cap. Caps are in token base units.\n",
|
|
15169
|
+
"hasJsonBody": true,
|
|
15170
|
+
"method": "PUT",
|
|
15171
|
+
"operationId": "updateSpendPolicy",
|
|
15172
|
+
"path": "/x402/spend-policy",
|
|
15173
|
+
"pathParams": [],
|
|
15174
|
+
"queryParams": [],
|
|
15175
|
+
"requestSchema": {
|
|
15176
|
+
"type": "object",
|
|
15177
|
+
"additionalProperties": false,
|
|
15178
|
+
"description": "Merge update: only the fields you include change; omit a field to keep\nits current value; send `null` to clear a cap.\n",
|
|
15179
|
+
"properties": {
|
|
15180
|
+
"paused": { "type": "boolean" },
|
|
15181
|
+
"max_per_payment": {
|
|
15182
|
+
"type": ["string", "null"],
|
|
15183
|
+
"pattern": "^[1-9][0-9]{0,38}$"
|
|
15184
|
+
},
|
|
15185
|
+
"max_per_day": {
|
|
15186
|
+
"type": ["string", "null"],
|
|
15187
|
+
"pattern": "^[1-9][0-9]{0,38}$"
|
|
15188
|
+
},
|
|
15189
|
+
"allowlist": {
|
|
15190
|
+
"type": ["array", "null"],
|
|
15191
|
+
"maxItems": 1e3,
|
|
15192
|
+
"items": {
|
|
15193
|
+
"type": "string",
|
|
15194
|
+
"format": "uuid"
|
|
15195
|
+
}
|
|
15196
|
+
}
|
|
15197
|
+
}
|
|
15198
|
+
},
|
|
15199
|
+
"responseSchema": {
|
|
15200
|
+
"type": "object",
|
|
15201
|
+
"description": "The payer's outbound spend policy. Returned with defaults (not paused,\nno caps, any on-net payee) when none is set.\n",
|
|
15202
|
+
"properties": {
|
|
15203
|
+
"paused": {
|
|
15204
|
+
"type": "boolean",
|
|
15205
|
+
"description": "Kill-switch. When true, all outbound payments are refused."
|
|
15206
|
+
},
|
|
15207
|
+
"max_per_payment": {
|
|
15208
|
+
"type": ["string", "null"],
|
|
15209
|
+
"description": "Per-payment cap in token base units, or null for no cap."
|
|
13097
15210
|
},
|
|
13098
|
-
"
|
|
13099
|
-
"type": "
|
|
13100
|
-
"
|
|
13101
|
-
"properties": {
|
|
13102
|
-
"total": { "type": "integer" },
|
|
13103
|
-
"deployed": { "type": "integer" },
|
|
13104
|
-
"pending": { "type": "integer" },
|
|
13105
|
-
"failed": { "type": "integer" }
|
|
13106
|
-
},
|
|
13107
|
-
"required": [
|
|
13108
|
-
"total",
|
|
13109
|
-
"deployed",
|
|
13110
|
-
"pending",
|
|
13111
|
-
"failed"
|
|
13112
|
-
]
|
|
15211
|
+
"max_per_day": {
|
|
15212
|
+
"type": ["string", "null"],
|
|
15213
|
+
"description": "Rolling-day cap in token base units, or null for no cap."
|
|
13113
15214
|
},
|
|
13114
|
-
"
|
|
13115
|
-
"type": "
|
|
13116
|
-
"
|
|
13117
|
-
|
|
13118
|
-
|
|
13119
|
-
"total": {
|
|
13120
|
-
"type": "integer",
|
|
13121
|
-
"description": "Number of inbound emails received in the last 30 days."
|
|
13122
|
-
},
|
|
13123
|
-
"latest_received_at": {
|
|
13124
|
-
"type": ["string", "null"],
|
|
13125
|
-
"format": "date-time",
|
|
13126
|
-
"description": "Most recent inbound email received in the last 30 days."
|
|
13127
|
-
}
|
|
15215
|
+
"allowlist": {
|
|
15216
|
+
"type": ["array", "null"],
|
|
15217
|
+
"items": {
|
|
15218
|
+
"type": "string",
|
|
15219
|
+
"format": "uuid"
|
|
13128
15220
|
},
|
|
13129
|
-
"
|
|
15221
|
+
"description": "Allowed payee org ids. `null` allows any on-net payee; `[]` denies\nall.\n"
|
|
13130
15222
|
}
|
|
13131
15223
|
},
|
|
13132
15224
|
"required": [
|
|
13133
|
-
"
|
|
13134
|
-
"
|
|
13135
|
-
"
|
|
13136
|
-
"
|
|
13137
|
-
"next_actions",
|
|
13138
|
-
"domains",
|
|
13139
|
-
"endpoints",
|
|
13140
|
-
"functions",
|
|
13141
|
-
"recent_emails"
|
|
15225
|
+
"paused",
|
|
15226
|
+
"max_per_payment",
|
|
15227
|
+
"max_per_day",
|
|
15228
|
+
"allowlist"
|
|
13142
15229
|
]
|
|
13143
15230
|
},
|
|
13144
|
-
"sdkName": "
|
|
13145
|
-
"summary": "
|
|
13146
|
-
"tag": "
|
|
13147
|
-
"tagCommand": "
|
|
15231
|
+
"sdkName": "updateSpendPolicy",
|
|
15232
|
+
"summary": "Update your spend policy",
|
|
15233
|
+
"tag": "Payments",
|
|
15234
|
+
"tagCommand": "payments"
|
|
13148
15235
|
},
|
|
13149
15236
|
{
|
|
13150
15237
|
"binaryResponse": false,
|
|
@@ -18933,8 +21020,8 @@ const PRIMITIVE_TEAM_AUTHOR = {
|
|
|
18933
21020
|
name: "Primitive Team",
|
|
18934
21021
|
url: "https://primitive.dev"
|
|
18935
21022
|
};
|
|
18936
|
-
const SDK_VERSION_RANGE = "^1.
|
|
18937
|
-
const CLI_VERSION_RANGE = "^1.
|
|
21023
|
+
const SDK_VERSION_RANGE = "^1.6.0";
|
|
21024
|
+
const CLI_VERSION_RANGE = "^1.6.0";
|
|
18938
21025
|
const ESBUILD_VERSION_RANGE = "^0.27.0";
|
|
18939
21026
|
function renderHandler() {
|
|
18940
21027
|
return `// env.PRIMITIVE_API_KEY, env.PRIMITIVE_WEBHOOK_SECRET, and
|
|
@@ -22324,6 +24411,392 @@ var OrgSecretsSetCommand = class OrgSecretsSetCommand extends Command {
|
|
|
22324
24411
|
}
|
|
22325
24412
|
};
|
|
22326
24413
|
//#endregion
|
|
24414
|
+
//#region src/oclif/commands/payments-shared.ts
|
|
24415
|
+
const PRIVATE_KEY_ENV = "PRIMITIVE_X402_PRIVATE_KEY";
|
|
24416
|
+
const PRIVATE_KEY_FLAG_DESCRIPTION = `Hex private key (0x-prefixed) of the wallet that signs. Prefer the ${PRIVATE_KEY_ENV} environment variable so the key is not exposed in shell history or the process list. The key is used locally to sign and never sent to Primitive.`;
|
|
24417
|
+
function x402BaseUrl(resolvedApiBaseUrl) {
|
|
24418
|
+
return resolvedApiBaseUrl.replace(/\/v1\/?$/, "");
|
|
24419
|
+
}
|
|
24420
|
+
/**
|
|
24421
|
+
* Build the x402 signing client. Returns null (after writing a hint) when no
|
|
24422
|
+
* API key resolved, so a not-signed-in caller gets the same guidance as any
|
|
24423
|
+
* other command rather than an opaque "no API key" throw from the SDK.
|
|
24424
|
+
*/
|
|
24425
|
+
function buildX402Client(params) {
|
|
24426
|
+
if (!params.apiKey) {
|
|
24427
|
+
process.stderr.write("Not signed in. Set PRIMITIVE_API_KEY or run `primitive signin`, then retry.\n");
|
|
24428
|
+
return null;
|
|
24429
|
+
}
|
|
24430
|
+
return createX402Client({
|
|
24431
|
+
apiKey: params.apiKey,
|
|
24432
|
+
baseUrl: x402BaseUrl(params.resolvedApiBaseUrl)
|
|
24433
|
+
});
|
|
24434
|
+
}
|
|
24435
|
+
const USDC_DECIMALS = 6;
|
|
24436
|
+
/**
|
|
24437
|
+
* Convert a human USDC amount ("0.01") to token base units ("10000"). Returns
|
|
24438
|
+
* null for a non-positive, malformed, or over-precise value (more than 6
|
|
24439
|
+
* fractional digits), so the caller can show a clear error instead of sending
|
|
24440
|
+
* a wrong amount.
|
|
24441
|
+
*/
|
|
24442
|
+
function usdcToBaseUnits(human) {
|
|
24443
|
+
const trimmed = human.trim();
|
|
24444
|
+
if (!/^\d+(\.\d+)?$/.test(trimmed)) return null;
|
|
24445
|
+
const [whole, frac = ""] = trimmed.split(".");
|
|
24446
|
+
if (frac.length > USDC_DECIMALS) return null;
|
|
24447
|
+
const padded = frac.padEnd(USDC_DECIMALS, "0");
|
|
24448
|
+
const base = BigInt(whole) * 10n ** BigInt(USDC_DECIMALS) + BigInt(padded);
|
|
24449
|
+
if (base <= 0n) return null;
|
|
24450
|
+
return base.toString();
|
|
24451
|
+
}
|
|
24452
|
+
/** Format token base units ("10000") back to a human USDC string ("0.01"). */
|
|
24453
|
+
function formatUsdc(baseUnits) {
|
|
24454
|
+
if (!/^\d+$/.test(baseUnits)) return baseUnits;
|
|
24455
|
+
const padded = baseUnits.padStart(USDC_DECIMALS + 1, "0");
|
|
24456
|
+
const whole = padded.slice(0, -USDC_DECIMALS);
|
|
24457
|
+
const frac = padded.slice(-USDC_DECIMALS).replace(/0+$/, "");
|
|
24458
|
+
return frac ? `${whole}.${frac}` : whole;
|
|
24459
|
+
}
|
|
24460
|
+
/** Block-explorer URL for a settlement tx, or null for an unknown network/tx. */
|
|
24461
|
+
function explorerTxUrl(network, tx) {
|
|
24462
|
+
if (!/^0x[0-9a-fA-F]{64}$/.test(tx)) return null;
|
|
24463
|
+
if (network === "base") return `https://basescan.org/tx/${tx}`;
|
|
24464
|
+
if (network === "base-sepolia") return `https://sepolia.basescan.org/tx/${tx}`;
|
|
24465
|
+
return null;
|
|
24466
|
+
}
|
|
24467
|
+
const X402_ERROR_HINTS = {
|
|
24468
|
+
no_payout_address: "Register a payout address first: `primitive payments register-payout-address --network <network>`.",
|
|
24469
|
+
feature_disabled: "x402 payments are not enabled for this organization yet.",
|
|
24470
|
+
payment_declined: "Your spend policy declined this payment. Check it with `primitive payments get-spend-policy`; if it is paused, re-enable with `primitive payments update-spend-policy --paused false`.",
|
|
24471
|
+
challenge_expired: "This challenge has expired. Ask the payee to create a new one (raise `--expires-in` when creating long-lived challenges).",
|
|
24472
|
+
settlement_failed: "On-chain settlement failed. The most common cause is insufficient USDC in the paying wallet on this network. Fund the wallet and retry.",
|
|
24473
|
+
payment_verification_failed: "The signed payment did not match the challenge. Make sure you are paying with the wallet and network the challenge was issued for.",
|
|
24474
|
+
ownership_proof_failed: "The signature did not prove control of the address. Make sure the wallet key matches the address you are registering."
|
|
24475
|
+
};
|
|
24476
|
+
/** Turn a hex private key into a viem account (a valid X402Signer). */
|
|
24477
|
+
function signerFromPrivateKey(rawKey) {
|
|
24478
|
+
const trimmed = rawKey.trim();
|
|
24479
|
+
const hex = trimmed.startsWith("0x") ? trimmed : `0x${trimmed}`;
|
|
24480
|
+
if (!/^0x[0-9a-fA-F]{64}$/.test(hex)) throw new X402Error(`private key must be 32 bytes of hex (64 hex chars, optionally 0x-prefixed); set ${PRIVATE_KEY_ENV} or pass --private-key`, 0);
|
|
24481
|
+
return privateKeyToAccount(hex);
|
|
24482
|
+
}
|
|
24483
|
+
/**
|
|
24484
|
+
* Map an X402Error onto the CLI's standard stderr error + hint surface, so a
|
|
24485
|
+
* payments failure reads like every other command's failure. Returns nothing;
|
|
24486
|
+
* the caller sets the exit code.
|
|
24487
|
+
*/
|
|
24488
|
+
function reportX402Error(error, ctx) {
|
|
24489
|
+
if (!(error instanceof X402Error)) {
|
|
24490
|
+
process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
|
|
24491
|
+
return;
|
|
24492
|
+
}
|
|
24493
|
+
const body = error.body;
|
|
24494
|
+
const payload = body && typeof body === "object" && "error" in body ? body : {
|
|
24495
|
+
success: false,
|
|
24496
|
+
error: {
|
|
24497
|
+
code: error.status === 0 ? "client_error" : "request_failed",
|
|
24498
|
+
message: error.message
|
|
24499
|
+
}
|
|
24500
|
+
};
|
|
24501
|
+
writeErrorWithHints(payload);
|
|
24502
|
+
const code = payload.error?.code;
|
|
24503
|
+
if (code && code in X402_ERROR_HINTS) process.stderr.write(`${X402_ERROR_HINTS[code]}\n`);
|
|
24504
|
+
surfaceUnauthorizedHint({
|
|
24505
|
+
auth: ctx.auth,
|
|
24506
|
+
baseUrlOverridden: ctx.baseUrlOverridden,
|
|
24507
|
+
configDir: ctx.configDir,
|
|
24508
|
+
payload
|
|
24509
|
+
});
|
|
24510
|
+
}
|
|
24511
|
+
//#endregion
|
|
24512
|
+
//#region src/oclif/commands/payments-charge.ts
|
|
24513
|
+
var PaymentsChargeCommand = class PaymentsChargeCommand extends Command {
|
|
24514
|
+
static description = `Request an x402 payment by creating a challenge (payee side).
|
|
24515
|
+
|
|
24516
|
+
Give the amount as human USDC with --amount-usdc (e.g. 0.01) or as token base
|
|
24517
|
+
units with --amount (e.g. 10000). The challenge JSON is printed to stdout;
|
|
24518
|
+
hand it to the payer (for example in an email reply) so they can pay it. The
|
|
24519
|
+
payee must have a registered payout address first.`;
|
|
24520
|
+
static summary = "Request an x402 payment (create a challenge)";
|
|
24521
|
+
static examples = [
|
|
24522
|
+
"<%= config.bin %> payments charge --amount-usdc 0.01",
|
|
24523
|
+
"<%= config.bin %> payments charge --amount 10000 --network base",
|
|
24524
|
+
"<%= config.bin %> payments charge --amount-usdc 1.50 > challenge.json"
|
|
24525
|
+
];
|
|
24526
|
+
static flags = {
|
|
24527
|
+
"api-key": Flags.string({
|
|
24528
|
+
description: "Primitive API key override (defaults to PRIMITIVE_API_KEY or saved OAuth login credentials)",
|
|
24529
|
+
env: "PRIMITIVE_API_KEY"
|
|
24530
|
+
}),
|
|
24531
|
+
"api-base-url": Flags.string({
|
|
24532
|
+
description: API_BASE_URL_FLAG_DESCRIPTION,
|
|
24533
|
+
env: "PRIMITIVE_API_BASE_URL",
|
|
24534
|
+
hidden: true
|
|
24535
|
+
}),
|
|
24536
|
+
"amount-usdc": Flags.string({
|
|
24537
|
+
description: "Amount to collect in USDC, e.g. 0.01. Converted to base units.",
|
|
24538
|
+
exclusive: ["amount"]
|
|
24539
|
+
}),
|
|
24540
|
+
amount: Flags.string({
|
|
24541
|
+
description: "Amount to collect in token base units, e.g. 10000 (0.01 USDC).",
|
|
24542
|
+
exclusive: ["amount-usdc"]
|
|
24543
|
+
}),
|
|
24544
|
+
network: Flags.string({
|
|
24545
|
+
description: "Chain to collect on.",
|
|
24546
|
+
options: ["base", "base-sepolia"],
|
|
24547
|
+
default: "base-sepolia"
|
|
24548
|
+
}),
|
|
24549
|
+
"payer-org": Flags.string({ description: "Restrict who can pay to this organization id (on-net binding)." }),
|
|
24550
|
+
description: Flags.string({ description: "Human-readable description of what the payment is for." }),
|
|
24551
|
+
resource: Flags.string({ description: "A URL identifying the thing being paid for." }),
|
|
24552
|
+
"expires-in": Flags.integer({ description: "Seconds until the challenge expires (60-86400; default 3600)." }),
|
|
24553
|
+
"idempotency-key": Flags.string({ description: "Retry-safe key: charging again with the same key returns the original challenge instead of a duplicate." }),
|
|
24554
|
+
time: Flags.boolean({ description: TIME_FLAG_DESCRIPTION })
|
|
24555
|
+
};
|
|
24556
|
+
async run() {
|
|
24557
|
+
const { flags } = await this.parse(PaymentsChargeCommand);
|
|
24558
|
+
let amount;
|
|
24559
|
+
if (flags["amount-usdc"] !== void 0) {
|
|
24560
|
+
const base = usdcToBaseUnits(flags["amount-usdc"]);
|
|
24561
|
+
if (!base) {
|
|
24562
|
+
process.stderr.write(`Invalid --amount-usdc "${flags["amount-usdc"]}". Use a positive amount with at most 6 decimals, e.g. 0.01.\n`);
|
|
24563
|
+
process.exitCode = 1;
|
|
24564
|
+
return;
|
|
24565
|
+
}
|
|
24566
|
+
amount = base;
|
|
24567
|
+
} else if (flags.amount !== void 0) amount = flags.amount;
|
|
24568
|
+
else {
|
|
24569
|
+
process.stderr.write("Provide --amount-usdc <usdc> (e.g. 0.01) or --amount <base-units> (e.g. 10000).\n");
|
|
24570
|
+
process.exitCode = 1;
|
|
24571
|
+
return;
|
|
24572
|
+
}
|
|
24573
|
+
const { auth, baseUrlOverridden, requestConfig } = await createAuthenticatedCliApiClient({
|
|
24574
|
+
apiKey: flags["api-key"],
|
|
24575
|
+
apiBaseUrl: flags["api-base-url"],
|
|
24576
|
+
configDir: this.config.configDir
|
|
24577
|
+
});
|
|
24578
|
+
await runWithTiming(flags.time, async () => {
|
|
24579
|
+
const client = buildX402Client({
|
|
24580
|
+
apiKey: auth.apiKey,
|
|
24581
|
+
resolvedApiBaseUrl: requestConfig.resolvedApiBaseUrl
|
|
24582
|
+
});
|
|
24583
|
+
if (!client) {
|
|
24584
|
+
process.exitCode = 1;
|
|
24585
|
+
return;
|
|
24586
|
+
}
|
|
24587
|
+
try {
|
|
24588
|
+
const challenge = await client.charge({
|
|
24589
|
+
amount,
|
|
24590
|
+
network: flags.network,
|
|
24591
|
+
...flags["payer-org"] ? { payerOrg: flags["payer-org"] } : {},
|
|
24592
|
+
...flags.description ? { description: flags.description } : {},
|
|
24593
|
+
...flags.resource ? { resource: flags.resource } : {},
|
|
24594
|
+
...flags["expires-in"] !== void 0 ? { expiresIn: flags["expires-in"] } : {},
|
|
24595
|
+
...flags["idempotency-key"] ? { idempotencyKey: flags["idempotency-key"] } : {}
|
|
24596
|
+
});
|
|
24597
|
+
process.stderr.write(`Challenge ${challenge.id} for ${formatUsdc(challenge.amount)} USDC on ${challenge.network}. Hand the JSON below to the payer; they settle it with \`primitive payments pay\`.\n`);
|
|
24598
|
+
this.log(JSON.stringify(challenge, null, 2));
|
|
24599
|
+
} catch (error) {
|
|
24600
|
+
reportX402Error(error, {
|
|
24601
|
+
auth,
|
|
24602
|
+
baseUrlOverridden,
|
|
24603
|
+
configDir: this.config.configDir
|
|
24604
|
+
});
|
|
24605
|
+
process.exitCode = 1;
|
|
24606
|
+
}
|
|
24607
|
+
});
|
|
24608
|
+
}
|
|
24609
|
+
};
|
|
24610
|
+
//#endregion
|
|
24611
|
+
//#region src/oclif/commands/payments-pay.ts
|
|
24612
|
+
function readChallenge(input) {
|
|
24613
|
+
let raw;
|
|
24614
|
+
if (input.inline !== void 0) raw = input.inline;
|
|
24615
|
+
else if (input.file !== void 0) raw = readFileSync(input.file, "utf8");
|
|
24616
|
+
else raw = readFileSync(0, "utf8");
|
|
24617
|
+
const trimmed = raw.trim();
|
|
24618
|
+
if (!trimmed) throw new Error("no challenge provided; pass --challenge '<json>', --challenge-file <path>, or pipe the challenge JSON on stdin");
|
|
24619
|
+
let parsed;
|
|
24620
|
+
try {
|
|
24621
|
+
parsed = JSON.parse(trimmed);
|
|
24622
|
+
} catch {
|
|
24623
|
+
throw new Error("challenge is not valid JSON");
|
|
24624
|
+
}
|
|
24625
|
+
if (parsed && typeof parsed === "object" && "data" in parsed) return parsed.data;
|
|
24626
|
+
return parsed;
|
|
24627
|
+
}
|
|
24628
|
+
var PaymentsPayCommand = class PaymentsPayCommand extends Command {
|
|
24629
|
+
static description = `Pay an x402 payment challenge.
|
|
24630
|
+
|
|
24631
|
+
Reads the challenge object the payee gave you, derives and signs the
|
|
24632
|
+
interaction-bound EIP-3009 authorization locally with your wallet key (read
|
|
24633
|
+
from ${PRIVATE_KEY_ENV} by default), and submits it for non-custodial
|
|
24634
|
+
on-chain settlement. The key never leaves your machine. Provide the challenge
|
|
24635
|
+
inline with --challenge, from a file with --challenge-file, or piped on stdin.`;
|
|
24636
|
+
static summary = "Sign and settle an x402 payment challenge";
|
|
24637
|
+
static examples = [
|
|
24638
|
+
"<%= config.bin %> payments pay --challenge-file challenge.json",
|
|
24639
|
+
"<%= config.bin %> payments pay --challenge '{\"id\":\"...\",\"network\":\"base-sepolia\",...}'",
|
|
24640
|
+
"cat challenge.json | <%= config.bin %> payments pay"
|
|
24641
|
+
];
|
|
24642
|
+
static flags = {
|
|
24643
|
+
"api-key": Flags.string({
|
|
24644
|
+
description: "Primitive API key override (defaults to PRIMITIVE_API_KEY or saved OAuth login credentials)",
|
|
24645
|
+
env: "PRIMITIVE_API_KEY"
|
|
24646
|
+
}),
|
|
24647
|
+
"api-base-url": Flags.string({
|
|
24648
|
+
description: API_BASE_URL_FLAG_DESCRIPTION,
|
|
24649
|
+
env: "PRIMITIVE_API_BASE_URL",
|
|
24650
|
+
hidden: true
|
|
24651
|
+
}),
|
|
24652
|
+
"private-key": Flags.string({
|
|
24653
|
+
description: PRIVATE_KEY_FLAG_DESCRIPTION,
|
|
24654
|
+
env: PRIVATE_KEY_ENV
|
|
24655
|
+
}),
|
|
24656
|
+
challenge: Flags.string({
|
|
24657
|
+
description: "The challenge object as a JSON string.",
|
|
24658
|
+
exclusive: ["challenge-file"]
|
|
24659
|
+
}),
|
|
24660
|
+
"challenge-file": Flags.string({
|
|
24661
|
+
description: "Path to a file containing the challenge JSON.",
|
|
24662
|
+
exclusive: ["challenge"]
|
|
24663
|
+
}),
|
|
24664
|
+
json: Flags.boolean({ description: "Print the raw receipt JSON instead of a human summary." }),
|
|
24665
|
+
time: Flags.boolean({ description: TIME_FLAG_DESCRIPTION })
|
|
24666
|
+
};
|
|
24667
|
+
async run() {
|
|
24668
|
+
const { flags } = await this.parse(PaymentsPayCommand);
|
|
24669
|
+
const { auth, baseUrlOverridden, requestConfig } = await createAuthenticatedCliApiClient({
|
|
24670
|
+
apiKey: flags["api-key"],
|
|
24671
|
+
apiBaseUrl: flags["api-base-url"],
|
|
24672
|
+
configDir: this.config.configDir
|
|
24673
|
+
});
|
|
24674
|
+
await runWithTiming(flags.time, async () => {
|
|
24675
|
+
const client = buildX402Client({
|
|
24676
|
+
apiKey: auth.apiKey,
|
|
24677
|
+
resolvedApiBaseUrl: requestConfig.resolvedApiBaseUrl
|
|
24678
|
+
});
|
|
24679
|
+
if (!client) {
|
|
24680
|
+
process.exitCode = 1;
|
|
24681
|
+
return;
|
|
24682
|
+
}
|
|
24683
|
+
try {
|
|
24684
|
+
const challenge = readChallenge({
|
|
24685
|
+
inline: flags.challenge,
|
|
24686
|
+
file: flags["challenge-file"]
|
|
24687
|
+
});
|
|
24688
|
+
const signer = signerFromPrivateKey(flags["private-key"] ?? "");
|
|
24689
|
+
const receipt = await client.pay(challenge, { signer });
|
|
24690
|
+
if (flags.json) {
|
|
24691
|
+
this.log(JSON.stringify(receipt, null, 2));
|
|
24692
|
+
return;
|
|
24693
|
+
}
|
|
24694
|
+
if (receipt.status === "settled" && receipt.settle_tx) {
|
|
24695
|
+
this.log(`Payment settled. Transaction: ${receipt.settle_tx}`);
|
|
24696
|
+
const url = explorerTxUrl(challenge.network, receipt.settle_tx);
|
|
24697
|
+
if (url) this.log(url);
|
|
24698
|
+
} else this.log(`Payment ${receipt.status}.`);
|
|
24699
|
+
} catch (error) {
|
|
24700
|
+
reportX402Error(error, {
|
|
24701
|
+
auth,
|
|
24702
|
+
baseUrlOverridden,
|
|
24703
|
+
configDir: this.config.configDir
|
|
24704
|
+
});
|
|
24705
|
+
process.exitCode = 1;
|
|
24706
|
+
}
|
|
24707
|
+
});
|
|
24708
|
+
}
|
|
24709
|
+
};
|
|
24710
|
+
//#endregion
|
|
24711
|
+
//#region src/oclif/commands/payments-register-payout-address.ts
|
|
24712
|
+
var PaymentsRegisterPayoutAddressCommand = class PaymentsRegisterPayoutAddressCommand extends Command {
|
|
24713
|
+
static description = `Register the default payout address your org receives x402 payments at.
|
|
24714
|
+
|
|
24715
|
+
Proves control of the address by signing an org-bound message locally with
|
|
24716
|
+
your wallet key (read from ${PRIVATE_KEY_ENV} by default), then registers the
|
|
24717
|
+
recovered address as the default for the chosen network. Registering again
|
|
24718
|
+
replaces the existing default. Run this before \`payments create-challenge\`.`;
|
|
24719
|
+
static summary = "Register a payout address for receiving x402 payments";
|
|
24720
|
+
static examples = ["<%= config.bin %> payments register-payout-address", "<%= config.bin %> payments register-payout-address --network base --label treasury"];
|
|
24721
|
+
static flags = {
|
|
24722
|
+
"api-key": Flags.string({
|
|
24723
|
+
description: "Primitive API key override (defaults to PRIMITIVE_API_KEY or saved OAuth login credentials)",
|
|
24724
|
+
env: "PRIMITIVE_API_KEY"
|
|
24725
|
+
}),
|
|
24726
|
+
"api-base-url": Flags.string({
|
|
24727
|
+
description: API_BASE_URL_FLAG_DESCRIPTION,
|
|
24728
|
+
env: "PRIMITIVE_API_BASE_URL",
|
|
24729
|
+
hidden: true
|
|
24730
|
+
}),
|
|
24731
|
+
"private-key": Flags.string({
|
|
24732
|
+
description: PRIVATE_KEY_FLAG_DESCRIPTION,
|
|
24733
|
+
env: PRIVATE_KEY_ENV
|
|
24734
|
+
}),
|
|
24735
|
+
network: Flags.string({
|
|
24736
|
+
description: "Chain the address receives on.",
|
|
24737
|
+
options: ["base", "base-sepolia"],
|
|
24738
|
+
default: "base-sepolia"
|
|
24739
|
+
}),
|
|
24740
|
+
label: Flags.string({ description: "Optional human-readable label for the address." }),
|
|
24741
|
+
"issued-at": Flags.string({ description: "ISO-8601 timestamp embedded in the signed message. Defaults to now. Must be within ~10 minutes of server time." }),
|
|
24742
|
+
json: Flags.boolean({ description: "Print the raw payout-address JSON instead of a human summary." }),
|
|
24743
|
+
time: Flags.boolean({ description: TIME_FLAG_DESCRIPTION })
|
|
24744
|
+
};
|
|
24745
|
+
async run() {
|
|
24746
|
+
const { flags } = await this.parse(PaymentsRegisterPayoutAddressCommand);
|
|
24747
|
+
const { apiClient, auth, baseUrlOverridden, requestConfig } = await createAuthenticatedCliApiClient({
|
|
24748
|
+
apiKey: flags["api-key"],
|
|
24749
|
+
apiBaseUrl: flags["api-base-url"],
|
|
24750
|
+
configDir: this.config.configDir
|
|
24751
|
+
});
|
|
24752
|
+
await runWithTiming(flags.time, async () => {
|
|
24753
|
+
const account = await getAccount({
|
|
24754
|
+
client: apiClient.client,
|
|
24755
|
+
responseStyle: "fields"
|
|
24756
|
+
});
|
|
24757
|
+
if (account.error) {
|
|
24758
|
+
const payload = extractErrorPayload(account.error);
|
|
24759
|
+
writeErrorWithHints(payload);
|
|
24760
|
+
surfaceUnauthorizedHint({
|
|
24761
|
+
auth,
|
|
24762
|
+
baseUrlOverridden,
|
|
24763
|
+
configDir: this.config.configDir,
|
|
24764
|
+
payload
|
|
24765
|
+
});
|
|
24766
|
+
process.exitCode = 1;
|
|
24767
|
+
return;
|
|
24768
|
+
}
|
|
24769
|
+
const org = account.data.data.id;
|
|
24770
|
+
const client = buildX402Client({
|
|
24771
|
+
apiKey: auth.apiKey,
|
|
24772
|
+
resolvedApiBaseUrl: requestConfig.resolvedApiBaseUrl
|
|
24773
|
+
});
|
|
24774
|
+
if (!client) {
|
|
24775
|
+
process.exitCode = 1;
|
|
24776
|
+
return;
|
|
24777
|
+
}
|
|
24778
|
+
try {
|
|
24779
|
+
const signer = signerFromPrivateKey(flags["private-key"] ?? "");
|
|
24780
|
+
const result = await client.registerPayoutAddress({
|
|
24781
|
+
org,
|
|
24782
|
+
network: flags.network,
|
|
24783
|
+
...flags["issued-at"] ? { issuedAt: flags["issued-at"] } : {},
|
|
24784
|
+
...flags.label ? { label: flags.label } : {}
|
|
24785
|
+
}, { signer });
|
|
24786
|
+
if (flags.json) this.log(JSON.stringify(result, null, 2));
|
|
24787
|
+
else this.log(`Registered ${result.address} as the default payout address for ${result.network}. You can now run \`primitive payments charge\`.`);
|
|
24788
|
+
} catch (error) {
|
|
24789
|
+
reportX402Error(error, {
|
|
24790
|
+
auth,
|
|
24791
|
+
baseUrlOverridden,
|
|
24792
|
+
configDir: this.config.configDir
|
|
24793
|
+
});
|
|
24794
|
+
process.exitCode = 1;
|
|
24795
|
+
}
|
|
24796
|
+
});
|
|
24797
|
+
}
|
|
24798
|
+
};
|
|
24799
|
+
//#endregion
|
|
22327
24800
|
//#region src/oclif/message-body-sources.ts
|
|
22328
24801
|
function defaultReadFile(path) {
|
|
22329
24802
|
return readFileSync(path, "utf8");
|
|
@@ -23754,7 +26227,9 @@ const OVERRIDDEN_OPERATION_IDS = new Set([
|
|
|
23754
26227
|
"domains:download-domain-zone-file",
|
|
23755
26228
|
"functions:test-function",
|
|
23756
26229
|
"inbox:get-inbox-status",
|
|
23757
|
-
"search:semantic-search"
|
|
26230
|
+
"search:semantic-search",
|
|
26231
|
+
"payments:register-payout-address",
|
|
26232
|
+
"payments:pay-challenge"
|
|
23758
26233
|
]);
|
|
23759
26234
|
const generatedCommands = Object.fromEntries(operationManifest.filter((operation) => !OVERRIDDEN_OPERATION_IDS.has(operationId(operation))).map((operation) => [operationId(operation), createOperationCommand(operation)]));
|
|
23760
26235
|
const COMMANDS = {
|
|
@@ -23827,7 +26302,12 @@ const COMMANDS = {
|
|
|
23827
26302
|
return [alias, command];
|
|
23828
26303
|
})),
|
|
23829
26304
|
...generatedCommands,
|
|
23830
|
-
"functions:logs": FunctionsLogsCommand
|
|
26305
|
+
"functions:logs": FunctionsLogsCommand,
|
|
26306
|
+
"payments:register-payout-address": PaymentsRegisterPayoutAddressCommand,
|
|
26307
|
+
"payments:register-payout": PaymentsRegisterPayoutAddressCommand,
|
|
26308
|
+
"payments:charge": PaymentsChargeCommand,
|
|
26309
|
+
"payments:pay-challenge": PaymentsPayCommand,
|
|
26310
|
+
"payments:pay": PaymentsPayCommand
|
|
23831
26311
|
};
|
|
23832
26312
|
//#endregion
|
|
23833
26313
|
export { CANONICAL_OPERATION_ALIASES, COMMANDS, lookupOperation };
|