@hsuite/smart-engines-sdk 3.0.0 → 3.0.2
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 +11 -0
- package/README.md +251 -282
- package/dist/index.d.ts +3 -76
- package/dist/index.js +0 -299
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -18,3 +18,14 @@
|
|
|
18
18
|
```
|
|
19
19
|
npm publish --access=public
|
|
20
20
|
```
|
|
21
|
+
|
|
22
|
+
## 3.0.1 — 2026-05-11
|
|
23
|
+
|
|
24
|
+
**Documentation-only fix.** No code changes.
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
- README rewritten end-to-end. The 3.0.0 README documented a non-existent
|
|
28
|
+
`apiKey` connect flow and Hedera-centric examples that contradicted the
|
|
29
|
+
XRPL-canonical architecture. The new README shows the actual Web3
|
|
30
|
+
challenge-response auth pattern, all BaaS sub-clients, the NestJS
|
|
31
|
+
integration, resilience primitives, and accurate peer-dep guidance.
|
package/README.md
CHANGED
|
@@ -1,373 +1,342 @@
|
|
|
1
1
|
# @hsuite/smart-engines-sdk
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
Client SDK for the [Smart Engines V3](https://hsuite.finance) multi-chain
|
|
4
|
+
platform. Build smart-apps and smart-agents that authenticate via Web3
|
|
5
|
+
challenge-response, talk to the network's BaaS surface (database, storage,
|
|
6
|
+
messaging, functions, deployment), and execute chain operations across
|
|
7
|
+
Hedera, XRPL, Polkadot, Solana, Stellar, EVM, and Bitcoin.
|
|
6
8
|
|
|
7
9
|
```bash
|
|
8
|
-
yarn add @hsuite/smart-engines-sdk
|
|
9
|
-
# or
|
|
10
10
|
npm install @hsuite/smart-engines-sdk
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
Plus the peer deps your app actually uses:
|
|
14
14
|
|
|
15
|
-
```
|
|
16
|
-
|
|
15
|
+
```bash
|
|
16
|
+
npm install xrpl # required — XRPL is canonical for auth
|
|
17
|
+
npm install @hashgraph/sdk # only if your app does Hedera-side ops
|
|
18
|
+
npm install @nestjs/common @nestjs/core # only if you use the NestJS integration
|
|
19
|
+
npm install zod # peer (likely transitive in your app already)
|
|
20
|
+
```
|
|
17
21
|
|
|
18
|
-
|
|
19
|
-
const client = new SmartEngineClient({
|
|
20
|
-
baseUrl: 'https://v3-testnet-sn1.hsuite.network',
|
|
21
|
-
apiKey: 'your-api-key',
|
|
22
|
-
});
|
|
22
|
+
---
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
const health = await client.getHealth();
|
|
26
|
-
console.log(health.status); // 'ok'
|
|
27
|
-
```
|
|
24
|
+
## Quick start — Web3 auth + register a smart-app
|
|
28
25
|
|
|
29
|
-
|
|
26
|
+
The canonical smart-app bootstrap flow:
|
|
30
27
|
|
|
31
|
-
|
|
28
|
+
```ts
|
|
29
|
+
import { BaasClient } from '@hsuite/smart-engines-sdk';
|
|
30
|
+
import { Wallet } from 'xrpl';
|
|
31
|
+
import { sign as xrplSign } from 'ripple-keypairs';
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
import { PrivateKey } from '@hashgraph/sdk';
|
|
33
|
+
// 1. Your XRPL wallet (real production: load XRPL_SEED from env / secret store)
|
|
34
|
+
const wallet = Wallet.fromSeed(process.env.XRPL_SEED!);
|
|
36
35
|
|
|
37
|
-
|
|
36
|
+
// 2. Construct the BaaS client
|
|
37
|
+
const baas = new BaasClient({
|
|
38
|
+
hostUrl: 'https://v3-testnet-gateway.hsuite.network',
|
|
39
|
+
appId: 'pending', // will be replaced after register()
|
|
40
|
+
pathPrefix: '/host', // gateway routes /host/* → smart-host
|
|
41
|
+
});
|
|
38
42
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
chain: '
|
|
43
|
-
|
|
44
|
-
publicKey:
|
|
45
|
-
signFn: (
|
|
46
|
-
const
|
|
47
|
-
return
|
|
43
|
+
// 3. Authenticate via Web3 challenge-response
|
|
44
|
+
// Cluster verifies with ripple-keypairs.verify(messageHex.toUpperCase(), signature, publicKey)
|
|
45
|
+
await baas.authenticate({
|
|
46
|
+
chain: 'xrpl',
|
|
47
|
+
walletAddress: wallet.address,
|
|
48
|
+
publicKey: wallet.publicKey,
|
|
49
|
+
signFn: (message) => {
|
|
50
|
+
const messageHex = Buffer.from(message, 'utf-8').toString('hex').toUpperCase();
|
|
51
|
+
return xrplSign(messageHex, wallet.privateKey);
|
|
48
52
|
},
|
|
49
53
|
});
|
|
50
54
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
55
|
+
// 4. Register a free_testnet smart-app (no HSUITE deposit on testnet; cluster runs DKG)
|
|
56
|
+
const app = await baas.register({
|
|
57
|
+
name: 'My Smart App',
|
|
58
|
+
services: ['database', 'storage', 'messaging', 'functions'],
|
|
59
|
+
});
|
|
56
60
|
|
|
57
|
-
|
|
61
|
+
console.log(`Registered smart-app ${app.appId} — status: ${app.status}`);
|
|
62
|
+
baas.setAppId(app.appId);
|
|
63
|
+
```
|
|
58
64
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
validatorTopicId: '0.0.98765',
|
|
66
|
-
});
|
|
67
|
-
console.log(`Account: ${account.accountId}`);
|
|
65
|
+
**Why XRPL?** Per the Smart Engines V3 architecture, XRPL is canonical for
|
|
66
|
+
smart-app authentication and registration. The cluster's validator/host pods
|
|
67
|
+
pay their own HCS fees from pod-local operator accounts; smart-apps never
|
|
68
|
+
need Hedera credentials for the framework. Smart-apps can still target any
|
|
69
|
+
chain (Hedera, Solana, …) for their own *business logic* — that's separate
|
|
70
|
+
from the dev wallet used to authenticate.
|
|
68
71
|
|
|
69
|
-
|
|
70
|
-
const info = await client.getAccountInfo('hedera', '0.0.12345');
|
|
72
|
+
**Faster bootstrap?** Use the [`@hsuite/smart-engines-cli`](https://www.npmjs.com/package/@hsuite/smart-engines-cli) — `hsuite init` generates a fresh XRPL wallet + funds it via the testnet faucet + writes `.env.local`, then `hsuite subscribe` registers the smart-app in one command.
|
|
71
73
|
|
|
72
|
-
|
|
73
|
-
const balance = await client.getBalance('hedera', '0.0.12345');
|
|
74
|
-
console.log(`Balance: ${balance.balance} | Tokens: ${balance.tokens.length}`);
|
|
75
|
-
```
|
|
74
|
+
---
|
|
76
75
|
|
|
77
|
-
|
|
76
|
+
## Available clients
|
|
78
77
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
validatorTimestamp: '1766490325.123456789',
|
|
89
|
-
validatorTopicId: '0.0.98765',
|
|
90
|
-
capabilities: {
|
|
91
|
-
mintable: true,
|
|
92
|
-
burnable: true,
|
|
93
|
-
pausable: true,
|
|
94
|
-
restrictable: true,
|
|
95
|
-
compliant: true,
|
|
96
|
-
wipeable: true,
|
|
97
|
-
},
|
|
98
|
-
});
|
|
99
|
-
console.log(`Token: ${token.tokenId}`);
|
|
78
|
+
| Client | Purpose |
|
|
79
|
+
|---|---|
|
|
80
|
+
| `BaasClient` | Authentication + database + storage + functions + messaging + deployment + agents |
|
|
81
|
+
| `SmartEngineClient` | Chain operations: account create, token create / mint / burn / freeze / wipe, transfers, HCS topics, TSS, IPFS |
|
|
82
|
+
| `SmartGatewayClient` | Gateway operations: routing, domains, DNS |
|
|
83
|
+
| `ValidatorAuthClient` | Standalone Web3 challenge-response auth (lower-level than `BaasClient.authenticate`) |
|
|
84
|
+
| `ValidatorDiscoveryClient` | HCS-registry-based validator discovery |
|
|
85
|
+
| `TSSClient`, `IPFSClient`, `TransactionsClient`, `SettlementClient`, `SnapshotsClient` | Direct sub-client access for advanced flows |
|
|
86
|
+
| `MirrorNodeClient` | Hedera mirror-node helper (when your app does Hedera-side queries) |
|
|
100
87
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
chain: 'hedera',
|
|
104
|
-
tokenId: token.tokenId,
|
|
105
|
-
amount: '500000',
|
|
106
|
-
});
|
|
88
|
+
All clients accept the same `pathPrefix: '/host'` option when consumed via
|
|
89
|
+
the cluster gateway. Set `pathPrefix: ''` for direct host access.
|
|
107
90
|
|
|
108
|
-
|
|
109
|
-
await client.burnToken({
|
|
110
|
-
chain: 'hedera',
|
|
111
|
-
tokenId: token.tokenId,
|
|
112
|
-
amount: '100',
|
|
113
|
-
});
|
|
91
|
+
---
|
|
114
92
|
|
|
115
|
-
|
|
116
|
-
const tokenInfo = await client.getTokenInfo('hedera', token.tokenId);
|
|
117
|
-
console.log(`Supply: ${tokenInfo.totalSupply}`);
|
|
118
|
-
console.log(`Capabilities:`, tokenInfo.capabilities);
|
|
119
|
-
```
|
|
93
|
+
## BaaS sub-clients
|
|
120
94
|
|
|
121
|
-
|
|
95
|
+
Once authenticated, every BaaS sub-client is reachable from a single
|
|
96
|
+
`BaasClient` instance:
|
|
122
97
|
|
|
123
|
-
|
|
124
|
-
// Pause all operations on a token
|
|
125
|
-
await client.pauseToken({ chain: 'hedera', tokenId: '0.0.123' });
|
|
126
|
-
await client.unpauseToken({ chain: 'hedera', tokenId: '0.0.123' });
|
|
98
|
+
### Database (Merkle-anchored key-value store)
|
|
127
99
|
|
|
128
|
-
|
|
129
|
-
await
|
|
130
|
-
|
|
100
|
+
```ts
|
|
101
|
+
const record = await baas.db.insert('users', { name: 'Alice', role: 'developer' });
|
|
102
|
+
// → { document, stateTransition: { merkleProof, stateRoot, ... } }
|
|
131
103
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
await client.disableCompliance({ chain: 'hedera', tokenId: '0.0.123', accountId: '0.0.456' });
|
|
104
|
+
const found = await baas.db.find('users', { role: 'developer' });
|
|
105
|
+
// → { documents: [...], count }
|
|
135
106
|
|
|
136
|
-
|
|
137
|
-
await
|
|
107
|
+
const updated = await baas.db.update('users', record.document._id, { role: 'admin' });
|
|
108
|
+
await baas.db.delete('users', record.document._id);
|
|
138
109
|
```
|
|
139
110
|
|
|
140
|
-
|
|
111
|
+
Every write returns a cryptographic state-transition proof anchored on-chain — verifiable without re-reading the DB.
|
|
141
112
|
|
|
142
|
-
|
|
143
|
-
// Transfer native currency
|
|
144
|
-
const tx = await client.transfer({
|
|
145
|
-
chain: 'hedera',
|
|
146
|
-
from: '0.0.12345',
|
|
147
|
-
to: '0.0.67890',
|
|
148
|
-
amount: '5.0',
|
|
149
|
-
});
|
|
150
|
-
console.log(`TX: ${tx.transactionId} Status: ${tx.status}`);
|
|
113
|
+
### Storage (IPFS-backed)
|
|
151
114
|
|
|
152
|
-
|
|
153
|
-
const
|
|
115
|
+
```ts
|
|
116
|
+
const upload = await baas.storage.upload(file, 'avatar.png');
|
|
117
|
+
// → { fileId, cid, url: 'ipfs://bafy…', size }
|
|
154
118
|
|
|
155
|
-
|
|
156
|
-
const
|
|
119
|
+
const files = await baas.storage.list();
|
|
120
|
+
const usage = await baas.storage.getUsage();
|
|
157
121
|
```
|
|
158
122
|
|
|
159
|
-
###
|
|
123
|
+
### Messaging (pub/sub channels)
|
|
160
124
|
|
|
161
|
-
|
|
125
|
+
```ts
|
|
126
|
+
await baas.messaging.publish('events', { type: 'user.created', userId: '...' });
|
|
127
|
+
const sub = await baas.messaging.subscribe('events');
|
|
128
|
+
```
|
|
162
129
|
|
|
163
|
-
|
|
164
|
-
// Create accounts on different chains
|
|
165
|
-
const hederaAccount = await client.createAccount({ chain: 'hedera', initialBalance: '10', ... });
|
|
166
|
-
const xrplAccount = await client.createAccount({ chain: 'xrpl', initialBalance: '25', ... });
|
|
167
|
-
const ethAccount = await client.createAccount({ chain: 'ethereum', initialBalance: '0.1', ... });
|
|
168
|
-
const solAccount = await client.createAccount({ chain: 'solana', initialBalance: '1', ... });
|
|
130
|
+
### Functions (verifiable compute)
|
|
169
131
|
|
|
170
|
-
|
|
171
|
-
const
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
132
|
+
```ts
|
|
133
|
+
const fn = await baas.functions.deploy({
|
|
134
|
+
name: 'compute-hash',
|
|
135
|
+
runtime: 'node20',
|
|
136
|
+
trigger: 'http',
|
|
137
|
+
code: '...', // your function source
|
|
138
|
+
});
|
|
176
139
|
|
|
177
|
-
|
|
178
|
-
|
|
140
|
+
const result = await baas.functions.invoke(fn.functionId, { input: '...' });
|
|
141
|
+
// Cluster runs in isolated sandboxes across the validator quorum;
|
|
142
|
+
// 2-of-3 TSS consensus required before result is signed.
|
|
179
143
|
```
|
|
180
144
|
|
|
181
|
-
###
|
|
145
|
+
### Smart Agents (autonomous workers)
|
|
146
|
+
|
|
147
|
+
```ts
|
|
148
|
+
const agent = await baas.agents.register({
|
|
149
|
+
name: 'Trading Bot',
|
|
150
|
+
capabilities: ['trade', 'withdraw'],
|
|
151
|
+
rules: {
|
|
152
|
+
maxTradeAmount: '1000',
|
|
153
|
+
allowedPairs: ['HBAR/USDC'],
|
|
154
|
+
dailyLimit: '5000',
|
|
155
|
+
requireApprovalAbove: '10000',
|
|
156
|
+
},
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
// Rules are pinned to HCS and enforced by the validator quorum.
|
|
160
|
+
// Every agent action is rules-checked, TSS-signed, then submitted on chain.
|
|
182
161
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
}));
|
|
189
|
-
console.log(`Sequence: ${result.sequenceNumber}`);
|
|
162
|
+
await baas.agents.fund(agent.agentId, { chain: 'hedera', amount: '500' });
|
|
163
|
+
await baas.agents.trade(agent.agentId, { chain: 'hedera', pair: 'HBAR/USDC', side: 'buy', amount: '100' });
|
|
164
|
+
await baas.agents.pause(agent.agentId);
|
|
165
|
+
await baas.agents.resume(agent.agentId);
|
|
166
|
+
const events = await baas.agents.getEvents(agent.agentId);
|
|
190
167
|
```
|
|
191
168
|
|
|
192
|
-
###
|
|
193
|
-
|
|
194
|
-
```typescript
|
|
195
|
-
// List validator templates
|
|
196
|
-
const templates = await client.validators.listTemplates();
|
|
169
|
+
### Deployment
|
|
197
170
|
|
|
198
|
-
|
|
199
|
-
const
|
|
171
|
+
```ts
|
|
172
|
+
const deployment = await baas.deployment.create({
|
|
173
|
+
name: 'My Smart App v2',
|
|
174
|
+
services: ['database', 'storage', 'messaging'],
|
|
175
|
+
config: { /* app-specific */ },
|
|
176
|
+
});
|
|
200
177
|
|
|
201
|
-
|
|
202
|
-
const
|
|
178
|
+
const apps = await baas.deployment.list();
|
|
179
|
+
const info = await baas.deployment.get(appId);
|
|
180
|
+
await baas.deployment.suspend(appId);
|
|
181
|
+
await baas.deployment.resume(appId);
|
|
203
182
|
```
|
|
204
183
|
|
|
205
|
-
|
|
184
|
+
---
|
|
206
185
|
|
|
207
|
-
|
|
208
|
-
// Check subscription status
|
|
209
|
-
const status = await client.subscription.getStatus('my-app-id');
|
|
186
|
+
## Chain operations via `SmartEngineClient`
|
|
210
187
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
appId: 'my-app',
|
|
214
|
-
developerAccountId: '0.0.12345',
|
|
215
|
-
chain: 'hedera',
|
|
216
|
-
selectedTier: 'starter',
|
|
217
|
-
selectedNetworks: ['hedera'],
|
|
218
|
-
});
|
|
219
|
-
console.log(`Deposit to: ${sub.depositWallet} Amount: ${sub.amount}`);
|
|
220
|
-
```
|
|
188
|
+
For direct chain operations independent of BaaS — e.g., a custodial backend
|
|
189
|
+
that creates accounts and tokens on behalf of users:
|
|
221
190
|
|
|
222
|
-
|
|
191
|
+
```ts
|
|
192
|
+
import { SmartEngineClient } from '@hsuite/smart-engines-sdk';
|
|
223
193
|
|
|
224
|
-
|
|
225
|
-
|
|
194
|
+
const client = new SmartEngineClient({
|
|
195
|
+
baseUrl: 'https://v3-testnet-gateway.hsuite.network',
|
|
196
|
+
// Auth via authToken (set after the Web3 challenge flow):
|
|
197
|
+
authToken: '<jwt-from-validator-auth-verify>',
|
|
198
|
+
});
|
|
226
199
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
appId: 'my-app-id',
|
|
200
|
+
// Create an account on any supported chain
|
|
201
|
+
const account = await client.createAccount({
|
|
230
202
|
chain: 'hedera',
|
|
203
|
+
initialBalance: '10',
|
|
204
|
+
validatorTimestamp: '...',
|
|
205
|
+
validatorTopicId: '0.0.98765',
|
|
231
206
|
});
|
|
232
207
|
|
|
233
|
-
//
|
|
234
|
-
await
|
|
235
|
-
|
|
236
|
-
|
|
208
|
+
// Create a fungible token
|
|
209
|
+
const token = await client.createToken({
|
|
210
|
+
chain: 'hedera',
|
|
211
|
+
name: 'My Token', symbol: 'MTK',
|
|
212
|
+
decimals: 8, initialSupply: '1000000',
|
|
213
|
+
type: 'fungible',
|
|
214
|
+
capabilities: { mintable: true, burnable: true, pausable: true, restrictable: true, compliant: true, wipeable: true },
|
|
215
|
+
validatorTimestamp: '...', validatorTopicId: '0.0.98765',
|
|
237
216
|
});
|
|
238
217
|
|
|
239
|
-
//
|
|
240
|
-
const
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
// Storage (IPFS-backed)
|
|
245
|
-
const file = await baas.storage.upload('data.json', Buffer.from(JSON.stringify(data)));
|
|
246
|
-
const download = await baas.storage.download(file.fileId);
|
|
247
|
-
|
|
248
|
-
// Serverless functions (Ed25519 code signing required)
|
|
249
|
-
await baas.functions.deploy({
|
|
250
|
-
name: 'process-payment',
|
|
251
|
-
runtime: 'nodejs',
|
|
252
|
-
signedCode: { code, signature, publicKey, timestamp, hash },
|
|
218
|
+
// Transfer
|
|
219
|
+
const tx = await client.transfer({
|
|
220
|
+
chain: 'hedera', from: '0.0.1', to: '0.0.2', amount: '1.5',
|
|
221
|
+
validatorTimestamp: '...', validatorTopicId: '0.0.98765',
|
|
253
222
|
});
|
|
254
|
-
const result = await baas.functions.invoke('process-payment', { amount: 100 });
|
|
255
223
|
|
|
256
|
-
//
|
|
257
|
-
await
|
|
258
|
-
|
|
224
|
+
// Balance + info
|
|
225
|
+
const balance = await client.getBalance('hedera', '0.0.12345');
|
|
226
|
+
const info = await client.getAccountInfo('hedera', '0.0.12345');
|
|
259
227
|
|
|
260
|
-
|
|
228
|
+
// HCS topic ops, IPFS pinning, TSS signing — all available via sub-clients
|
|
229
|
+
await client.tss.signMPC({ chain: 'hedera', entityId: '...', transactionBytes: '0x...' });
|
|
230
|
+
await client.ipfs.upload(file, 'document.pdf');
|
|
231
|
+
await client.transactions.prepareTransfer({ chain: 'xrpl', from: '...', to: '...', amount: '100' });
|
|
232
|
+
```
|
|
261
233
|
|
|
262
|
-
|
|
234
|
+
---
|
|
263
235
|
|
|
264
|
-
|
|
265
|
-
import { SmartEngineError, ErrorCode } from '@hsuite/smart-engines-sdk';
|
|
236
|
+
## NestJS integration
|
|
266
237
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
} catch (error) {
|
|
270
|
-
if (error instanceof SmartEngineError) {
|
|
271
|
-
console.log(`Code: ${error.code}`); // e.g., 'INSUFFICIENT_BALANCE'
|
|
272
|
-
console.log(`Status: ${error.statusCode}`); // e.g., 400
|
|
273
|
-
console.log(`Retryable: ${error.isRetryable}`); // e.g., false
|
|
274
|
-
console.log(`Context:`, error.context); // e.g., { chain: 'hedera' }
|
|
275
|
-
|
|
276
|
-
switch (error.code) {
|
|
277
|
-
case ErrorCode.INSUFFICIENT_BALANCE:
|
|
278
|
-
console.log('Not enough funds');
|
|
279
|
-
break;
|
|
280
|
-
case ErrorCode.CHAIN_CONNECTION_ERROR:
|
|
281
|
-
console.log('Network issue — will retry');
|
|
282
|
-
if (error.isRetryable) { /* retry logic */ }
|
|
283
|
-
break;
|
|
284
|
-
case ErrorCode.RATE_LIMIT_EXCEEDED:
|
|
285
|
-
console.log('Too many requests — back off');
|
|
286
|
-
break;
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
```
|
|
291
|
-
|
|
292
|
-
### Error Codes
|
|
293
|
-
|
|
294
|
-
| Code | Description | Retryable |
|
|
295
|
-
|------|-------------|-----------|
|
|
296
|
-
| `INSUFFICIENT_BALANCE` | Not enough native or token balance | No |
|
|
297
|
-
| `INVALID_ACCOUNT_ID` | Account doesn't exist or is deleted | No |
|
|
298
|
-
| `CHAIN_CONNECTION_ERROR` | Network/RPC connectivity issue | Yes |
|
|
299
|
-
| `CHAIN_TIMEOUT` | Request timed out | Yes |
|
|
300
|
-
| `RATE_LIMIT_EXCEEDED` | Too many requests | Yes |
|
|
301
|
-
| `INVALID_TRANSACTION` | Malformed or invalid transaction | No |
|
|
302
|
-
| `TRANSACTION_FAILED` | Transaction executed but failed | No |
|
|
303
|
-
| `CONTRACT_REVERT` | Smart contract execution reverted | No |
|
|
304
|
-
| `TOKEN_NOT_ASSOCIATED` | Token not associated to account (Hedera) | No |
|
|
305
|
-
| `TRUST_LINE_REQUIRED` | Trust line needed (XRPL/Stellar) | No |
|
|
306
|
-
| `INVALID_SIGNATURE` | Bad signature on transaction | No |
|
|
307
|
-
|
|
308
|
-
## NestJS Integration
|
|
309
|
-
|
|
310
|
-
```typescript
|
|
238
|
+
```ts
|
|
239
|
+
// app.module.ts
|
|
311
240
|
import { Module } from '@nestjs/common';
|
|
312
|
-
import {
|
|
241
|
+
import { ConfigModule, ConfigService } from '@nestjs/config';
|
|
242
|
+
import { SmartEngineModule } from '@hsuite/smart-engines-sdk/nestjs';
|
|
313
243
|
|
|
314
244
|
@Module({
|
|
315
245
|
imports: [
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
246
|
+
ConfigModule.forRoot({ isGlobal: true }),
|
|
247
|
+
SmartEngineModule.forRootAsync({
|
|
248
|
+
imports: [ConfigModule],
|
|
249
|
+
useFactory: (config: ConfigService) => ({
|
|
250
|
+
baseUrl: config.get('VALIDATOR_URL')!,
|
|
251
|
+
timeout: 30000,
|
|
252
|
+
testConnection: true,
|
|
253
|
+
autoReconnect: true,
|
|
254
|
+
reconnectInterval: 5000,
|
|
255
|
+
}),
|
|
256
|
+
inject: [ConfigService],
|
|
257
|
+
isGlobal: true,
|
|
319
258
|
}),
|
|
320
259
|
],
|
|
321
260
|
})
|
|
322
261
|
export class AppModule {}
|
|
323
262
|
```
|
|
324
263
|
|
|
325
|
-
|
|
264
|
+
Inject the `SmartEngineService` into your controllers / services for typed
|
|
265
|
+
access to `client.getHealth() / client.createAccount() / ...`.
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
## Resilience primitives
|
|
270
|
+
|
|
271
|
+
The SDK ships circuit-breaker, rate-limiter, and retry primitives used
|
|
272
|
+
internally — exposed for app-level use too:
|
|
273
|
+
|
|
274
|
+
```ts
|
|
275
|
+
import { CircuitBreaker, RateLimiter, retryWithBackoff } from '@hsuite/smart-engines-sdk';
|
|
276
|
+
|
|
277
|
+
const breaker = new CircuitBreaker({ failureThreshold: 5, resetTimeoutMs: 30_000 });
|
|
278
|
+
const result = await breaker.execute(() => someFlakyOperation());
|
|
279
|
+
|
|
280
|
+
const limiter = new RateLimiter({ maxRequests: 60, windowMs: 60_000 });
|
|
281
|
+
if (limiter.isAllowed(walletAddress)) { /* proceed */ }
|
|
282
|
+
|
|
283
|
+
const value = await retryWithBackoff(
|
|
284
|
+
() => someTransientCall(),
|
|
285
|
+
{ maxRetries: 3, initialDelayMs: 200, backoffMultiplier: 2 },
|
|
286
|
+
);
|
|
287
|
+
```
|
|
326
288
|
|
|
327
|
-
|
|
328
|
-
import { Injectable } from '@nestjs/common';
|
|
329
|
-
import { SmartEngineService } from '@hsuite/smart-engines-sdk';
|
|
289
|
+
---
|
|
330
290
|
|
|
331
|
-
|
|
332
|
-
export class PaymentService {
|
|
333
|
-
constructor(private readonly smartEngine: SmartEngineService) {}
|
|
291
|
+
## Error handling
|
|
334
292
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
293
|
+
```ts
|
|
294
|
+
import { SmartEngineError, ErrorCode, UnsupportedCapabilityError, BaasError } from '@hsuite/smart-engines-sdk';
|
|
295
|
+
|
|
296
|
+
try {
|
|
297
|
+
await client.createToken({ chain: 'xrpl', name: 'X', symbol: 'X', type: 'fungible', /* ... */ capabilities: { wipeable: true } });
|
|
298
|
+
} catch (err) {
|
|
299
|
+
if (err instanceof UnsupportedCapabilityError) {
|
|
300
|
+
console.error(`${err.capability} not supported on ${err.chain}; alternatives:`, err.alternatives);
|
|
301
|
+
} else if (err instanceof SmartEngineError && err.code === ErrorCode.RATE_LIMIT_EXCEEDED) {
|
|
302
|
+
// back off + retry
|
|
303
|
+
} else if (err instanceof BaasError) {
|
|
304
|
+
console.error('BaaS request failed:', err.statusCode, err.details);
|
|
342
305
|
}
|
|
343
306
|
}
|
|
344
307
|
```
|
|
345
308
|
|
|
346
|
-
|
|
309
|
+
---
|
|
347
310
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
311
|
+
## Peer dependencies
|
|
312
|
+
|
|
313
|
+
| Package | Required? | When |
|
|
314
|
+
|---|---|---|
|
|
315
|
+
| `xrpl` | required | Web3 auth signing (`Wallet.fromSeed`, `wallet.publicKey`, etc.) |
|
|
316
|
+
| `zod` | required | Schema validation (request/response shapes) |
|
|
317
|
+
| `@nestjs/common` + `@nestjs/core` | optional | Only if you import from `@hsuite/smart-engines-sdk/nestjs` |
|
|
318
|
+
| `@hashgraph/sdk` | optional | Only if your app does Hedera-side business logic |
|
|
319
|
+
|
|
320
|
+
`ripple-keypairs` is a transitive dep of `xrpl` — no separate install needed.
|
|
357
321
|
|
|
358
|
-
|
|
322
|
+
---
|
|
323
|
+
|
|
324
|
+
## Bundle
|
|
325
|
+
|
|
326
|
+
The SDK is a single 134 KB CJS bundle with workspace-only primitives
|
|
327
|
+
vendored in. Single-file `.d.ts` (84 KB) for full type ergonomics.
|
|
328
|
+
|
|
329
|
+
```
|
|
330
|
+
@hsuite/smart-engines-sdk@3.0.0
|
|
331
|
+
dist/index.js 134 KB — main bundle
|
|
332
|
+
dist/index.d.ts 84 KB — types
|
|
333
|
+
dist/nestjs/index.js 104 KB — NestJS integration
|
|
334
|
+
dist/nestjs/index.d.ts 64 KB
|
|
335
|
+
```
|
|
359
336
|
|
|
360
|
-
|
|
361
|
-
|-------|------------|--------|------|-----------|-----|-----------|
|
|
362
|
-
| Hedera | ✅ | ✅ HTS | ✅ | ✅ HCS | — | ✅ TSS |
|
|
363
|
-
| XRPL | ✅ | ✅ Trust Lines | ✅ XLS-20 | — | ✅ Native | ✅ SignerList |
|
|
364
|
-
| Ethereum | ✅ | ✅ ERC-20 | — | — | — | ✅ Safe |
|
|
365
|
-
| Polygon | ✅ | ✅ ERC-20 | — | — | — | ✅ Safe |
|
|
366
|
-
| Solana | ✅ | ✅ SPL | ✅ Metaplex | — | — | ✅ Squads |
|
|
367
|
-
| Polkadot | ✅ | ✅ Assets | — | — | — | — |
|
|
368
|
-
| Stellar | ✅ | ✅ Assets | — | — | ✅ SDEX | — |
|
|
369
|
-
| Bitcoin | ✅ | — | — | — | — | — |
|
|
337
|
+
---
|
|
370
338
|
|
|
371
339
|
## License
|
|
372
340
|
|
|
373
|
-
|
|
341
|
+
MIT. Built on the Smart Engines V3 architecture
|
|
342
|
+
([github.com/HSuiteNetwork/smart-engines-multichain](https://github.com/HSuiteNetwork/smart-engines-multichain)).
|