n8n-nodes-taliware 0.1.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/LICENSE +21 -0
- package/README.md +291 -0
- package/dist/credentials/TaliwareApi.credentials.d.ts +9 -0
- package/dist/credentials/TaliwareApi.credentials.js +52 -0
- package/dist/credentials/TaliwareApi.credentials.js.map +1 -0
- package/dist/credentials/icons/taliware.dark.svg +13 -0
- package/dist/credentials/icons/taliware.svg +13 -0
- package/dist/lib/cl2cClient.d.ts +18 -0
- package/dist/lib/cl2cClient.js +77 -0
- package/dist/lib/cl2cClient.js.map +1 -0
- package/dist/lib/createNft.d.ts +12 -0
- package/dist/lib/createNft.js +36 -0
- package/dist/lib/createNft.js.map +1 -0
- package/dist/lib/errors.d.ts +16 -0
- package/dist/lib/errors.js +68 -0
- package/dist/lib/errors.js.map +1 -0
- package/dist/lib/getTaliwareCredentials.d.ts +3 -0
- package/dist/lib/getTaliwareCredentials.js +26 -0
- package/dist/lib/getTaliwareCredentials.js.map +1 -0
- package/dist/lib/initiateMint.d.ts +16 -0
- package/dist/lib/initiateMint.js +25 -0
- package/dist/lib/initiateMint.js.map +1 -0
- package/dist/lib/mapOutput.d.ts +3 -0
- package/dist/lib/mapOutput.js +69 -0
- package/dist/lib/mapOutput.js.map +1 -0
- package/dist/lib/pollNftStatus.d.ts +12 -0
- package/dist/lib/pollNftStatus.js +87 -0
- package/dist/lib/pollNftStatus.js.map +1 -0
- package/dist/lib/resolveSmartContractId.d.ts +2 -0
- package/dist/lib/resolveSmartContractId.js +16 -0
- package/dist/lib/resolveSmartContractId.js.map +1 -0
- package/dist/lib/resolveUserId.d.ts +3 -0
- package/dist/lib/resolveUserId.js +40 -0
- package/dist/lib/resolveUserId.js.map +1 -0
- package/dist/lib/toolParameters.d.ts +3 -0
- package/dist/lib/toolParameters.js +115 -0
- package/dist/lib/toolParameters.js.map +1 -0
- package/dist/lib/types.d.ts +88 -0
- package/dist/lib/types.js +19 -0
- package/dist/lib/types.js.map +1 -0
- package/dist/lib/validateMintInputs.d.ts +6 -0
- package/dist/lib/validateMintInputs.js +100 -0
- package/dist/lib/validateMintInputs.js.map +1 -0
- package/dist/nodes/TaliwareMint/TaliwareMint.node.d.ts +5 -0
- package/dist/nodes/TaliwareMint/TaliwareMint.node.js +101 -0
- package/dist/nodes/TaliwareMint/TaliwareMint.node.js.map +1 -0
- package/dist/nodes/TaliwareMint/TaliwareMint.node.json +21 -0
- package/dist/nodes/TaliwareMint/taliware.dark.svg +13 -0
- package/dist/nodes/TaliwareMint/taliware.svg +13 -0
- package/dist/package.json +59 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +59 -0
- package/workflows/README.md +33 -0
- package/workflows/agent-tool-mint.example.json +144 -0
- package/workflows/manual-mint-binary.example.json +83 -0
- package/workflows/manual-mint-testnet.example.json +60 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 TALIWARE
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
# n8n-nodes-taliware
|
|
2
|
+
|
|
3
|
+
TALIWARE CL2C biometric NFT mint node for [n8n](https://n8n.io/) — manually execute mints or expose **Mint Biometric NFT** as an AI Agent tool.
|
|
4
|
+
|
|
5
|
+
The node is a thin gate to the [CL2C API](https://developer.taliware.com/api/cl2c.yaml): resolve owner → create NFT → poll until `MINTED` or `FAILED` → return agent-readable JSON. Confida biometric approval happens on the owner's mobile device after create; this package does not embed the Confida SDK.
|
|
6
|
+
|
|
7
|
+
**Requirements:** n8n **≥ 1.79.0** (community AI Agent tools).
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
Goal: first successful testnet mint in under 30 minutes.
|
|
14
|
+
|
|
15
|
+
### 1. Install the community node
|
|
16
|
+
|
|
17
|
+
On your n8n host, set environment variables:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
N8N_COMMUNITY_PACKAGES_ENABLED=true
|
|
21
|
+
N8N_COMMUNITY_PACKAGES_ALLOW_TOOL_USAGE=true # required for AI Agent tools
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Restart n8n, then: **Settings → Community Nodes → Install** → enter `n8n-nodes-taliware`.
|
|
25
|
+
|
|
26
|
+
### 2. Create Taliware API credentials
|
|
27
|
+
|
|
28
|
+
In n8n: **Credentials → New → Taliware API**
|
|
29
|
+
|
|
30
|
+
| Field | Required | Notes |
|
|
31
|
+
|-------|----------|-------|
|
|
32
|
+
| API Key | Yes | Sent as `x-api-key` on CL2C requests only — never logged |
|
|
33
|
+
| Base URL | No | Default: `https://developer.taliware.com/api/v1` |
|
|
34
|
+
| Default Smart Contract ID | No | UUID of a contract with `env: TESTNET` for testnet mints |
|
|
35
|
+
|
|
36
|
+
**Testnet:** Use the same API host. Pick a smart contract where `env` is `TESTNET` (via [CL2C API](https://developer.taliware.com/api/cl2c.yaml) or TALIWARE platform). Set that UUID in credentials or override it on the node.
|
|
37
|
+
|
|
38
|
+
List contracts (example):
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
curl -s -H "x-api-key: YOUR_KEY" \
|
|
42
|
+
"https://developer.taliware.com/api/v1/cl2c/contract?limit=50" | jq '.data[] | {id, name, env, network}'
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### 3. Invite the NFT owner
|
|
46
|
+
|
|
47
|
+
The owner must exist on the TALIWARE platform before mint. Either:
|
|
48
|
+
|
|
49
|
+
- **Platform UI** — invite the user via the TALIWARE dashboard, or
|
|
50
|
+
- **API** — `POST /cl2c/user` with the owner's email:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
curl -s -X POST "https://developer.taliware.com/api/v1/cl2c/user" \
|
|
54
|
+
-H "x-api-key: YOUR_KEY" \
|
|
55
|
+
-H "Content-Type: application/json" \
|
|
56
|
+
-d '{"email":"owner@example.com"}'
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
The owner must complete Confida setup (see below) before mint can succeed.
|
|
60
|
+
|
|
61
|
+
**Owner User ID:** When resolving by email, the node uses the org entry `id` from `GET /cl2c/user` (UUID), **not** the nested `user.id` platform identifier. You can paste that UUID into **Owner User ID** to skip email lookup:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
curl -s -H "x-api-key: YOUR_KEY" \
|
|
65
|
+
"https://developer.taliware.com/api/v1/cl2c/user?search=owner@example.com" | jq '.data[] | {id, email, status}'
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Use the top-level `id` field in the mint request.
|
|
69
|
+
|
|
70
|
+
### 4. Run your first manual mint
|
|
71
|
+
|
|
72
|
+
1. Add **Mint Biometric NFT** to a workflow.
|
|
73
|
+
2. Select **Taliware API** credentials.
|
|
74
|
+
3. Set parameters:
|
|
75
|
+
- **Owner Email** (or **Owner User ID**)
|
|
76
|
+
- **Name** (required)
|
|
77
|
+
- **Image Path** — HTTPS URL, base64 (`data:image/...;base64,...` or raw), or leave empty and pass binary on the input item (see **Binary Property Name**)
|
|
78
|
+
- **Smart Contract ID** — leave empty to use credential default, or paste a TESTNET contract UUID
|
|
79
|
+
4. Click **Execute workflow**.
|
|
80
|
+
5. The owner receives a Confida mobile notification — complete fingerprint approval on device.
|
|
81
|
+
6. The node polls until `status` is `MINTED` or `FAILED` (default: 10 s interval, 20 min timeout).
|
|
82
|
+
|
|
83
|
+
On success, output includes `status: "MINTED"`, `mintedAt`, and `smartContract.contractAddress`.
|
|
84
|
+
|
|
85
|
+
**Mint from a local file:** Import [`workflows/manual-mint-binary.example.json`](workflows/manual-mint-binary.example.json) — **Read Binary File** (set `filePath` to your PNG/JPEG) → **Mint Biometric NFT** with **Image Path** empty and **Binary Property Name** `data`.
|
|
86
|
+
|
|
87
|
+
If Confida confirms but the node ends with `status: FAILED` and `mintedAt: null`, the create + IPFS + biometric steps succeeded; on-chain mint likely failed (e.g. unfunded org wallet / CRDB tokens). Retry after TALIWARE recharges testnet funds — no node change required.
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Confida (biometric approval)
|
|
92
|
+
|
|
93
|
+
TALIWARE orchestrates [Confida](https://developer.taliware.com/docs/confida) for biometric identity verification. This node **does not** embed the Confida SDK or capture biometrics inside n8n.
|
|
94
|
+
|
|
95
|
+
What happens:
|
|
96
|
+
|
|
97
|
+
1. Owner is invited to the platform and completes Confida setup on mobile.
|
|
98
|
+
2. `POST /cl2c/nft` creates the NFT with `status: CREATED` and triggers Confida notifications.
|
|
99
|
+
3. Owner approves on mobile (fingerprint).
|
|
100
|
+
4. This node polls `GET /cl2c/nft/{id}` until terminal status.
|
|
101
|
+
|
|
102
|
+
If the owner ignores the notification, polling hits the timeout — see **ConfidaTimeout** in [Error Reference](#error-reference).
|
|
103
|
+
|
|
104
|
+
Full Confida documentation: [developer.taliware.com/docs/confida](https://developer.taliware.com/docs/confida)
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## AI Agent tool
|
|
109
|
+
|
|
110
|
+
### Connect the tool
|
|
111
|
+
|
|
112
|
+
1. Confirm env vars from [Quick Start](#1-install-the-community-node) are set.
|
|
113
|
+
2. Add an **AI Agent** node to your workflow.
|
|
114
|
+
3. On the agent's **Tools** input, add **Mint Biometric NFT Tool** (the wrapped variant of this node).
|
|
115
|
+
4. Select credentials and configure poll/debug settings on the tool node if needed.
|
|
116
|
+
|
|
117
|
+
Agent-supplied parameters (via `$fromAI` when the tool is connected):
|
|
118
|
+
|
|
119
|
+
| Parameter | Required | Notes |
|
|
120
|
+
|-----------|----------|-------|
|
|
121
|
+
| `name` | Yes | NFT display name |
|
|
122
|
+
| `description` | No | Photo or artwork description |
|
|
123
|
+
| `imagePath` | No | HTTPS URL or base64 image for `MintRequest.imagePath` |
|
|
124
|
+
| `ownerEmail` | One of email/userId | Platform user email |
|
|
125
|
+
| `ownerUserId` | One of email/userId | Org entry `id` from `GET /cl2c/user`; skips email lookup when set |
|
|
126
|
+
| `smartContractId` | No | Overrides credential default |
|
|
127
|
+
| `ownershipPercentage` | No | Default 100 |
|
|
128
|
+
|
|
129
|
+
Manual **Execute** and **Tool** invoke share the same `execute()` code path.
|
|
130
|
+
|
|
131
|
+
### Tool output fields (for agent prompts)
|
|
132
|
+
|
|
133
|
+
On `MINTED`, the tool returns a single JSON item (under ~8 KB, no raw image bytes):
|
|
134
|
+
|
|
135
|
+
```json
|
|
136
|
+
{
|
|
137
|
+
"id": "uuid",
|
|
138
|
+
"status": "MINTED",
|
|
139
|
+
"name": "My Photo NFT",
|
|
140
|
+
"description": "…",
|
|
141
|
+
"imagePath": "https://…",
|
|
142
|
+
"externalUrl": "https://…",
|
|
143
|
+
"mintedAt": "2026-05-30T12:00:00.000Z",
|
|
144
|
+
"smartContract": {
|
|
145
|
+
"id": "uuid",
|
|
146
|
+
"contractAddress": "0x…",
|
|
147
|
+
"env": "TESTNET",
|
|
148
|
+
"network": "cordoba"
|
|
149
|
+
},
|
|
150
|
+
"copyright": [
|
|
151
|
+
{
|
|
152
|
+
"email": "owner@example.com",
|
|
153
|
+
"status": "…",
|
|
154
|
+
"percentage": 100,
|
|
155
|
+
"walletAddress": "0x…"
|
|
156
|
+
}
|
|
157
|
+
]
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Use `id`, `status`, `mintedAt`, `smartContract.contractAddress`, and `copyright[]` in agent system prompts so the model can confirm mint success to the user.
|
|
162
|
+
|
|
163
|
+
### Workflow Tool workaround (n8n #26202)
|
|
164
|
+
|
|
165
|
+
Some n8n versions have a [FIFO queue ordering bug](https://github.com/n8n-io/n8n/issues/26202) where AI Agents receive an **empty observation** from `usableAsTool` community nodes even though the tool executed successfully.
|
|
166
|
+
|
|
167
|
+
**Symptom:** Agent says the tool returned nothing; execution log shows the mint node succeeded with JSON output.
|
|
168
|
+
|
|
169
|
+
**Workaround:** Wrap the mint in a sub-workflow and connect it via n8n's native **Workflow Tool** (uses `supplyData`, not the `usableAsTool` wrapper):
|
|
170
|
+
|
|
171
|
+
1. Create a workflow with **Execute Workflow Trigger** (or **When Executed by Another Workflow**) → **Mint Biometric NFT** → return mapped JSON.
|
|
172
|
+
2. In your agent workflow, add **Workflow Tool** pointing at that sub-workflow instead of **Mint Biometric NFT Tool** directly.
|
|
173
|
+
3. Map tool inputs in the sub-workflow trigger to mint node parameters.
|
|
174
|
+
|
|
175
|
+
Upgrade n8n when a fix for #26202 is available in your release channel.
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## Error Reference
|
|
180
|
+
|
|
181
|
+
All failures use `NodeOperationError` with a prefix in the execution log:
|
|
182
|
+
|
|
183
|
+
| Prefix | Likely cause | Remediation |
|
|
184
|
+
|--------|--------------|-------------|
|
|
185
|
+
| **Configuration:** | Invalid or missing API key, bad base URL, missing default smart contract when node override is empty | Verify **Taliware API** credentials; set **Default Smart Contract ID** or node **Smart Contract ID** |
|
|
186
|
+
| **Validation:** | Missing name, missing owner email/userId, owner not found, invalid `imagePath`, CL2C 400/404 validation | Fix parameters before retry; invite owner via platform or `POST /cl2c/user` |
|
|
187
|
+
| **API:** | CL2C request failed, NFT `status: FAILED` after poll | Read message and API `details`; check contract env, owner Confida status, image data/URL |
|
|
188
|
+
| **ConfidaTimeout:** | Poll timeout — owner did not complete biometric approval in time | Ask owner to approve on mobile; increase **Poll Timeout Minutes**; node does **not** auto re-mint |
|
|
189
|
+
| **n8nTool:** | n8n tool-layer issues (e.g. empty observation from #26202) | Use [Workflow Tool workaround](#workflow-tool-workaround-n8n-26202); upgrade n8n |
|
|
190
|
+
|
|
191
|
+
Example messages:
|
|
192
|
+
|
|
193
|
+
- `Validation: Name is required`
|
|
194
|
+
- `Validation: Owner not found — user must be invited via TALIWARE platform or POST /cl2c/user`
|
|
195
|
+
- `Validation: imagePath must be an HTTPS URL, a data:image/...;base64,... URI, or raw base64 image data`
|
|
196
|
+
- `ConfidaTimeout: Mint approval timed out — Confida biometric approval may still be pending (id=…, status=CREATED)`
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## Reliability
|
|
201
|
+
|
|
202
|
+
### Duplicate mint on agent retries
|
|
203
|
+
|
|
204
|
+
CL2C v1.0.0 has **no idempotency key**. If an AI Agent retries a failed or timed-out tool call, each attempt creates a **new** NFT via `POST /cl2c/nft`. Design agent prompts and error handling to avoid blind retries after partial success (e.g. after create but before poll completes).
|
|
205
|
+
|
|
206
|
+
### HTTP 429 rate limits
|
|
207
|
+
|
|
208
|
+
The CL2C client retries up to 3 times with exponential backoff (1 s, 2 s, 4 s) on HTTP 429.
|
|
209
|
+
|
|
210
|
+
### Poll behaviour
|
|
211
|
+
|
|
212
|
+
The node polls until NFT-level `status` is `MINTED` or `FAILED`. Success is determined by `status === 'MINTED'`, not individual `copyright[].status` values. Defaults: 10 s interval, 20 min timeout (configurable on the node).
|
|
213
|
+
|
|
214
|
+
### Debug mode
|
|
215
|
+
|
|
216
|
+
Enable **Debug** on the node to log NFT `id`, poll count, and last `status` only — never API keys or full email addresses.
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
## Publishing
|
|
221
|
+
|
|
222
|
+
Version **0.1.0** is published to npm as [`n8n-nodes-taliware`](https://www.npmjs.com/package/n8n-nodes-taliware).
|
|
223
|
+
|
|
224
|
+
### Local checks before release
|
|
225
|
+
|
|
226
|
+
```bash
|
|
227
|
+
npm run lint
|
|
228
|
+
npm run build
|
|
229
|
+
npm pack --dry-run # verify tarball: dist/, workflows/, README, LICENSE, CHANGELOG only
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
The package `files` field includes only `dist/` and `workflows/` — no BMad or planning artifacts are shipped.
|
|
233
|
+
|
|
234
|
+
### Release to npm (with provenance)
|
|
235
|
+
|
|
236
|
+
1. Configure [npm Trusted Publishing](https://docs.npmjs.com/trusted-publishers) (OIDC) on npmjs.com for this repo's `publish.yml` workflow, or set `NPM_TOKEN` in GitHub secrets.
|
|
237
|
+
2. Locally bump and tag (does **not** publish from your machine):
|
|
238
|
+
|
|
239
|
+
```bash
|
|
240
|
+
npm run release
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
3. Push the tag (e.g. `0.1.0`) — GitHub Actions runs `.github/workflows/publish.yml`, which lint/builds and runs `npm publish` with `NPM_CONFIG_PROVENANCE=true`.
|
|
244
|
+
|
|
245
|
+
Example workflows for post-publish validation are in [`workflows/`](workflows/).
|
|
246
|
+
|
|
247
|
+
---
|
|
248
|
+
|
|
249
|
+
## Development
|
|
250
|
+
|
|
251
|
+
**Requirements:** Node.js ≥ 22.16 (n8n engine), npm. For local `npm run dev` with bundled n8n, **Node 22 LTS** is recommended — Node 24 may fail on native `isolated-vm` builds.
|
|
252
|
+
|
|
253
|
+
```bash
|
|
254
|
+
cd n8n-nodes-taliware
|
|
255
|
+
npm install # uses .npmrc ignore-scripts=true for @n8n/node-cli
|
|
256
|
+
npm run build
|
|
257
|
+
npm run lint
|
|
258
|
+
npm run dev # symlinks to ~/.n8n-node-cli and starts n8n + tsc watch
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
### Local n8n test (while testnet tokens recharge)
|
|
262
|
+
|
|
263
|
+
1. `npm run build && npm run dev` (or `docker compose up` after build).
|
|
264
|
+
2. Open http://localhost:5678 → **Credentials → Taliware API**:
|
|
265
|
+
- **API Key:** your `n8nplugin…` CL2C key (`x-api-key`, not Bearer)
|
|
266
|
+
- **Default Smart Contract ID:** TESTNET contract UUID
|
|
267
|
+
3. Import `workflows/manual-mint-binary.example.json`.
|
|
268
|
+
4. Set **Read Binary File → filePath** to a local image (e.g. `scripts/fixtures/testest.png` during dev).
|
|
269
|
+
5. Set **Owner Email** to a Confida-ready ACTIVE user; leave **Image Path** empty.
|
|
270
|
+
6. Execute → approve Confida on mobile → node polls until `MINTED` or `FAILED`.
|
|
271
|
+
|
|
272
|
+
See [`scripts/README.md`](scripts/README.md) for curl smoke tests without n8n.
|
|
273
|
+
|
|
274
|
+
**External n8n:**
|
|
275
|
+
|
|
276
|
+
```bash
|
|
277
|
+
# Terminal 1
|
|
278
|
+
npm run dev -- --external-n8n
|
|
279
|
+
|
|
280
|
+
# Terminal 2
|
|
281
|
+
N8N_DEV_RELOAD=true N8N_USER_FOLDER=$HOME/.n8n-node-cli n8n start
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
|
|
286
|
+
## Resources
|
|
287
|
+
|
|
288
|
+
- [CL2C OpenAPI spec (cl2c.yaml)](https://developer.taliware.com/api/cl2c.yaml)
|
|
289
|
+
- [Confida documentation](https://developer.taliware.com/docs/confida)
|
|
290
|
+
- [n8n community nodes](https://docs.n8n.io/integrations/community-nodes/)
|
|
291
|
+
- [n8n $fromAI() function](https://docs.n8n.io/advanced-ai/examples/using-the-fromai-function/)
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ICredentialTestRequest, ICredentialType, INodeProperties, Icon } from 'n8n-workflow';
|
|
2
|
+
export declare class TaliwareApi implements ICredentialType {
|
|
3
|
+
name: string;
|
|
4
|
+
displayName: string;
|
|
5
|
+
icon: Icon;
|
|
6
|
+
documentationUrl: string;
|
|
7
|
+
properties: INodeProperties[];
|
|
8
|
+
test: ICredentialTestRequest;
|
|
9
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TaliwareApi = void 0;
|
|
4
|
+
const DEFAULT_BASE_URL = 'https://developer.taliware.com/api/v1';
|
|
5
|
+
class TaliwareApi {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.name = 'taliwareApi';
|
|
8
|
+
this.displayName = 'Taliware API';
|
|
9
|
+
this.icon = {
|
|
10
|
+
light: 'file:icons/taliware.svg',
|
|
11
|
+
dark: 'file:icons/taliware.dark.svg',
|
|
12
|
+
};
|
|
13
|
+
this.documentationUrl = 'https://developer.taliware.com/docs/api';
|
|
14
|
+
this.properties = [
|
|
15
|
+
{
|
|
16
|
+
displayName: 'API Key',
|
|
17
|
+
name: 'apiKey',
|
|
18
|
+
type: 'string',
|
|
19
|
+
typeOptions: { password: true },
|
|
20
|
+
required: true,
|
|
21
|
+
default: '',
|
|
22
|
+
description: 'Organization API key from the TALIWARE Developer Platform',
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
displayName: 'Base URL',
|
|
26
|
+
name: 'baseUrl',
|
|
27
|
+
type: 'string',
|
|
28
|
+
default: DEFAULT_BASE_URL,
|
|
29
|
+
description: 'CL2C API base URL (testnet uses the same host; select a TESTNET contract id)',
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
displayName: 'Default Smart Contract ID',
|
|
33
|
+
name: 'defaultSmartContractId',
|
|
34
|
+
type: 'string',
|
|
35
|
+
default: '',
|
|
36
|
+
description: 'Optional default contract UUID for mint operations',
|
|
37
|
+
},
|
|
38
|
+
];
|
|
39
|
+
this.test = {
|
|
40
|
+
request: {
|
|
41
|
+
baseURL: '={{$credentials.baseUrl}}',
|
|
42
|
+
url: '/cl2c/user',
|
|
43
|
+
qs: { limit: '1' },
|
|
44
|
+
headers: {
|
|
45
|
+
'x-api-key': '={{$credentials.apiKey}}',
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
exports.TaliwareApi = TaliwareApi;
|
|
52
|
+
//# sourceMappingURL=TaliwareApi.credentials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TaliwareApi.credentials.js","sourceRoot":"","sources":["../../credentials/TaliwareApi.credentials.ts"],"names":[],"mappings":";;;AAOA,MAAM,gBAAgB,GAAG,uCAAuC,CAAC;AAEjE,MAAa,WAAW;IAAxB;QACC,SAAI,GAAG,aAAa,CAAC;QAErB,gBAAW,GAAG,cAAc,CAAC;QAE7B,SAAI,GAAS;YACZ,KAAK,EAAE,yBAAyB;YAChC,IAAI,EAAE,8BAA8B;SACpC,CAAC;QAEF,qBAAgB,GAAG,yCAAyC,CAAC;QAE7D,eAAU,GAAsB;YAC/B;gBACC,WAAW,EAAE,SAAS;gBACtB,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;gBAC/B,QAAQ,EAAE,IAAI;gBACd,OAAO,EAAE,EAAE;gBACX,WAAW,EAAE,2DAA2D;aACxE;YACD;gBACC,WAAW,EAAE,UAAU;gBACvB,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,gBAAgB;gBACzB,WAAW,EAAE,8EAA8E;aAC3F;YACD;gBACC,WAAW,EAAE,2BAA2B;gBACxC,IAAI,EAAE,wBAAwB;gBAC9B,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,EAAE;gBACX,WAAW,EAAE,oDAAoD;aACjE;SACD,CAAC;QAEF,SAAI,GAA2B;YAC9B,OAAO,EAAE;gBACR,OAAO,EAAE,2BAA2B;gBACpC,GAAG,EAAE,YAAY;gBACjB,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE;gBAClB,OAAO,EAAE;oBACR,WAAW,EAAE,0BAA0B;iBACvC;aACD;SACD,CAAC;IACH,CAAC;CAAA;AAhDD,kCAgDC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="aquamarine"
|
|
2
|
+
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-cpu">
|
|
3
|
+
<rect x="4" y="4" width="16" height="16" rx="2" ry="2"></rect>
|
|
4
|
+
<rect x="9" y="9" width="6" height="6"></rect>
|
|
5
|
+
<line x1="9" y1="1" x2="9" y2="4"></line>
|
|
6
|
+
<line x1="15" y1="1" x2="15" y2="4"></line>
|
|
7
|
+
<line x1="9" y1="20" x2="9" y2="23"></line>
|
|
8
|
+
<line x1="15" y1="20" x2="15" y2="23"></line>
|
|
9
|
+
<line x1="20" y1="9" x2="23" y2="9"></line>
|
|
10
|
+
<line x1="20" y1="14" x2="23" y2="14"></line>
|
|
11
|
+
<line x1="1" y1="9" x2="4" y2="9"></line>
|
|
12
|
+
<line x1="1" y1="14" x2="4" y2="14"></line>
|
|
13
|
+
</svg>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="darkblue"
|
|
2
|
+
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-cpu">
|
|
3
|
+
<rect x="4" y="4" width="16" height="16" rx="2" ry="2"></rect>
|
|
4
|
+
<rect x="9" y="9" width="6" height="6"></rect>
|
|
5
|
+
<line x1="9" y1="1" x2="9" y2="4"></line>
|
|
6
|
+
<line x1="15" y1="1" x2="15" y2="4"></line>
|
|
7
|
+
<line x1="9" y1="20" x2="9" y2="23"></line>
|
|
8
|
+
<line x1="15" y1="20" x2="15" y2="23"></line>
|
|
9
|
+
<line x1="20" y1="9" x2="23" y2="9"></line>
|
|
10
|
+
<line x1="20" y1="14" x2="23" y2="14"></line>
|
|
11
|
+
<line x1="1" y1="9" x2="4" y2="9"></line>
|
|
12
|
+
<line x1="1" y1="14" x2="4" y2="14"></line>
|
|
13
|
+
</svg>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { INode } from 'n8n-workflow';
|
|
2
|
+
import type { TaliwareApiCredentials } from './types';
|
|
3
|
+
export interface Cl2cRequestOptions {
|
|
4
|
+
method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
5
|
+
path: string;
|
|
6
|
+
query?: Record<string, string | number | undefined>;
|
|
7
|
+
body?: unknown;
|
|
8
|
+
}
|
|
9
|
+
export declare class Cl2cClient {
|
|
10
|
+
private readonly credentials;
|
|
11
|
+
private readonly node;
|
|
12
|
+
constructor(credentials: TaliwareApiCredentials, node: INode);
|
|
13
|
+
request<T>(options: Cl2cRequestOptions): Promise<T>;
|
|
14
|
+
private buildUrl;
|
|
15
|
+
private parseResponse;
|
|
16
|
+
private assertCl2cPath;
|
|
17
|
+
}
|
|
18
|
+
export declare function createCl2cClient(credentials: TaliwareApiCredentials, node: INode): Cl2cClient;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Cl2cClient = void 0;
|
|
4
|
+
exports.createCl2cClient = createCl2cClient;
|
|
5
|
+
const n8n_workflow_1 = require("n8n-workflow");
|
|
6
|
+
const errors_1 = require("./errors");
|
|
7
|
+
const MAX_429_RETRIES = 3;
|
|
8
|
+
const INITIAL_BACKOFF_MS = 1000;
|
|
9
|
+
class Cl2cClient {
|
|
10
|
+
constructor(credentials, node) {
|
|
11
|
+
this.credentials = credentials;
|
|
12
|
+
this.node = node;
|
|
13
|
+
}
|
|
14
|
+
async request(options) {
|
|
15
|
+
this.assertCl2cPath(options.path);
|
|
16
|
+
for (let attempt = 0; attempt <= MAX_429_RETRIES; attempt++) {
|
|
17
|
+
const response = await fetch(this.buildUrl(options), {
|
|
18
|
+
method: options.method,
|
|
19
|
+
headers: {
|
|
20
|
+
'Content-Type': 'application/json',
|
|
21
|
+
'x-api-key': this.credentials.apiKey,
|
|
22
|
+
},
|
|
23
|
+
body: options.body !== undefined ? JSON.stringify(options.body) : undefined,
|
|
24
|
+
});
|
|
25
|
+
if (response.status === 429 && attempt < MAX_429_RETRIES) {
|
|
26
|
+
await (0, n8n_workflow_1.sleep)(INITIAL_BACKOFF_MS * Math.pow(2, attempt));
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
return await this.parseResponse(response);
|
|
30
|
+
}
|
|
31
|
+
throw (0, errors_1.configurationError)(this.node, 'Exceeded maximum retries for rate-limited CL2C request');
|
|
32
|
+
}
|
|
33
|
+
buildUrl(options) {
|
|
34
|
+
const url = new URL(options.path.startsWith('/') ? options.path.slice(1) : options.path, `${this.credentials.baseUrl}/`);
|
|
35
|
+
if (options.query) {
|
|
36
|
+
for (const [key, value] of Object.entries(options.query)) {
|
|
37
|
+
if (value !== undefined && value !== '') {
|
|
38
|
+
url.searchParams.set(key, String(value));
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return url.toString();
|
|
43
|
+
}
|
|
44
|
+
async parseResponse(response) {
|
|
45
|
+
if (response.status === 401) {
|
|
46
|
+
throw (0, errors_1.configurationError)(this.node, errors_1.INVALID_API_KEY_MESSAGE);
|
|
47
|
+
}
|
|
48
|
+
const payload = await readResponseBody(response);
|
|
49
|
+
if (!response.ok) {
|
|
50
|
+
throw (0, errors_1.httpErrorFromResponse)(this.node, response.status, payload, `HTTP ${response.status}: CL2C request failed`);
|
|
51
|
+
}
|
|
52
|
+
return payload;
|
|
53
|
+
}
|
|
54
|
+
assertCl2cPath(path) {
|
|
55
|
+
const normalized = path.startsWith('/') ? path : `/${path}`;
|
|
56
|
+
if (!normalized.startsWith('/cl2c/')) {
|
|
57
|
+
throw (0, errors_1.configurationError)(this.node, `Invalid CL2C path: ${normalized}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
exports.Cl2cClient = Cl2cClient;
|
|
62
|
+
function createCl2cClient(credentials, node) {
|
|
63
|
+
return new Cl2cClient(credentials, node);
|
|
64
|
+
}
|
|
65
|
+
async function readResponseBody(response) {
|
|
66
|
+
const text = await response.text();
|
|
67
|
+
if (!text) {
|
|
68
|
+
return undefined;
|
|
69
|
+
}
|
|
70
|
+
try {
|
|
71
|
+
return JSON.parse(text);
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return text;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=cl2cClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cl2cClient.js","sourceRoot":"","sources":["../../lib/cl2cClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Cl2cClient } from './cl2cClient';
|
|
2
|
+
import { type NftDetail } from './types';
|
|
3
|
+
export interface CreateNftInput {
|
|
4
|
+
name: string;
|
|
5
|
+
smartContractId: string;
|
|
6
|
+
userId: string;
|
|
7
|
+
ownershipPercentage: number;
|
|
8
|
+
description?: string;
|
|
9
|
+
imagePath?: string;
|
|
10
|
+
externalUrl?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function createNft(client: Cl2cClient, input: CreateNftInput): Promise<NftDetail>;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createNft = createNft;
|
|
4
|
+
const types_1 = require("./types");
|
|
5
|
+
async function createNft(client, input) {
|
|
6
|
+
var _a, _b, _c;
|
|
7
|
+
const body = {
|
|
8
|
+
name: input.name.trim(),
|
|
9
|
+
smartContractId: input.smartContractId,
|
|
10
|
+
supply: 1,
|
|
11
|
+
copyright: [
|
|
12
|
+
{
|
|
13
|
+
userId: input.userId,
|
|
14
|
+
percentage: input.ownershipPercentage,
|
|
15
|
+
},
|
|
16
|
+
],
|
|
17
|
+
};
|
|
18
|
+
const description = (_a = input.description) === null || _a === void 0 ? void 0 : _a.trim();
|
|
19
|
+
if (description) {
|
|
20
|
+
body.description = description;
|
|
21
|
+
}
|
|
22
|
+
const imagePath = (_b = input.imagePath) === null || _b === void 0 ? void 0 : _b.trim();
|
|
23
|
+
if (imagePath) {
|
|
24
|
+
body.imagePath = imagePath;
|
|
25
|
+
}
|
|
26
|
+
const externalUrl = (_c = input.externalUrl) === null || _c === void 0 ? void 0 : _c.trim();
|
|
27
|
+
if (externalUrl) {
|
|
28
|
+
body.externalUrl = externalUrl;
|
|
29
|
+
}
|
|
30
|
+
return await client.request({
|
|
31
|
+
method: 'POST',
|
|
32
|
+
path: types_1.CL2C_PATHS.nft,
|
|
33
|
+
body,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=createNft.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createNft.js","sourceRoot":"","sources":["../../lib/createNft.ts"],"names":[],"mappings":";;AAaA,8BAoCC;AAhDD,mCAAuE;AAYhE,KAAK,UAAU,SAAS,CAC9B,MAAkB,EAClB,KAAqB;;IAErB,MAAM,IAAI,GAAgB;QACzB,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE;QACvB,eAAe,EAAE,KAAK,CAAC,eAAe;QACtC,MAAM,EAAE,CAAC;QACT,SAAS,EAAE;YACV;gBACC,MAAM,EAAE,KAAK,CAAC,MAAM;gBACpB,UAAU,EAAE,KAAK,CAAC,mBAAmB;aACrC;SACD;KACD,CAAC;IAEF,MAAM,WAAW,GAAG,MAAA,KAAK,CAAC,WAAW,0CAAE,IAAI,EAAE,CAAC;IAC9C,IAAI,WAAW,EAAE,CAAC;QACjB,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;IAChC,CAAC;IAED,MAAM,SAAS,GAAG,MAAA,KAAK,CAAC,SAAS,0CAAE,IAAI,EAAE,CAAC;IAC1C,IAAI,SAAS,EAAE,CAAC;QACf,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC5B,CAAC;IAED,MAAM,WAAW,GAAG,MAAA,KAAK,CAAC,WAAW,0CAAE,IAAI,EAAE,CAAC;IAC9C,IAAI,WAAW,EAAE,CAAC;QACjB,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;IAChC,CAAC;IAED,OAAO,MAAM,MAAM,CAAC,OAAO,CAAY;QACtC,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,kBAAU,CAAC,GAAG;QACpB,IAAI;KACJ,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { INode } from 'n8n-workflow';
|
|
2
|
+
import { NodeOperationError } from 'n8n-workflow';
|
|
3
|
+
import type { Cl2cErrorResponse } from './types';
|
|
4
|
+
export type ErrorPrefix = 'Configuration' | 'Validation' | 'API' | 'ConfidaTimeout' | 'n8nTool';
|
|
5
|
+
export declare function prefixedError(prefix: ErrorPrefix, message: string): string;
|
|
6
|
+
export declare function createNodeError(node: INode, prefix: ErrorPrefix, message: string): NodeOperationError;
|
|
7
|
+
export declare function configurationError(node: INode, message: string): NodeOperationError;
|
|
8
|
+
export declare function validationError(node: INode, message: string): NodeOperationError;
|
|
9
|
+
export declare function apiError(node: INode, message: string): NodeOperationError;
|
|
10
|
+
export declare function confidaTimeoutError(node: INode, message: string): NodeOperationError;
|
|
11
|
+
export declare function n8nToolError(node: INode, message: string): NodeOperationError;
|
|
12
|
+
export declare const INVALID_API_KEY_MESSAGE = "Invalid API key or unauthorized access";
|
|
13
|
+
export declare function formatCl2cApiErrorMessage(payload: unknown, fallback?: string): string;
|
|
14
|
+
export declare function apiErrorFromPayload(node: INode, payload: unknown, fallback?: string): NodeOperationError;
|
|
15
|
+
export declare function httpErrorFromResponse(node: INode, status: number, payload: unknown, fallback?: string): NodeOperationError;
|
|
16
|
+
export declare function isCl2cErrorResponse(payload: unknown): payload is Cl2cErrorResponse;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.INVALID_API_KEY_MESSAGE = void 0;
|
|
4
|
+
exports.prefixedError = prefixedError;
|
|
5
|
+
exports.createNodeError = createNodeError;
|
|
6
|
+
exports.configurationError = configurationError;
|
|
7
|
+
exports.validationError = validationError;
|
|
8
|
+
exports.apiError = apiError;
|
|
9
|
+
exports.confidaTimeoutError = confidaTimeoutError;
|
|
10
|
+
exports.n8nToolError = n8nToolError;
|
|
11
|
+
exports.formatCl2cApiErrorMessage = formatCl2cApiErrorMessage;
|
|
12
|
+
exports.apiErrorFromPayload = apiErrorFromPayload;
|
|
13
|
+
exports.httpErrorFromResponse = httpErrorFromResponse;
|
|
14
|
+
exports.isCl2cErrorResponse = isCl2cErrorResponse;
|
|
15
|
+
const n8n_workflow_1 = require("n8n-workflow");
|
|
16
|
+
function prefixedError(prefix, message) {
|
|
17
|
+
return `${prefix}: ${message}`;
|
|
18
|
+
}
|
|
19
|
+
function createNodeError(node, prefix, message) {
|
|
20
|
+
return new n8n_workflow_1.NodeOperationError(node, prefixedError(prefix, message));
|
|
21
|
+
}
|
|
22
|
+
function configurationError(node, message) {
|
|
23
|
+
return createNodeError(node, 'Configuration', message);
|
|
24
|
+
}
|
|
25
|
+
function validationError(node, message) {
|
|
26
|
+
return createNodeError(node, 'Validation', message);
|
|
27
|
+
}
|
|
28
|
+
function apiError(node, message) {
|
|
29
|
+
return createNodeError(node, 'API', message);
|
|
30
|
+
}
|
|
31
|
+
function confidaTimeoutError(node, message) {
|
|
32
|
+
return createNodeError(node, 'ConfidaTimeout', message);
|
|
33
|
+
}
|
|
34
|
+
function n8nToolError(node, message) {
|
|
35
|
+
return createNodeError(node, 'n8nTool', message);
|
|
36
|
+
}
|
|
37
|
+
exports.INVALID_API_KEY_MESSAGE = 'Invalid API key or unauthorized access';
|
|
38
|
+
function formatCl2cApiErrorMessage(payload, fallback = 'API request failed') {
|
|
39
|
+
if (!payload || typeof payload !== 'object') {
|
|
40
|
+
return fallback;
|
|
41
|
+
}
|
|
42
|
+
const record = payload;
|
|
43
|
+
const parts = [];
|
|
44
|
+
if (typeof record.error === 'string' && record.error.trim()) {
|
|
45
|
+
parts.push(record.error.trim());
|
|
46
|
+
}
|
|
47
|
+
if (Array.isArray(record.details)) {
|
|
48
|
+
const detailMessages = record.details.filter((entry) => typeof entry === 'string' && entry.trim().length > 0);
|
|
49
|
+
if (detailMessages.length > 0) {
|
|
50
|
+
parts.push(detailMessages.join('; '));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return parts.length > 0 ? parts.join(' — ') : fallback;
|
|
54
|
+
}
|
|
55
|
+
function apiErrorFromPayload(node, payload, fallback) {
|
|
56
|
+
return apiError(node, formatCl2cApiErrorMessage(payload, fallback));
|
|
57
|
+
}
|
|
58
|
+
function httpErrorFromResponse(node, status, payload, fallback) {
|
|
59
|
+
const message = formatCl2cApiErrorMessage(payload, fallback !== null && fallback !== void 0 ? fallback : `HTTP ${status}: CL2C request failed`);
|
|
60
|
+
if (status === 400 || status === 404) {
|
|
61
|
+
return validationError(node, message);
|
|
62
|
+
}
|
|
63
|
+
return apiError(node, message);
|
|
64
|
+
}
|
|
65
|
+
function isCl2cErrorResponse(payload) {
|
|
66
|
+
return Boolean(payload && typeof payload === 'object' && 'error' in payload);
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../lib/errors.ts"],"names":[],"mappings":"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"}
|