stablevoy 1.7.0 → 1.8.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/CHANGELOG.md +5 -0
- package/README.md +12 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/keys/Crc32.d.ts +3 -0
- package/dist/keys/Crc32.d.ts.map +1 -0
- package/dist/keys/Crc32.js +18 -0
- package/dist/keys/Crc32.js.map +1 -0
- package/dist/keys/KeyFormat.d.ts +10 -0
- package/dist/keys/KeyFormat.d.ts.map +1 -0
- package/dist/keys/KeyFormat.js +37 -0
- package/dist/keys/KeyFormat.js.map +1 -0
- package/dist/model/ConnectedApp.d.ts.map +1 -1
- package/dist/model/ConnectedApp.js +3 -2
- package/dist/model/ConnectedApp.js.map +1 -1
- package/dist/model/ConnectedStore.d.ts.map +1 -1
- package/dist/model/ConnectedStore.js +5 -4
- package/dist/model/ConnectedStore.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.8.0
|
|
4
|
+
|
|
5
|
+
- Stablevoy is moving to its own key formats: API keys `svk_live_...` / `svk_test_...` and webhook signing secrets `svwhsec_...`, each ending in a checksum. The SDK accepts them and the older `sk_live_` / `sk_test_` / `whsec_` in connect answers; older keys keep working.
|
|
6
|
+
- `checkApiKey(value)` and `checkWebhookSecret(value)` tell a pasted key apart: `ok`, `mistyped` (a new-format key whose checksum does not match, so a character is wrong or missing) or `not_a_key`.
|
|
7
|
+
|
|
3
8
|
## 1.7.0
|
|
4
9
|
|
|
5
10
|
- `invoices.summary({ period })` or `invoices.summary({ createdFrom, createdTo })`: totals of the invoices created in a range of UTC days, with the count per status, the invoiced amount and the money received, also per network and token. Periods are in `SummaryPeriod`; one request covers at most 92 days, and a longer range is refused with `ApiError.INVALID_INVOICE_FILTER`.
|
package/README.md
CHANGED
|
@@ -181,6 +181,18 @@ export async function POST(request: Request) {
|
|
|
181
181
|
}
|
|
182
182
|
```
|
|
183
183
|
|
|
184
|
+
## Check a pasted key
|
|
185
|
+
|
|
186
|
+
API keys are `svk_live_...` or `svk_test_...` and webhook signing secrets `svwhsec_...`; both end in a checksum. Keys made before this format (`sk_live_`, `sk_test_`, `whsec_`) keep working.
|
|
187
|
+
|
|
188
|
+
```ts
|
|
189
|
+
import { checkApiKey } from 'stablevoy';
|
|
190
|
+
|
|
191
|
+
if (checkApiKey(input) === 'mistyped') console.log('A character is wrong or missing: copy the key again from the dashboard.');
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
`checkApiKey` and `checkWebhookSecret` answer `ok`, `mistyped` or `not_a_key`, without any request.
|
|
195
|
+
|
|
184
196
|
## Errors and retries
|
|
185
197
|
|
|
186
198
|
Every error extends `StablevoyError`. API errors are `ApiError` with the HTTP `status`, a stable `code`, a readable `detail` and a link to the [error catalog](https://stablevoy.com/docs/api/errors/); the ones you may want to handle on their own are `AuthenticationError`, `ValidationError` (with `issues`), `NotFoundError`, `RateLimitedError` and `MaintenanceError`. `TransportError` means no answer at all.
|
package/dist/index.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ export type { ConnectionOptions } from './ConnectionOptions.js';
|
|
|
4
4
|
export type { ConnectedStore } from './model/ConnectedStore.js';
|
|
5
5
|
export type { ConnectedApp, ConnectedAppStore } from './model/ConnectedApp.js';
|
|
6
6
|
export { VERSION } from './version.js';
|
|
7
|
+
export { checkApiKey, checkWebhookSecret, type KeyCheck } from './keys/KeyFormat.js';
|
|
7
8
|
export { RetryPolicy } from './http/RetryPolicy.js';
|
|
8
9
|
export type { Sleep } from './http/Sleep.js';
|
|
9
10
|
export type { Query, Transport } from './http/Transport.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,KAAK,gBAAgB,EAAE,KAAK,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACpG,YAAY,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAChE,YAAY,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,YAAY,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC/E,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,YAAY,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAC7C,YAAY,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,KAAK,iBAAiB,EAAE,KAAK,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACrG,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AACvE,YAAY,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,KAAK,cAAc,EAAE,KAAK,mBAAmB,EAAE,KAAK,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AACpJ,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACvE,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,KAAK,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACtG,YAAY,EAAE,kBAAkB,EAAE,cAAc,EAAE,cAAc,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC5H,YAAY,EAAE,eAAe,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AACpH,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACjG,OAAO,EAAE,eAAe,EAAE,KAAK,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAC5F,YAAY,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC9D,YAAY,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,KAAK,eAAe,EAAE,KAAK,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzF,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,qCAAqC,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,KAAK,gBAAgB,EAAE,KAAK,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACpG,YAAY,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAChE,YAAY,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,YAAY,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC/E,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,KAAK,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACrF,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,YAAY,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAC7C,YAAY,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,KAAK,iBAAiB,EAAE,KAAK,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACrG,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AACvE,YAAY,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,KAAK,cAAc,EAAE,KAAK,mBAAmB,EAAE,KAAK,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AACpJ,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACvE,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,KAAK,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACtG,YAAY,EAAE,kBAAkB,EAAE,cAAc,EAAE,cAAc,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC5H,YAAY,EAAE,eAAe,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AACpH,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACjG,OAAO,EAAE,eAAe,EAAE,KAAK,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAC5F,YAAY,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC9D,YAAY,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,KAAK,eAAe,EAAE,KAAK,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzF,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,qCAAqC,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { Stablevoy } from './Stablevoy.js';
|
|
2
2
|
export { StablevoyConnect } from './StablevoyConnect.js';
|
|
3
3
|
export { VERSION } from './version.js';
|
|
4
|
+
export { checkApiKey, checkWebhookSecret } from './keys/KeyFormat.js';
|
|
4
5
|
export { RetryPolicy } from './http/RetryPolicy.js';
|
|
5
6
|
export { Invoices } from './resources/Invoices.js';
|
|
6
7
|
export { Stores } from './resources/Stores.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAyB,MAAM,gBAAgB,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAA6C,MAAM,uBAAuB,CAAC;AAIpG,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAGpD,OAAO,EAAE,QAAQ,EAAoD,MAAM,yBAAyB,CAAC;AACrG,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AAEvE,OAAO,EAAE,aAAa,EAA4F,MAAM,2BAA2B,CAAC;AACpJ,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACvE,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAsB,MAAM,0BAA0B,CAAC;AAGtG,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACjG,OAAO,EAAE,eAAe,EAA+B,MAAM,8BAA8B,CAAC;AAG5F,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAA2C,MAAM,sBAAsB,CAAC;AACzF,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,qCAAqC,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAyB,MAAM,gBAAgB,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAA6C,MAAM,uBAAuB,CAAC;AAIpG,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAiB,MAAM,qBAAqB,CAAC;AACrF,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAGpD,OAAO,EAAE,QAAQ,EAAoD,MAAM,yBAAyB,CAAC;AACrG,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AAEvE,OAAO,EAAE,aAAa,EAA4F,MAAM,2BAA2B,CAAC;AACpJ,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACvE,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAsB,MAAM,0BAA0B,CAAC;AAGtG,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACjG,OAAO,EAAE,eAAe,EAA+B,MAAM,8BAA8B,CAAC;AAG5F,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAA2C,MAAM,sBAAsB,CAAC;AACzF,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,qCAAqC,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Crc32.d.ts","sourceRoot":"","sources":["../../src/keys/Crc32.ts"],"names":[],"mappings":"AAUA,sDAAsD;AACtD,wBAAgB,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAI1C"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const TABLE = (() => {
|
|
2
|
+
const table = new Uint32Array(256);
|
|
3
|
+
for (let n = 0; n < 256; n++) {
|
|
4
|
+
let c = n;
|
|
5
|
+
for (let k = 0; k < 8; k++)
|
|
6
|
+
c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;
|
|
7
|
+
table[n] = c >>> 0;
|
|
8
|
+
}
|
|
9
|
+
return table;
|
|
10
|
+
})();
|
|
11
|
+
/** CRC-32 (IEEE, the zlib one) of an ASCII string. */
|
|
12
|
+
export function crc32(text) {
|
|
13
|
+
let crc = 0xffffffff;
|
|
14
|
+
for (let i = 0; i < text.length; i++)
|
|
15
|
+
crc = TABLE[(crc ^ text.charCodeAt(i)) & 0xff] ^ (crc >>> 8);
|
|
16
|
+
return (crc ^ 0xffffffff) >>> 0;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=Crc32.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Crc32.js","sourceRoot":"","sources":["../../src/keys/Crc32.ts"],"names":[],"mappings":"AAAA,MAAM,KAAK,GAAG,CAAC,GAAG,EAAE;IAClB,MAAM,KAAK,GAAG,IAAI,WAAW,CAAC,GAAG,CAAC,CAAC;IACnC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QAC7B,IAAI,CAAC,GAAG,CAAC,CAAC;QACV,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;YAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QACzE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACrB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC,CAAC,EAAE,CAAC;AAEL,sDAAsD;AACtD,MAAM,UAAU,KAAK,CAAC,IAAY;IAChC,IAAI,GAAG,GAAG,UAAU,CAAC;IACrB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE;QAAE,GAAG,GAAI,KAAK,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAY,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC;IAC/G,OAAO,CAAC,GAAG,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;AAClC,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** How a pasted or received key or secret looks: right, wrong in a way that means a typo or a cut copy, or not one at all. */
|
|
2
|
+
export type KeyCheck = 'ok' | 'mistyped' | 'not_a_key';
|
|
3
|
+
/**
|
|
4
|
+
* Stablevoy store API keys are svk_live_ / svk_test_ followed by 30 random and 6 checksum characters; keys made before the
|
|
5
|
+
* new format are sk_live_ / sk_test_ and keep working. A checksummed key with a broken checksum was mistyped or cut.
|
|
6
|
+
*/
|
|
7
|
+
export declare function checkApiKey(value: string): KeyCheck;
|
|
8
|
+
/** Webhook signing secrets: svwhsec_ with a checksum, or the older whsec_. */
|
|
9
|
+
export declare function checkWebhookSecret(value: string): KeyCheck;
|
|
10
|
+
//# sourceMappingURL=KeyFormat.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KeyFormat.d.ts","sourceRoot":"","sources":["../../src/keys/KeyFormat.ts"],"names":[],"mappings":"AAUA,8HAA8H;AAC9H,MAAM,MAAM,QAAQ,GAAG,IAAI,GAAG,UAAU,GAAG,WAAW,CAAC;AAEvD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,CAInD;AAED,8EAA8E;AAC9E,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,CAG1D"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { crc32 } from './Crc32.js';
|
|
2
|
+
const BASE62 = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
|
|
3
|
+
const CHECKSUMMED_BODY = /^[0-9A-Za-z]{36}$/;
|
|
4
|
+
const API_KEY_PREFIXES = ['svk_live_', 'svk_test_'];
|
|
5
|
+
const WEBHOOK_SECRET_PREFIX = 'svwhsec_';
|
|
6
|
+
/** The older formats are recognised by prefix only, as before the checksummed ones existed. */
|
|
7
|
+
const OLDER_API_KEY = /^sk_(live|test)_/;
|
|
8
|
+
const OLDER_WEBHOOK_SECRET = /^whsec_/;
|
|
9
|
+
/**
|
|
10
|
+
* Stablevoy store API keys are svk_live_ / svk_test_ followed by 30 random and 6 checksum characters; keys made before the
|
|
11
|
+
* new format are sk_live_ / sk_test_ and keep working. A checksummed key with a broken checksum was mistyped or cut.
|
|
12
|
+
*/
|
|
13
|
+
export function checkApiKey(value) {
|
|
14
|
+
const prefix = API_KEY_PREFIXES.find((p) => value.startsWith(p));
|
|
15
|
+
if (prefix !== undefined)
|
|
16
|
+
return hasValidChecksum(prefix, value) ? 'ok' : 'mistyped';
|
|
17
|
+
return OLDER_API_KEY.test(value) ? 'ok' : 'not_a_key';
|
|
18
|
+
}
|
|
19
|
+
/** Webhook signing secrets: svwhsec_ with a checksum, or the older whsec_. */
|
|
20
|
+
export function checkWebhookSecret(value) {
|
|
21
|
+
if (value.startsWith(WEBHOOK_SECRET_PREFIX))
|
|
22
|
+
return hasValidChecksum(WEBHOOK_SECRET_PREFIX, value) ? 'ok' : 'mistyped';
|
|
23
|
+
return OLDER_WEBHOOK_SECRET.test(value) ? 'ok' : 'not_a_key';
|
|
24
|
+
}
|
|
25
|
+
function hasValidChecksum(prefix, value) {
|
|
26
|
+
const body = value.slice(prefix.length);
|
|
27
|
+
if (!CHECKSUMMED_BODY.test(body))
|
|
28
|
+
return false;
|
|
29
|
+
let n = crc32(prefix + body.slice(0, 30));
|
|
30
|
+
let checksum = '';
|
|
31
|
+
for (let i = 0; i < 6; i++) {
|
|
32
|
+
checksum = BASE62.charAt(n % 62) + checksum;
|
|
33
|
+
n = Math.floor(n / 62);
|
|
34
|
+
}
|
|
35
|
+
return body.slice(30) === checksum;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=KeyFormat.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KeyFormat.js","sourceRoot":"","sources":["../../src/keys/KeyFormat.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,MAAM,MAAM,GAAG,gEAAgE,CAAC;AAChF,MAAM,gBAAgB,GAAG,mBAAmB,CAAC;AAC7C,MAAM,gBAAgB,GAAG,CAAC,WAAW,EAAE,WAAW,CAAU,CAAC;AAC7D,MAAM,qBAAqB,GAAG,UAAU,CAAC;AACzC,+FAA+F;AAC/F,MAAM,aAAa,GAAG,kBAAkB,CAAC;AACzC,MAAM,oBAAoB,GAAG,SAAS,CAAC;AAKvC;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,MAAM,MAAM,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IACjE,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,gBAAgB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC;IACrF,OAAO,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC;AACxD,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,kBAAkB,CAAC,KAAa;IAC9C,IAAI,KAAK,CAAC,UAAU,CAAC,qBAAqB,CAAC;QAAE,OAAO,gBAAgB,CAAC,qBAAqB,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC;IACvH,OAAO,oBAAoB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC;AAC/D,CAAC;AAED,SAAS,gBAAgB,CAAC,MAAc,EAAE,KAAa;IACrD,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACxC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IAC/C,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IAC1C,IAAI,QAAQ,GAAG,EAAE,CAAC;IAClB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,QAAQ,CAAC;QAC5C,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IACzB,CAAC;IACD,OAAO,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,QAAQ,CAAC;AACrC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConnectedApp.d.ts","sourceRoot":"","sources":["../../src/model/ConnectedApp.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"ConnectedApp.d.ts","sourceRoot":"","sources":["../../src/model/ConnectedApp.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAG1C,0FAA0F;AAC1F,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,+GAA+G;AAC/G,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,MAAM,EAAE,SAAS,iBAAiB,EAAE,CAAC;CAC/C;AAED,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,MAAM,GAAG,YAAY,CAQzD"}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { UnexpectedResponseError } from '../errors/UnexpectedResponseError.js';
|
|
2
|
+
import { checkApiKey } from '../keys/KeyFormat.js';
|
|
2
3
|
export function parseConnectedApp(f) {
|
|
3
4
|
const stores = f.objects('stores', (s) => {
|
|
4
5
|
const apiKey = s.string('apiKey');
|
|
5
|
-
if (
|
|
6
|
-
throw new UnexpectedResponseError(`${s.pathOf('apiKey')} is not an API key (
|
|
6
|
+
if (checkApiKey(apiKey) !== 'ok')
|
|
7
|
+
throw new UnexpectedResponseError(`${s.pathOf('apiKey')} is not an API key (svk_live_, svk_test_, or the older sk_live_, sk_test_)`);
|
|
7
8
|
return { storeId: s.string('id'), storeName: s.string('name'), apiKey };
|
|
8
9
|
});
|
|
9
10
|
if (stores.length === 0)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConnectedApp.js","sourceRoot":"","sources":["../../src/model/ConnectedApp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAC;
|
|
1
|
+
{"version":3,"file":"ConnectedApp.js","sourceRoot":"","sources":["../../src/model/ConnectedApp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAC;AAE/E,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAcnD,MAAM,UAAU,iBAAiB,CAAC,CAAS;IACzC,MAAM,MAAM,GAAG,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE;QACvC,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAClC,IAAI,WAAW,CAAC,MAAM,CAAC,KAAK,IAAI;YAAE,MAAM,IAAI,uBAAuB,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,4EAA4E,CAAC,CAAC;QACvK,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1E,CAAC,CAAC,CAAC;IACH,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,MAAM,IAAI,uBAAuB,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IAC7F,OAAO,EAAE,MAAM,EAAE,CAAC;AACpB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConnectedStore.d.ts","sourceRoot":"","sources":["../../src/model/ConnectedStore.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"ConnectedStore.d.ts","sourceRoot":"","sources":["../../src/model/ConnectedStore.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAG1C,yHAAyH;AACzH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,MAAM,GAAG,cAAc,CAO7D"}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { UnexpectedResponseError } from '../errors/UnexpectedResponseError.js';
|
|
2
|
+
import { checkApiKey, checkWebhookSecret } from '../keys/KeyFormat.js';
|
|
2
3
|
export function parseConnectedStore(f) {
|
|
3
4
|
const apiKey = f.string('apiKey');
|
|
4
|
-
if (
|
|
5
|
-
throw new UnexpectedResponseError(`${f.pathOf('apiKey')} is not an API key (
|
|
5
|
+
if (checkApiKey(apiKey) !== 'ok')
|
|
6
|
+
throw new UnexpectedResponseError(`${f.pathOf('apiKey')} is not an API key (svk_live_, svk_test_, or the older sk_live_, sk_test_)`);
|
|
6
7
|
const webhookSecret = f.string('webhookSecret');
|
|
7
|
-
if (
|
|
8
|
-
throw new UnexpectedResponseError(`${f.pathOf('webhookSecret')} is not a webhook secret (whsec_)`);
|
|
8
|
+
if (checkWebhookSecret(webhookSecret) !== 'ok')
|
|
9
|
+
throw new UnexpectedResponseError(`${f.pathOf('webhookSecret')} is not a webhook secret (svwhsec_, or the older whsec_)`);
|
|
9
10
|
const store = f.object('store');
|
|
10
11
|
return { apiKey, webhookSecret, storeId: store.string('id'), storeName: store.string('name') };
|
|
11
12
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConnectedStore.js","sourceRoot":"","sources":["../../src/model/ConnectedStore.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAC;
|
|
1
|
+
{"version":3,"file":"ConnectedStore.js","sourceRoot":"","sources":["../../src/model/ConnectedStore.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAC;AAE/E,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAUvE,MAAM,UAAU,mBAAmB,CAAC,CAAS;IAC3C,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAClC,IAAI,WAAW,CAAC,MAAM,CAAC,KAAK,IAAI;QAAE,MAAM,IAAI,uBAAuB,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,4EAA4E,CAAC,CAAC;IACvK,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;IAChD,IAAI,kBAAkB,CAAC,aAAa,CAAC,KAAK,IAAI;QAAE,MAAM,IAAI,uBAAuB,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,eAAe,CAAC,0DAA0D,CAAC,CAAC;IAC1K,MAAM,KAAK,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAChC,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;AACjG,CAAC"}
|
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "1.
|
|
1
|
+
export declare const VERSION = "1.8.0";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const VERSION = '1.
|
|
1
|
+
export const VERSION = '1.8.0';
|
|
2
2
|
//# sourceMappingURL=version.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "stablevoy",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
4
4
|
"description": "Node.js and TypeScript client for the Stablevoy API: non-custodial USDT and USDC payments, invoices and signed webhooks.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"stablevoy",
|
|
@@ -52,10 +52,10 @@
|
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@eslint/js": "10.0.1",
|
|
54
54
|
"@types/node": "26.6.6",
|
|
55
|
-
"@vitest/coverage-v8": "5.0
|
|
55
|
+
"@vitest/coverage-v8": "5.1.0",
|
|
56
56
|
"eslint": "10.14.0",
|
|
57
57
|
"typescript": "6.0.3",
|
|
58
58
|
"typescript-eslint": "8.72.1",
|
|
59
|
-
"vitest": "5.0
|
|
59
|
+
"vitest": "5.1.0"
|
|
60
60
|
}
|
|
61
61
|
}
|