@vestiarion/sdk 0.1.0 → 0.2.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 +22 -5
- package/dist/client.d.ts +11 -2
- package/dist/client.js +13 -1
- package/dist/http.d.ts +2 -1
- package/dist/http.js +4 -2
- package/dist/types.d.ts +26 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -12,10 +12,11 @@ It has no dependencies, and runs on Node 20 or later, Deno, Bun and edge runtime
|
|
|
12
12
|
## Install
|
|
13
13
|
|
|
14
14
|
```bash
|
|
15
|
-
npm install
|
|
15
|
+
npm install @vestiarion/sdk
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
-
pnpm, Yarn and Bun
|
|
18
|
+
pnpm, Yarn and Bun install it the same way. The package is ESM only. Each version is also served as a tarball, such as
|
|
19
|
+
`https://www.vestiarion.xyz/sdk/vestiarion-sdk-0.2.0.tgz`, which `npm install` takes as it is.
|
|
19
20
|
|
|
20
21
|
## Read
|
|
21
22
|
|
|
@@ -38,9 +39,10 @@ workspace.
|
|
|
38
39
|
|
|
39
40
|
## Add records
|
|
40
41
|
|
|
41
|
-
A key with write access ("Can also add
|
|
42
|
+
A key with write access ("Can also add records") adds counterparties, invoices, milestones and payee links.
|
|
42
43
|
- The agent decides each invoice as it decides one typed into the console, with every guardrail.
|
|
43
|
-
-
|
|
44
|
+
- A milestone starts pending. GitHub verifies it once its pull request is merged, or a person does; then the agent decides.
|
|
45
|
+
- An address added this way, or entered by a payee through a link, waits for a person in the workspace to confirm it.
|
|
44
46
|
|
|
45
47
|
```ts
|
|
46
48
|
const counterparty = await vestiarion.counterparties.create(
|
|
@@ -55,6 +57,20 @@ const invoice = await vestiarion.invoices.create(
|
|
|
55
57
|
|
|
56
58
|
Pass your own record's id as `idempotencyKey`, so that your own retries cannot add it twice either.
|
|
57
59
|
|
|
60
|
+
Pay a contributor when their pull request merges, and ask a new payee for their address:
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
const milestone = await vestiarion.milestones.create(
|
|
64
|
+
{ contractorId: contractor.id, title: "CSV export for EURC", amount: "150.00", verificationSource: "https://github.com/acme/app/pull/42" },
|
|
65
|
+
{ idempotencyKey: "pr-acme-app-42" }
|
|
66
|
+
);
|
|
67
|
+
const link = await vestiarion.payeeLinks.create({ counterpartyId: contractor.id });
|
|
68
|
+
// Send link.url to the payee: it is shown only in this answer.
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
A payee link takes no `idempotencyKey`: the API keeps only the link's hash, so a repeat makes a new link and the unused
|
|
72
|
+
one stops working.
|
|
73
|
+
|
|
58
74
|
## Errors and retries
|
|
59
75
|
|
|
60
76
|
Every failure is a `VestiarionError`. It carries:
|
|
@@ -68,7 +84,8 @@ A request is retried twice by default after:
|
|
|
68
84
|
- a `500`, `502`, `503` or `504`;
|
|
69
85
|
- a timeout or a network failure.
|
|
70
86
|
|
|
71
|
-
A write
|
|
87
|
+
A write carries an `Idempotency-Key`, so retrying it never adds the record twice. A payee link is the exception: a retry
|
|
88
|
+
makes a new link, which replaces the first.
|
|
72
89
|
|
|
73
90
|
## Webhooks
|
|
74
91
|
|
package/dist/client.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type FetchLike } from "./http.js";
|
|
2
|
-
import type { Counterparty, CounterpartyDetail, CreateCounterpartyInput, CreateInvoiceInput, Insights, Invoice, LedgerEntry, LedgerVerification, ListCounterpartiesParams, ListInvoicesParams, ListLedgerEntriesParams, ListMilestonesParams, Milestone, Page, Status, Treasury } from "./types.js";
|
|
2
|
+
import type { Counterparty, CounterpartyDetail, CreateCounterpartyInput, CreateInvoiceInput, CreateMilestoneInput, CreatePayeeLinkInput, Insights, Invoice, LedgerEntry, LedgerVerification, ListCounterpartiesParams, ListInvoicesParams, ListLedgerEntriesParams, ListMilestonesParams, Milestone, Page, PayeeLink, Status, Treasury } from "./types.js";
|
|
3
3
|
/** Where the API is, unless `baseUrl` says otherwise. */
|
|
4
4
|
export declare const DEFAULT_BASE_URL = "https://www.vestiarion.xyz";
|
|
5
5
|
export interface VestiarionOptions {
|
|
@@ -49,7 +49,16 @@ export declare class Vestiarion {
|
|
|
49
49
|
get(id: string): Promise<CounterpartyDetail>;
|
|
50
50
|
create(input: CreateCounterpartyInput, options?: WriteOptions): Promise<Counterparty>;
|
|
51
51
|
};
|
|
52
|
-
readonly milestones: Collection<Milestone, ListMilestonesParams
|
|
52
|
+
readonly milestones: Collection<Milestone, ListMilestonesParams> & {
|
|
53
|
+
create(input: CreateMilestoneInput, options?: WriteOptions): Promise<Milestone>;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* One-time links where a payee enters the address they are paid at. A link's `url` is in the answer only: send it to
|
|
57
|
+
* the payee. Making one revokes the payee's unused link, so a retry gives a working link too.
|
|
58
|
+
*/
|
|
59
|
+
readonly payeeLinks: {
|
|
60
|
+
create(input: CreatePayeeLinkInput): Promise<PayeeLink>;
|
|
61
|
+
};
|
|
53
62
|
readonly treasury: {
|
|
54
63
|
get(): Promise<Treasury>;
|
|
55
64
|
};
|
package/dist/client.js
CHANGED
|
@@ -48,6 +48,11 @@ export class Vestiarion {
|
|
|
48
48
|
invoices;
|
|
49
49
|
counterparties;
|
|
50
50
|
milestones;
|
|
51
|
+
/**
|
|
52
|
+
* One-time links where a payee enters the address they are paid at. A link's `url` is in the answer only: send it to
|
|
53
|
+
* the payee. Making one revokes the payee's unused link, so a retry gives a working link too.
|
|
54
|
+
*/
|
|
55
|
+
payeeLinks;
|
|
51
56
|
treasury;
|
|
52
57
|
insights;
|
|
53
58
|
constructor(options) {
|
|
@@ -84,7 +89,14 @@ export class Vestiarion {
|
|
|
84
89
|
get: (id) => one(`/api/v1/counterparties/${encodeURIComponent(id)}`),
|
|
85
90
|
create: (input, write) => add("/api/v1/counterparties", input, write),
|
|
86
91
|
};
|
|
87
|
-
this.milestones =
|
|
92
|
+
this.milestones = {
|
|
93
|
+
...collection(transport, "/api/v1/milestones"),
|
|
94
|
+
create: (input, write) => add("/api/v1/milestones", input, write),
|
|
95
|
+
};
|
|
96
|
+
// The API keeps no outcome for a payee link's key, so none is sent (write API part 2, W3).
|
|
97
|
+
this.payeeLinks = {
|
|
98
|
+
create: (input) => transport.request({ method: "POST", path: "/api/v1/payee-links", body: input, idempotencyKey: null }).then((answer) => answer.data),
|
|
99
|
+
};
|
|
88
100
|
this.treasury = { get: () => one("/api/v1/treasury") };
|
|
89
101
|
this.insights = { get: () => one("/api/v1/insights") };
|
|
90
102
|
}
|
package/dist/http.d.ts
CHANGED
|
@@ -29,7 +29,8 @@ export interface RequestSpec {
|
|
|
29
29
|
path: string;
|
|
30
30
|
query?: object;
|
|
31
31
|
body?: unknown;
|
|
32
|
-
|
|
32
|
+
/** A write's key: the caller's, or a fresh one when left out. `null` sends none, for a write that keeps no outcome for one. */
|
|
33
|
+
idempotencyKey?: string | null;
|
|
33
34
|
}
|
|
34
35
|
export interface Transport {
|
|
35
36
|
request<T>(spec: RequestSpec): Promise<T>;
|
package/dist/http.js
CHANGED
|
@@ -121,8 +121,10 @@ export function createTransport(options) {
|
|
|
121
121
|
let body;
|
|
122
122
|
if (spec.method === "POST") {
|
|
123
123
|
headers["content-type"] = "application/json";
|
|
124
|
-
// Every write
|
|
125
|
-
|
|
124
|
+
// Every write that keeps an outcome for a key carries one, so retrying it can never add the record twice (R6). A
|
|
125
|
+
// payee link keeps none, since that would store the link: a retry makes a new link, which replaces the first.
|
|
126
|
+
if (spec.idempotencyKey !== null)
|
|
127
|
+
headers["idempotency-key"] = spec.idempotencyKey ?? uuid();
|
|
126
128
|
body = JSON.stringify(spec.body ?? {});
|
|
127
129
|
}
|
|
128
130
|
for (let attempt = 0;; attempt += 1) {
|
package/dist/types.d.ts
CHANGED
|
@@ -174,6 +174,16 @@ export interface Milestone {
|
|
|
174
174
|
} | null;
|
|
175
175
|
createdAt: string;
|
|
176
176
|
}
|
|
177
|
+
/** A one-time link for a payee to enter the address they are paid at. That address waits for a person in the workspace to confirm it before the agent pays to it. */
|
|
178
|
+
export interface PayeeLink {
|
|
179
|
+
/** The link's own id. It is not the link: that is `url`. */
|
|
180
|
+
id: string;
|
|
181
|
+
counterpartyId: string;
|
|
182
|
+
/** The one-time page where the payee enters their address. It is in this answer only: Vestiarion keeps just its hash. Send it to the payee yourself. */
|
|
183
|
+
url: string;
|
|
184
|
+
/** When the link stops working, 7 days after it was made. It also stops once the payee has used it, or a newer link replaces it. */
|
|
185
|
+
expiresAt: string;
|
|
186
|
+
}
|
|
177
187
|
/** The workspace's accounts, reserve, obligations, latest forecast and recent treasury moves. */
|
|
178
188
|
export interface Treasury {
|
|
179
189
|
accounts: Array<{
|
|
@@ -335,6 +345,22 @@ export interface CreateCounterpartyInput {
|
|
|
335
345
|
/** Where it is emailed once a payment to it is confirmed. */
|
|
336
346
|
noticeEmail?: string;
|
|
337
347
|
}
|
|
348
|
+
/** A milestone to add. It starts pending: the agent pays it only once it is verified, by GitHub or by a person, and only after its own checks. */
|
|
349
|
+
export interface CreateMilestoneInput {
|
|
350
|
+
/** The `id` of the contractor or vendor to pay, from `GET /api/v1/counterparties` or from the answer that added it. A client is not paid for milestones. */
|
|
351
|
+
contractorId: string;
|
|
352
|
+
/** What was delivered, 3 to 160 characters. */
|
|
353
|
+
title: string;
|
|
354
|
+
/** What the work is paid, in USDC, with at most 6 decimal places. A decimal string such as `"250.00"` keeps it exact; a number is read the same way. */
|
|
355
|
+
amount: string | number;
|
|
356
|
+
/** A link to the delivered work: https, up to 500 characters. A GitHub pull request (`https://github.com/<owner>/<repo>/pull/<number>`) is checked by the agent, which verifies the milestone once it is merged. Any other link is evidence for the person who verifies the milestone on Contractors. */
|
|
357
|
+
verificationSource?: string;
|
|
358
|
+
}
|
|
359
|
+
/** Who the link is for. */
|
|
360
|
+
export interface CreatePayeeLinkInput {
|
|
361
|
+
/** The `id` of the vendor or contractor who is to enter the address they are paid at. A client gets no link: the agent never pays one. */
|
|
362
|
+
counterpartyId: string;
|
|
363
|
+
}
|
|
338
364
|
/** The query parameters of `list-ledger-entries`. */
|
|
339
365
|
export interface ListLedgerEntriesParams {
|
|
340
366
|
/** How many items to return. Defaults to 50; a larger value is capped at 200. */
|
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** This package's version, sent in every request's `User-Agent`. tests/sdk-package.test.ts holds it to package.json. */
|
|
2
|
-
export declare const VERSION = "0.
|
|
2
|
+
export declare const VERSION = "0.2.0";
|
package/dist/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** This package's version, sent in every request's `User-Agent`. tests/sdk-package.test.ts holds it to package.json. */
|
|
2
|
-
export const VERSION = "0.
|
|
2
|
+
export const VERSION = "0.2.0";
|