@outlayer/sdk 0.1.0-alpha.1
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 +207 -0
- package/dist/index.cjs +389 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1788 -0
- package/dist/index.d.ts +1788 -0
- package/dist/index.js +373 -0
- package/dist/index.js.map +1 -0
- package/package.json +68 -0
- package/spec/openapi.yaml +1648 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 OutLayer contributors
|
|
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,207 @@
|
|
|
1
|
+
# @outlayer/sdk
|
|
2
|
+
|
|
3
|
+
TypeScript SDK for **OutLayer Agent Custody** — multi-chain wallets for AI agents with TEE-enforced policy, multisig approvals, and gasless cross-chain transfers via NEAR Intents.
|
|
4
|
+
|
|
5
|
+
[Docs](docs/) · [Examples](examples/) · [API spec](https://api.outlayer.fastnear.com/docs) · [Source](https://github.com/out-layer/sdk-js)
|
|
6
|
+
|
|
7
|
+
## Why this SDK
|
|
8
|
+
|
|
9
|
+
If you've used Steward.fi or similar AI-agent wallet infra, you know the shape: API key in, signed transactions out. OutLayer keeps that shape but moves the trust root:
|
|
10
|
+
|
|
11
|
+
- **Keys live in a TEE** (Intel Trust Domain Extensions on Phala Cloud). The infrastructure operator cannot extract them.
|
|
12
|
+
- **Policy is enforced inside the TEE**, before signing, against an encrypted policy stored on the NEAR blockchain.
|
|
13
|
+
- **Sovereign exit** is available: a customer can permissionlessly recover their wallet's master key even if OutLayer shuts down. (Requires opting into the `vault` flow — see the [vault docs](https://outlayer.fastnear.com/docs/vaults).)
|
|
14
|
+
- **Multi-chain wallets** (NEAR, Ethereum, Solana, Bitcoin) with deterministic address derivation and gasless cross-chain transfers via NEAR Intents.
|
|
15
|
+
|
|
16
|
+
## Install
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install @outlayer/sdk
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Requires Node 18+ (uses native `fetch` and `crypto.randomUUID`). Works in the browser, Bun, and Deno with no extra config.
|
|
23
|
+
|
|
24
|
+
## 60-second quickstart
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
import { OutlayerClient } from '@outlayer/sdk';
|
|
28
|
+
|
|
29
|
+
// 1. Register an anonymous wallet. The API key is shown ONCE — save it.
|
|
30
|
+
const { apiKey, walletId, handoffUrl } = await OutlayerClient.register();
|
|
31
|
+
console.log('API key:', apiKey);
|
|
32
|
+
console.log('Set up policy:', handoffUrl);
|
|
33
|
+
|
|
34
|
+
// 2. Use the wallet
|
|
35
|
+
const client = new OutlayerClient({ apiKey });
|
|
36
|
+
|
|
37
|
+
const addr = await client.getAddress('near');
|
|
38
|
+
console.log('NEAR address:', addr.address);
|
|
39
|
+
|
|
40
|
+
const balance = await client.getBalance({ chain: 'near' });
|
|
41
|
+
console.log('Balance:', balance.balance);
|
|
42
|
+
|
|
43
|
+
// 3. Withdraw across chains — gasless via NEAR Intents
|
|
44
|
+
const result = await client.withdraw({
|
|
45
|
+
chain: 'ethereum',
|
|
46
|
+
to: '0x742d35Cc6634C0532925a3b844Bc9e7595f8b4f5',
|
|
47
|
+
amount: '1000000', // 1 USDT (6 decimals)
|
|
48
|
+
token: 'nep141:usdt.tether-token.near',
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
if (result.status === 'pending_approval') {
|
|
52
|
+
console.log(`Awaiting ${result.required} approvals; ${result.approved} so far.`);
|
|
53
|
+
} else {
|
|
54
|
+
console.log('Submitted as request', result.request_id);
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
That's the whole flow. The wallet has no policy yet, so withdraws are unrestricted; visit `handoffUrl` in a browser to set spending limits, allowlists, and multisig.
|
|
59
|
+
|
|
60
|
+
## What's in the SDK
|
|
61
|
+
|
|
62
|
+
| Surface | What it does |
|
|
63
|
+
|---|---|
|
|
64
|
+
| `OutlayerClient.register()` | Create a new wallet, get an API key |
|
|
65
|
+
| `client.getAddress(chain)` | Derive address for NEAR / Ethereum / Solana / Bitcoin |
|
|
66
|
+
| `client.getBalance({...})` | Read on-chain or intents.near balance |
|
|
67
|
+
| `client.listTokens()` | Catalog of swap-capable tokens |
|
|
68
|
+
| `client.call({...})` | Sign and broadcast a NEAR contract call |
|
|
69
|
+
| `client.transfer({...})` | Native chain transfer (currently NEAR-only at the chain layer) |
|
|
70
|
+
| `client.withdraw({...})` | Gasless cross-chain withdraw via NEAR Intents |
|
|
71
|
+
| `client.withdrawDryRun({...})` | Policy + balance check without execution |
|
|
72
|
+
| `client.swap({...})` | Cross-chain swap via 1Click |
|
|
73
|
+
| `client.swapQuote({...})` | Price preview without execution |
|
|
74
|
+
| `client.intentsDeposit({...})` | Move FT into intents.near for cross-chain ops |
|
|
75
|
+
| `client.signMessage({...})` | NEP-413 or raw message signing |
|
|
76
|
+
| `client.getRequest(id)` | Status of an async operation |
|
|
77
|
+
| `client.listRequests({...})` | List recent operations |
|
|
78
|
+
| `client.policy.*` | Policy lifecycle (encrypt → sign → store) |
|
|
79
|
+
| `client.approvals.*` | Multisig approval workflow |
|
|
80
|
+
| `client.audit.list({...})` | Event history |
|
|
81
|
+
|
|
82
|
+
Full reference: [API spec](https://api.outlayer.fastnear.com/docs).
|
|
83
|
+
|
|
84
|
+
## Documentation
|
|
85
|
+
|
|
86
|
+
| Topic | Read this if you want to… |
|
|
87
|
+
|---|---|
|
|
88
|
+
| [Getting started](docs/getting-started.md) | Register, set a policy, do your first withdraw |
|
|
89
|
+
| [Wallet operations](docs/wallets.md) | Send / receive / swap / withdraw — full method reference |
|
|
90
|
+
| [Policy management](docs/policy.md) | Configure spending limits, allowlists, time windows, multisig thresholds |
|
|
91
|
+
| [Multisig approvals](docs/approvals.md) | Wire up the NEP-413 approval flow |
|
|
92
|
+
| [Error handling](docs/errors.md) | Handle `PolicyDeniedError`, `WalletFrozenError`, retries |
|
|
93
|
+
| [Vaults (sovereign custody)](docs/vaults.md) | Bind a wallet to a deployed customer vault |
|
|
94
|
+
| [Migration from raw HTTP](docs/migration-from-http.md) | Move from `fetch('/wallet/v1/...')` to the SDK |
|
|
95
|
+
|
|
96
|
+
### Vault custody (advanced)
|
|
97
|
+
|
|
98
|
+
For production deployments that need **sovereign exit guarantees**, bind a wallet to a customer-owned vault. Vault deployment happens via the [dashboard](https://outlayer.fastnear.com/vault) or `outlayer vault init` CLI (not the SDK — your NEAR keys never touch us). Once deployed, binding is one option:
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
const wallet = await OutlayerClient.register({ vaultId: 'vault.alice.near' });
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
See [docs/vaults.md](docs/vaults.md) and https://outlayer.fastnear.com/docs/vaults.
|
|
105
|
+
|
|
106
|
+
## Examples
|
|
107
|
+
|
|
108
|
+
Runnable scripts in [`examples/`](examples/):
|
|
109
|
+
|
|
110
|
+
- `01-register.ts` — register a wallet, derive addresses on 4 chains, check balance
|
|
111
|
+
- `02-withdraw.ts` — gasless cross-chain withdraw with dry-run + polling
|
|
112
|
+
- `03-multisig.ts` — submit a withdraw that triggers the approval flow
|
|
113
|
+
- `04-agent-loop.ts` — minimal autonomous agent that respects policy
|
|
114
|
+
- `05-cross-chain-app.ts` — end-to-end DeFi flow: cross-chain login pattern, deposit instructions, swap USDT → NEAR, stake with a validator, gasless withdraw back to Ethereum. CLI with sub-commands (`addresses | balances | buy-near | stake | unstake | withdraw-eth | login-demo`).
|
|
115
|
+
|
|
116
|
+
Run with:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
npx tsx examples/01-register.ts # no auth needed
|
|
120
|
+
OUTLAYER_API_KEY=wk_... npx tsx examples/02-withdraw.ts # needs API key
|
|
121
|
+
OUTLAYER_API_KEY=wk_... npx tsx examples/05-cross-chain-app.ts addresses # cross-chain identity
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Errors
|
|
125
|
+
|
|
126
|
+
Every non-2xx response is thrown as a typed subclass of `OutlayerError`:
|
|
127
|
+
|
|
128
|
+
```ts
|
|
129
|
+
import { OutlayerClient, PolicyDeniedError, WalletFrozenError } from '@outlayer/sdk';
|
|
130
|
+
|
|
131
|
+
try {
|
|
132
|
+
await client.withdraw({ chain: 'near', to: 'bob.near', amount: '100' });
|
|
133
|
+
} catch (err) {
|
|
134
|
+
if (err instanceof PolicyDeniedError) {
|
|
135
|
+
console.log('Policy rejected:', err.message);
|
|
136
|
+
} else if (err instanceof WalletFrozenError) {
|
|
137
|
+
console.log('Wallet is frozen by the controller');
|
|
138
|
+
} else {
|
|
139
|
+
throw err;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
See [errors.md](docs/errors.md) for the full list.
|
|
145
|
+
|
|
146
|
+
## Retry, idempotency, network failures
|
|
147
|
+
|
|
148
|
+
Transient 5xx and network errors are retried automatically (3 attempts, exponential backoff 100ms → 1.6s). 4xx is not retried — those are deterministic.
|
|
149
|
+
|
|
150
|
+
Write operations get an auto-generated `Idempotency-Key` per call; retries from the SDK's own retry layer reuse the same key, so repeated calls don't double-spend. To control idempotency yourself (e.g., for at-least-once delivery from a queue):
|
|
151
|
+
|
|
152
|
+
```ts
|
|
153
|
+
await client.withdraw({
|
|
154
|
+
chain: 'near',
|
|
155
|
+
to: 'bob.near',
|
|
156
|
+
amount: '1000000000000000000000000',
|
|
157
|
+
idempotencyKey: 'my-job-id-12345',
|
|
158
|
+
});
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Reusing the same key returns the original result without re-executing.
|
|
162
|
+
|
|
163
|
+
## Configuration
|
|
164
|
+
|
|
165
|
+
```ts
|
|
166
|
+
const client = new OutlayerClient({
|
|
167
|
+
apiKey: process.env.OUTLAYER_API_KEY!,
|
|
168
|
+
baseUrl: 'https://api.outlayer.fastnear.com', // default
|
|
169
|
+
fetch: customFetch, // optional, for SSR/proxies
|
|
170
|
+
retry: {
|
|
171
|
+
maxAttempts: 5,
|
|
172
|
+
initialDelayMs: 200,
|
|
173
|
+
maxDelayMs: 4000,
|
|
174
|
+
},
|
|
175
|
+
});
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## Browser usage
|
|
179
|
+
|
|
180
|
+
Don't ship your API key to a browser. The key has full wallet authority. Either:
|
|
181
|
+
|
|
182
|
+
1. **Proxy through your backend** — frontend calls your backend, your backend calls OutLayer.
|
|
183
|
+
2. **Use a payment key for that single tx** — created via the dashboard, scoped to a specific operation.
|
|
184
|
+
|
|
185
|
+
The SDK works in browsers, but only with keys you've already gated.
|
|
186
|
+
|
|
187
|
+
## Versioning
|
|
188
|
+
|
|
189
|
+
This is `0.1.0-alpha` — expect breaking changes until `0.x` stabilizes around v1. Breaking changes will be documented in [`CHANGELOG.md`](CHANGELOG.md). Pin to a patch version (`0.1.0-alpha.1`) in production until v1.
|
|
190
|
+
|
|
191
|
+
## Contributing
|
|
192
|
+
|
|
193
|
+
The OpenAPI spec is the source of truth — when adding endpoints, update [out-layer/api-spec](https://github.com/out-layer/api-spec) first, regenerate types here with `npm run gen`, then add ergonomic wrappers in `src/client.ts`.
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
git clone https://github.com/out-layer/sdk-js
|
|
197
|
+
cd sdk-js
|
|
198
|
+
npm install
|
|
199
|
+
npm run gen # regenerate src/types.ts from spec
|
|
200
|
+
npm run typecheck
|
|
201
|
+
npm test
|
|
202
|
+
npm run build
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
## License
|
|
206
|
+
|
|
207
|
+
MIT.
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var createClient = require('openapi-fetch');
|
|
4
|
+
|
|
5
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
6
|
+
|
|
7
|
+
var createClient__default = /*#__PURE__*/_interopDefault(createClient);
|
|
8
|
+
|
|
9
|
+
// src/http.ts
|
|
10
|
+
|
|
11
|
+
// src/errors.ts
|
|
12
|
+
var OutlayerError = class extends Error {
|
|
13
|
+
code;
|
|
14
|
+
status;
|
|
15
|
+
details;
|
|
16
|
+
constructor(opts) {
|
|
17
|
+
super(opts.message);
|
|
18
|
+
this.name = "OutlayerError";
|
|
19
|
+
this.code = opts.code;
|
|
20
|
+
this.status = opts.status;
|
|
21
|
+
this.details = opts.details;
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
var PolicyDeniedError = class extends OutlayerError {
|
|
25
|
+
constructor(opts) {
|
|
26
|
+
super(opts);
|
|
27
|
+
this.name = "PolicyDeniedError";
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
var WalletFrozenError = class extends OutlayerError {
|
|
31
|
+
constructor(opts) {
|
|
32
|
+
super(opts);
|
|
33
|
+
this.name = "WalletFrozenError";
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
var UnauthorizedError = class extends OutlayerError {
|
|
37
|
+
constructor(opts) {
|
|
38
|
+
super(opts);
|
|
39
|
+
this.name = "UnauthorizedError";
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
var RateLimitedError = class extends OutlayerError {
|
|
43
|
+
constructor(opts) {
|
|
44
|
+
super(opts);
|
|
45
|
+
this.name = "RateLimitedError";
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
var NotFoundError = class extends OutlayerError {
|
|
49
|
+
constructor(opts) {
|
|
50
|
+
super(opts);
|
|
51
|
+
this.name = "NotFoundError";
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
var BadRequestError = class extends OutlayerError {
|
|
55
|
+
constructor(opts) {
|
|
56
|
+
super(opts);
|
|
57
|
+
this.name = "BadRequestError";
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
var codeToCtor = {
|
|
61
|
+
policy_denied: PolicyDeniedError,
|
|
62
|
+
wallet_frozen: WalletFrozenError,
|
|
63
|
+
missing_auth: UnauthorizedError,
|
|
64
|
+
invalid_api_key: UnauthorizedError,
|
|
65
|
+
timestamp_expired: UnauthorizedError,
|
|
66
|
+
rate_limited: RateLimitedError,
|
|
67
|
+
request_not_found: NotFoundError,
|
|
68
|
+
approval_not_found: NotFoundError,
|
|
69
|
+
bad_request: BadRequestError,
|
|
70
|
+
invalid_address: BadRequestError,
|
|
71
|
+
insufficient_balance: BadRequestError,
|
|
72
|
+
unsupported_chain: BadRequestError,
|
|
73
|
+
unsupported_token: BadRequestError
|
|
74
|
+
};
|
|
75
|
+
function makeError(body, status) {
|
|
76
|
+
const code = body.error ?? "parse_error";
|
|
77
|
+
const message = body.message ?? `HTTP ${status}`;
|
|
78
|
+
const opts = body.details !== void 0 ? { code, message, status, details: body.details } : { code, message, status };
|
|
79
|
+
const Ctor = codeToCtor[code] ?? OutlayerError;
|
|
80
|
+
return new Ctor(opts);
|
|
81
|
+
}
|
|
82
|
+
async function errorFromResponse(response, parsed) {
|
|
83
|
+
let body;
|
|
84
|
+
if (parsed && typeof parsed === "object") {
|
|
85
|
+
body = parsed;
|
|
86
|
+
} else {
|
|
87
|
+
try {
|
|
88
|
+
body = await response.clone().json();
|
|
89
|
+
} catch {
|
|
90
|
+
body = { error: "internal_error", message: response.statusText };
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return makeError(body, response.status);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// src/http.ts
|
|
97
|
+
var DEFAULT_BASE_URL = "https://api.outlayer.fastnear.com";
|
|
98
|
+
var DEFAULT_RETRY = {
|
|
99
|
+
maxAttempts: 3,
|
|
100
|
+
initialDelayMs: 100,
|
|
101
|
+
maxDelayMs: 1600
|
|
102
|
+
};
|
|
103
|
+
function makeClient(opts) {
|
|
104
|
+
const init = {
|
|
105
|
+
baseUrl: opts.baseUrl ?? DEFAULT_BASE_URL,
|
|
106
|
+
headers: { Authorization: `Bearer ${opts.apiKey}` }
|
|
107
|
+
};
|
|
108
|
+
if (opts.fetch) init.fetch = opts.fetch;
|
|
109
|
+
const client = createClient__default.default(init);
|
|
110
|
+
const retry = { ...DEFAULT_RETRY, ...opts.retry };
|
|
111
|
+
return { client, retry };
|
|
112
|
+
}
|
|
113
|
+
function makeUnauthenticatedClient(opts = {}) {
|
|
114
|
+
const init = {
|
|
115
|
+
baseUrl: opts.baseUrl ?? DEFAULT_BASE_URL
|
|
116
|
+
};
|
|
117
|
+
if (opts.fetch) init.fetch = opts.fetch;
|
|
118
|
+
return createClient__default.default(init);
|
|
119
|
+
}
|
|
120
|
+
async function runWithRetry(call, retry) {
|
|
121
|
+
let lastError;
|
|
122
|
+
for (let attempt = 1; attempt <= retry.maxAttempts; attempt++) {
|
|
123
|
+
try {
|
|
124
|
+
const { data, error, response } = await call();
|
|
125
|
+
if (response.ok) {
|
|
126
|
+
return data;
|
|
127
|
+
}
|
|
128
|
+
const err = await errorFromResponse(response, error);
|
|
129
|
+
if (err.status >= 500 && attempt < retry.maxAttempts) {
|
|
130
|
+
lastError = err;
|
|
131
|
+
await sleep(backoff(attempt, retry));
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
throw err;
|
|
135
|
+
} catch (e) {
|
|
136
|
+
if (e instanceof OutlayerError) throw e;
|
|
137
|
+
lastError = e;
|
|
138
|
+
if (attempt < retry.maxAttempts && isNetworkError(e)) {
|
|
139
|
+
await sleep(backoff(attempt, retry));
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
throw new OutlayerError({
|
|
143
|
+
code: "network_error",
|
|
144
|
+
message: e instanceof Error ? e.message : String(e),
|
|
145
|
+
status: 0
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
throw lastError;
|
|
150
|
+
}
|
|
151
|
+
function backoff(attempt, cfg) {
|
|
152
|
+
return Math.min(cfg.maxDelayMs, cfg.initialDelayMs * 2 ** (attempt - 1));
|
|
153
|
+
}
|
|
154
|
+
function sleep(ms) {
|
|
155
|
+
return new Promise((r) => setTimeout(r, ms));
|
|
156
|
+
}
|
|
157
|
+
function isNetworkError(e) {
|
|
158
|
+
return e instanceof TypeError;
|
|
159
|
+
}
|
|
160
|
+
function newIdempotencyKey() {
|
|
161
|
+
return crypto.randomUUID();
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// src/client.ts
|
|
165
|
+
function idempotencyHeader(key) {
|
|
166
|
+
return { "Idempotency-Key": key ?? newIdempotencyKey() };
|
|
167
|
+
}
|
|
168
|
+
var PolicyAPI = class {
|
|
169
|
+
constructor(client, retry) {
|
|
170
|
+
this.client = client;
|
|
171
|
+
this.retry = retry;
|
|
172
|
+
}
|
|
173
|
+
client;
|
|
174
|
+
retry;
|
|
175
|
+
get() {
|
|
176
|
+
return runWithRetry(() => this.client.GET("/wallet/v1/policy"), this.retry);
|
|
177
|
+
}
|
|
178
|
+
encrypt(body) {
|
|
179
|
+
return runWithRetry(() => this.client.POST("/wallet/v1/encrypt-policy", { body }), this.retry);
|
|
180
|
+
}
|
|
181
|
+
sign(encryptedData) {
|
|
182
|
+
return runWithRetry(
|
|
183
|
+
() => this.client.POST("/wallet/v1/sign-policy", { body: { encrypted_data: encryptedData } }),
|
|
184
|
+
this.retry
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
invalidateCache(walletId) {
|
|
188
|
+
return runWithRetry(
|
|
189
|
+
() => this.client.POST("/wallet/v1/invalidate-cache", { body: { wallet_id: walletId } }),
|
|
190
|
+
this.retry
|
|
191
|
+
).then(() => void 0);
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
var ApprovalsAPI = class {
|
|
195
|
+
constructor(client, retry) {
|
|
196
|
+
this.client = client;
|
|
197
|
+
this.retry = retry;
|
|
198
|
+
}
|
|
199
|
+
client;
|
|
200
|
+
retry;
|
|
201
|
+
listPending() {
|
|
202
|
+
return runWithRetry(() => this.client.GET("/wallet/v1/pending_approvals"), this.retry);
|
|
203
|
+
}
|
|
204
|
+
approve(approvalId, auth) {
|
|
205
|
+
return runWithRetry(
|
|
206
|
+
() => this.client.POST("/wallet/v1/approve/{id}", {
|
|
207
|
+
params: { path: { id: approvalId } },
|
|
208
|
+
body: auth
|
|
209
|
+
}),
|
|
210
|
+
this.retry
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
reject(approvalId, auth, reason) {
|
|
214
|
+
const body = reason !== void 0 ? { ...auth, reason } : auth;
|
|
215
|
+
return runWithRetry(
|
|
216
|
+
() => this.client.POST("/wallet/v1/reject/{id}", {
|
|
217
|
+
params: { path: { id: approvalId } },
|
|
218
|
+
body
|
|
219
|
+
}),
|
|
220
|
+
this.retry
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
var AuditAPI = class {
|
|
225
|
+
constructor(client, retry) {
|
|
226
|
+
this.client = client;
|
|
227
|
+
this.retry = retry;
|
|
228
|
+
}
|
|
229
|
+
client;
|
|
230
|
+
retry;
|
|
231
|
+
list(opts = {}) {
|
|
232
|
+
return runWithRetry(
|
|
233
|
+
() => this.client.GET("/wallet/v1/audit", { params: { query: opts } }),
|
|
234
|
+
this.retry
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
};
|
|
238
|
+
var OutlayerClient = class {
|
|
239
|
+
client;
|
|
240
|
+
retry;
|
|
241
|
+
policy;
|
|
242
|
+
approvals;
|
|
243
|
+
audit;
|
|
244
|
+
constructor(opts) {
|
|
245
|
+
const { client, retry } = makeClient(opts);
|
|
246
|
+
this.client = client;
|
|
247
|
+
this.retry = retry;
|
|
248
|
+
this.policy = new PolicyAPI(client, retry);
|
|
249
|
+
this.approvals = new ApprovalsAPI(client, retry);
|
|
250
|
+
this.audit = new AuditAPI(client, retry);
|
|
251
|
+
}
|
|
252
|
+
// ------- Static factory: register a new wallet (no auth) -------
|
|
253
|
+
/**
|
|
254
|
+
* Register a new wallet and obtain an API key.
|
|
255
|
+
*
|
|
256
|
+
* - Empty call: anonymous wallet on OutLayer's shared master. Convenient, no setup.
|
|
257
|
+
* - With `vaultId`: bind to a deployed customer vault so keys derive through
|
|
258
|
+
* the per-vault master. Vault binding is permanent.
|
|
259
|
+
* - With `body`: full control — pass any `RegisterRequest` field (e.g., NEP-413
|
|
260
|
+
* account-binding fields). `vaultId` is merged into `body.vault_id` if not
|
|
261
|
+
* already set.
|
|
262
|
+
*
|
|
263
|
+
* Vault deployment is NOT done here — use the dashboard
|
|
264
|
+
* (https://outlayer.fastnear.com/vault) or `outlayer vault init` CLI.
|
|
265
|
+
* See docs/vaults.md for the full flow.
|
|
266
|
+
*/
|
|
267
|
+
static async register(opts = {}) {
|
|
268
|
+
const client = makeUnauthenticatedClient(opts);
|
|
269
|
+
const body = { ...opts.body ?? {} };
|
|
270
|
+
if (opts.vaultId !== void 0 && body.vault_id === void 0) {
|
|
271
|
+
body.vault_id = opts.vaultId;
|
|
272
|
+
}
|
|
273
|
+
const { data, error, response } = await client.POST("/register", { body });
|
|
274
|
+
if (!response.ok) throw await errorFromResponse(response, error);
|
|
275
|
+
return data;
|
|
276
|
+
}
|
|
277
|
+
// ------- Wallet read -------
|
|
278
|
+
getAddress(chain) {
|
|
279
|
+
return runWithRetry(
|
|
280
|
+
() => this.client.GET("/wallet/v1/address", { params: { query: { chain } } }),
|
|
281
|
+
this.retry
|
|
282
|
+
);
|
|
283
|
+
}
|
|
284
|
+
getBalance(opts = {}) {
|
|
285
|
+
return runWithRetry(
|
|
286
|
+
() => this.client.GET("/wallet/v1/balance", { params: { query: opts } }),
|
|
287
|
+
this.retry
|
|
288
|
+
);
|
|
289
|
+
}
|
|
290
|
+
listTokens() {
|
|
291
|
+
return runWithRetry(() => this.client.GET("/wallet/v1/tokens"), this.retry);
|
|
292
|
+
}
|
|
293
|
+
// ------- Wallet write -------
|
|
294
|
+
call(opts) {
|
|
295
|
+
const { idempotencyKey, ...body } = opts;
|
|
296
|
+
return runWithRetry(
|
|
297
|
+
() => this.client.POST("/wallet/v1/call", {
|
|
298
|
+
body,
|
|
299
|
+
headers: idempotencyHeader(idempotencyKey)
|
|
300
|
+
}),
|
|
301
|
+
this.retry
|
|
302
|
+
);
|
|
303
|
+
}
|
|
304
|
+
transfer(opts) {
|
|
305
|
+
const { idempotencyKey, ...body } = opts;
|
|
306
|
+
return runWithRetry(
|
|
307
|
+
() => this.client.POST("/wallet/v1/transfer", {
|
|
308
|
+
body,
|
|
309
|
+
headers: idempotencyHeader(idempotencyKey)
|
|
310
|
+
}),
|
|
311
|
+
this.retry
|
|
312
|
+
);
|
|
313
|
+
}
|
|
314
|
+
intentsDeposit(opts) {
|
|
315
|
+
const { idempotencyKey, ...body } = opts;
|
|
316
|
+
return runWithRetry(
|
|
317
|
+
() => this.client.POST("/wallet/v1/intents/deposit", {
|
|
318
|
+
body,
|
|
319
|
+
headers: idempotencyHeader(idempotencyKey)
|
|
320
|
+
}),
|
|
321
|
+
this.retry
|
|
322
|
+
);
|
|
323
|
+
}
|
|
324
|
+
withdraw(opts) {
|
|
325
|
+
const { idempotencyKey, ...body } = opts;
|
|
326
|
+
return runWithRetry(
|
|
327
|
+
() => this.client.POST("/wallet/v1/intents/withdraw", {
|
|
328
|
+
body,
|
|
329
|
+
headers: idempotencyHeader(idempotencyKey)
|
|
330
|
+
}),
|
|
331
|
+
this.retry
|
|
332
|
+
);
|
|
333
|
+
}
|
|
334
|
+
withdrawDryRun(opts) {
|
|
335
|
+
return runWithRetry(
|
|
336
|
+
() => this.client.POST("/wallet/v1/intents/withdraw/dry-run", { body: opts }),
|
|
337
|
+
this.retry
|
|
338
|
+
);
|
|
339
|
+
}
|
|
340
|
+
swap(opts) {
|
|
341
|
+
const { idempotencyKey, ...body } = opts;
|
|
342
|
+
return runWithRetry(
|
|
343
|
+
() => this.client.POST("/wallet/v1/intents/swap", {
|
|
344
|
+
body,
|
|
345
|
+
headers: idempotencyHeader(idempotencyKey)
|
|
346
|
+
}),
|
|
347
|
+
this.retry
|
|
348
|
+
);
|
|
349
|
+
}
|
|
350
|
+
swapQuote(opts) {
|
|
351
|
+
return runWithRetry(
|
|
352
|
+
() => this.client.POST("/wallet/v1/intents/swap/quote", { body: opts }),
|
|
353
|
+
this.retry
|
|
354
|
+
);
|
|
355
|
+
}
|
|
356
|
+
signMessage(opts) {
|
|
357
|
+
return runWithRetry(
|
|
358
|
+
() => this.client.POST("/wallet/v1/sign-message", { body: opts }),
|
|
359
|
+
this.retry
|
|
360
|
+
);
|
|
361
|
+
}
|
|
362
|
+
// ------- Async request tracking -------
|
|
363
|
+
getRequest(id) {
|
|
364
|
+
return runWithRetry(
|
|
365
|
+
() => this.client.GET("/wallet/v1/requests/{id}", { params: { path: { id } } }),
|
|
366
|
+
this.retry
|
|
367
|
+
);
|
|
368
|
+
}
|
|
369
|
+
listRequests(opts = {}) {
|
|
370
|
+
return runWithRetry(
|
|
371
|
+
() => this.client.GET("/wallet/v1/requests", { params: { query: opts } }),
|
|
372
|
+
this.retry
|
|
373
|
+
);
|
|
374
|
+
}
|
|
375
|
+
};
|
|
376
|
+
|
|
377
|
+
exports.ApprovalsAPI = ApprovalsAPI;
|
|
378
|
+
exports.AuditAPI = AuditAPI;
|
|
379
|
+
exports.BadRequestError = BadRequestError;
|
|
380
|
+
exports.NotFoundError = NotFoundError;
|
|
381
|
+
exports.OutlayerClient = OutlayerClient;
|
|
382
|
+
exports.OutlayerError = OutlayerError;
|
|
383
|
+
exports.PolicyAPI = PolicyAPI;
|
|
384
|
+
exports.PolicyDeniedError = PolicyDeniedError;
|
|
385
|
+
exports.RateLimitedError = RateLimitedError;
|
|
386
|
+
exports.UnauthorizedError = UnauthorizedError;
|
|
387
|
+
exports.WalletFrozenError = WalletFrozenError;
|
|
388
|
+
//# sourceMappingURL=index.cjs.map
|
|
389
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/http.ts","../src/client.ts"],"names":["createClient"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { components } from './types.js';\n\nexport type ApiErrorCode = components['schemas']['ErrorCode'];\nexport type ErrorCode = ApiErrorCode | 'network_error' | 'parse_error';\n\nexport type ErrorBody = {\n error?: ApiErrorCode;\n message?: string;\n details?: unknown;\n};\n\nexport interface OutlayerErrorOptions {\n code: ErrorCode;\n message: string;\n status: number;\n details?: unknown;\n}\n\nexport class OutlayerError extends Error {\n readonly code: ErrorCode;\n readonly status: number;\n readonly details: unknown;\n\n constructor(opts: OutlayerErrorOptions) {\n super(opts.message);\n this.name = 'OutlayerError';\n this.code = opts.code;\n this.status = opts.status;\n this.details = opts.details;\n }\n}\n\nexport class PolicyDeniedError extends OutlayerError {\n constructor(opts: OutlayerErrorOptions) {\n super(opts);\n this.name = 'PolicyDeniedError';\n }\n}\n\nexport class WalletFrozenError extends OutlayerError {\n constructor(opts: OutlayerErrorOptions) {\n super(opts);\n this.name = 'WalletFrozenError';\n }\n}\n\nexport class UnauthorizedError extends OutlayerError {\n constructor(opts: OutlayerErrorOptions) {\n super(opts);\n this.name = 'UnauthorizedError';\n }\n}\n\nexport class RateLimitedError extends OutlayerError {\n constructor(opts: OutlayerErrorOptions) {\n super(opts);\n this.name = 'RateLimitedError';\n }\n}\n\nexport class NotFoundError extends OutlayerError {\n constructor(opts: OutlayerErrorOptions) {\n super(opts);\n this.name = 'NotFoundError';\n }\n}\n\nexport class BadRequestError extends OutlayerError {\n constructor(opts: OutlayerErrorOptions) {\n super(opts);\n this.name = 'BadRequestError';\n }\n}\n\nconst codeToCtor: Partial<Record<ErrorCode, new (opts: OutlayerErrorOptions) => OutlayerError>> = {\n policy_denied: PolicyDeniedError,\n wallet_frozen: WalletFrozenError,\n missing_auth: UnauthorizedError,\n invalid_api_key: UnauthorizedError,\n timestamp_expired: UnauthorizedError,\n rate_limited: RateLimitedError,\n request_not_found: NotFoundError,\n approval_not_found: NotFoundError,\n bad_request: BadRequestError,\n invalid_address: BadRequestError,\n insufficient_balance: BadRequestError,\n unsupported_chain: BadRequestError,\n unsupported_token: BadRequestError,\n};\n\nexport function makeError(body: ErrorBody, status: number): OutlayerError {\n const code: ErrorCode = body.error ?? 'parse_error';\n const message = body.message ?? `HTTP ${status}`;\n const opts: OutlayerErrorOptions = body.details !== undefined\n ? { code, message, status, details: body.details }\n : { code, message, status };\n const Ctor = codeToCtor[code] ?? OutlayerError;\n return new Ctor(opts);\n}\n\nexport async function errorFromResponse(response: Response, parsed?: unknown): Promise<OutlayerError> {\n let body: ErrorBody;\n if (parsed && typeof parsed === 'object') {\n body = parsed as ErrorBody;\n } else {\n try {\n body = (await response.clone().json()) as ErrorBody;\n } catch {\n body = { error: 'internal_error', message: response.statusText };\n }\n }\n return makeError(body, response.status);\n}\n","import createClient, { type Client } from 'openapi-fetch';\nimport type { paths } from './types.js';\nimport { OutlayerError, errorFromResponse } from './errors.js';\n\nexport const DEFAULT_BASE_URL = 'https://api.outlayer.fastnear.com';\n\nexport type RetryConfig = {\n maxAttempts?: number;\n initialDelayMs?: number;\n maxDelayMs?: number;\n};\n\nexport type ClientOptions = {\n apiKey: string;\n baseUrl?: string;\n fetch?: typeof fetch;\n retry?: RetryConfig;\n};\n\nexport type UnauthenticatedOptions = {\n baseUrl?: string;\n fetch?: typeof fetch;\n};\n\nexport const DEFAULT_RETRY: Required<RetryConfig> = {\n maxAttempts: 3,\n initialDelayMs: 100,\n maxDelayMs: 1600,\n};\n\nexport type FetchClient = Client<paths, `${string}/${string}`>;\n\nexport function makeClient(opts: ClientOptions): { client: FetchClient; retry: Required<RetryConfig> } {\n const init: Parameters<typeof createClient<paths>>[0] = {\n baseUrl: opts.baseUrl ?? DEFAULT_BASE_URL,\n headers: { Authorization: `Bearer ${opts.apiKey}` },\n };\n if (opts.fetch) init.fetch = opts.fetch;\n const client = createClient<paths>(init);\n const retry: Required<RetryConfig> = { ...DEFAULT_RETRY, ...opts.retry };\n return { client, retry };\n}\n\nexport function makeUnauthenticatedClient(opts: UnauthenticatedOptions = {}): FetchClient {\n const init: Parameters<typeof createClient<paths>>[0] = {\n baseUrl: opts.baseUrl ?? DEFAULT_BASE_URL,\n };\n if (opts.fetch) init.fetch = opts.fetch;\n return createClient<paths>(init);\n}\n\nexport type FetchCall<T> = () => Promise<{\n data?: T;\n error?: unknown;\n response: Response;\n}>;\n\nexport async function runWithRetry<T>(\n call: FetchCall<T>,\n retry: Required<RetryConfig>,\n): Promise<T> {\n let lastError: unknown;\n for (let attempt = 1; attempt <= retry.maxAttempts; attempt++) {\n try {\n const { data, error, response } = await call();\n if (response.ok) {\n return data as T;\n }\n const err = await errorFromResponse(response, error);\n if (err.status >= 500 && attempt < retry.maxAttempts) {\n lastError = err;\n await sleep(backoff(attempt, retry));\n continue;\n }\n throw err;\n } catch (e) {\n if (e instanceof OutlayerError) throw e;\n lastError = e;\n if (attempt < retry.maxAttempts && isNetworkError(e)) {\n await sleep(backoff(attempt, retry));\n continue;\n }\n throw new OutlayerError({\n code: 'network_error',\n message: e instanceof Error ? e.message : String(e),\n status: 0,\n });\n }\n }\n throw lastError;\n}\n\nfunction backoff(attempt: number, cfg: Required<RetryConfig>): number {\n return Math.min(cfg.maxDelayMs, cfg.initialDelayMs * 2 ** (attempt - 1));\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((r) => setTimeout(r, ms));\n}\n\nfunction isNetworkError(e: unknown): boolean {\n return e instanceof TypeError;\n}\n\nexport function newIdempotencyKey(): string {\n return crypto.randomUUID();\n}\n","import type { components } from './types.js';\nimport {\n type ClientOptions,\n type FetchClient,\n type RetryConfig,\n type UnauthenticatedOptions,\n DEFAULT_RETRY,\n makeClient,\n makeUnauthenticatedClient,\n newIdempotencyKey,\n runWithRetry,\n} from './http.js';\nimport { errorFromResponse } from './errors.js';\n\ntype Schemas = components['schemas'];\n\n// ---------------------------------------------------------------------------\n// Re-exported user-facing types (so consumers don't import paths/components)\n// ---------------------------------------------------------------------------\n\nexport type Chain = Schemas['Chain'];\nexport type RequestType = Schemas['RequestType'];\nexport type RequestStatus = Schemas['RequestStatus'];\n\nexport type RegisterRequest = Schemas['RegisterRequest'];\nexport type RegisterResponse = Schemas['RegisterResponse'];\nexport type AddressResponse = Schemas['AddressResponse'];\nexport type BalanceResponse = Schemas['BalanceResponse'];\nexport type TokensResponse = Schemas['TokensResponse'];\n\nexport type CallRequest = Schemas['CallRequest'];\nexport type CallResponse = Schemas['CallResponse'];\nexport type TransferRequest = Schemas['TransferRequest'];\nexport type IntentsDepositRequest = Schemas['IntentsDepositRequest'];\nexport type IntentsDepositResponse = Schemas['IntentsDepositResponse'];\n\nexport type WithdrawRequest = Schemas['WithdrawRequest'];\nexport type WithdrawResponse = Schemas['WithdrawResponse'];\nexport type DryRunResponse = Schemas['DryRunResponse'];\n\nexport type SwapRequest = Schemas['SwapRequest'];\nexport type SwapResponse = Schemas['SwapResponse'];\nexport type SwapQuoteResponse = Schemas['SwapQuoteResponse'];\n\nexport type SignMessageRequest = Schemas['SignMessageRequest'];\nexport type SignMessageResponse = Schemas['SignMessageResponse'];\n\nexport type RequestStatusResponse = Schemas['RequestStatusResponse'];\nexport type RequestListResponse = Schemas['RequestListResponse'];\n\nexport type PolicyResponse = Schemas['PolicyResponse'];\nexport type PolicyRules = Schemas['PolicyRules'];\nexport type ApprovalConfig = Schemas['ApprovalConfig'];\nexport type EncryptPolicyRequest = Schemas['EncryptPolicyRequest'];\nexport type EncryptPolicyResponse = Schemas['EncryptPolicyResponse'];\nexport type SignPolicyResponse = Schemas['SignPolicyResponse'];\n\nexport type PendingApproval = Schemas['PendingApproval'];\nexport type PendingApprovalsResponse = Schemas['PendingApprovalsResponse'];\nexport type Nep413Auth = Schemas['Nep413Auth'];\nexport type ApproveResponse = Schemas['ApproveResponse'];\n\nexport type AuditEvent = Schemas['AuditEvent'];\nexport type AuditResponse = Schemas['AuditResponse'];\n\n// ---------------------------------------------------------------------------\n// Shared helpers\n// ---------------------------------------------------------------------------\n\ntype Idempotent = { idempotencyKey?: string };\n\nfunction idempotencyHeader(key: string | undefined): Record<string, string> {\n return { 'Idempotency-Key': key ?? newIdempotencyKey() };\n}\n\n// ---------------------------------------------------------------------------\n// Sub-namespaces\n// ---------------------------------------------------------------------------\n\nexport class PolicyAPI {\n constructor(\n private readonly client: FetchClient,\n private readonly retry: Required<RetryConfig>,\n ) {}\n\n get(): Promise<PolicyResponse> {\n return runWithRetry(() => this.client.GET('/wallet/v1/policy'), this.retry);\n }\n\n encrypt(body: EncryptPolicyRequest): Promise<EncryptPolicyResponse> {\n return runWithRetry(() => this.client.POST('/wallet/v1/encrypt-policy', { body }), this.retry);\n }\n\n sign(encryptedData: string): Promise<SignPolicyResponse> {\n return runWithRetry(\n () => this.client.POST('/wallet/v1/sign-policy', { body: { encrypted_data: encryptedData } }),\n this.retry,\n );\n }\n\n invalidateCache(walletId: string): Promise<void> {\n return runWithRetry(\n () => this.client.POST('/wallet/v1/invalidate-cache', { body: { wallet_id: walletId } }),\n this.retry,\n ).then(() => undefined);\n }\n}\n\nexport class ApprovalsAPI {\n constructor(\n private readonly client: FetchClient,\n private readonly retry: Required<RetryConfig>,\n ) {}\n\n listPending(): Promise<PendingApprovalsResponse> {\n return runWithRetry(() => this.client.GET('/wallet/v1/pending_approvals'), this.retry);\n }\n\n approve(approvalId: string, auth: Nep413Auth): Promise<ApproveResponse> {\n return runWithRetry(\n () =>\n this.client.POST('/wallet/v1/approve/{id}', {\n params: { path: { id: approvalId } },\n body: auth,\n }),\n this.retry,\n );\n }\n\n reject(approvalId: string, auth: Nep413Auth, reason?: string): Promise<ApproveResponse> {\n const body = reason !== undefined ? { ...auth, reason } : auth;\n return runWithRetry(\n () =>\n this.client.POST('/wallet/v1/reject/{id}', {\n params: { path: { id: approvalId } },\n body,\n }),\n this.retry,\n );\n }\n}\n\nexport class AuditAPI {\n constructor(\n private readonly client: FetchClient,\n private readonly retry: Required<RetryConfig>,\n ) {}\n\n list(opts: { limit?: number; offset?: number } = {}): Promise<AuditResponse> {\n return runWithRetry(\n () => this.client.GET('/wallet/v1/audit', { params: { query: opts } }),\n this.retry,\n );\n }\n}\n\n// ---------------------------------------------------------------------------\n// Main client\n// ---------------------------------------------------------------------------\n\nexport class OutlayerClient {\n private readonly client: FetchClient;\n private readonly retry: Required<RetryConfig>;\n\n readonly policy: PolicyAPI;\n readonly approvals: ApprovalsAPI;\n readonly audit: AuditAPI;\n\n constructor(opts: ClientOptions) {\n const { client, retry } = makeClient(opts);\n this.client = client;\n this.retry = retry;\n this.policy = new PolicyAPI(client, retry);\n this.approvals = new ApprovalsAPI(client, retry);\n this.audit = new AuditAPI(client, retry);\n }\n\n // ------- Static factory: register a new wallet (no auth) -------\n\n /**\n * Register a new wallet and obtain an API key.\n *\n * - Empty call: anonymous wallet on OutLayer's shared master. Convenient, no setup.\n * - With `vaultId`: bind to a deployed customer vault so keys derive through\n * the per-vault master. Vault binding is permanent.\n * - With `body`: full control — pass any `RegisterRequest` field (e.g., NEP-413\n * account-binding fields). `vaultId` is merged into `body.vault_id` if not\n * already set.\n *\n * Vault deployment is NOT done here — use the dashboard\n * (https://outlayer.fastnear.com/vault) or `outlayer vault init` CLI.\n * See docs/vaults.md for the full flow.\n */\n static async register(\n opts: {\n vaultId?: string;\n body?: RegisterRequest;\n } & UnauthenticatedOptions = {},\n ): Promise<RegisterResponse> {\n const client = makeUnauthenticatedClient(opts);\n const body: RegisterRequest = { ...(opts.body ?? {}) };\n if (opts.vaultId !== undefined && body.vault_id === undefined) {\n body.vault_id = opts.vaultId;\n }\n const { data, error, response } = await client.POST('/register', { body });\n if (!response.ok) throw await errorFromResponse(response, error);\n return data as RegisterResponse;\n }\n\n // ------- Wallet read -------\n\n getAddress(chain: Chain): Promise<AddressResponse> {\n return runWithRetry(\n () => this.client.GET('/wallet/v1/address', { params: { query: { chain } } }),\n this.retry,\n );\n }\n\n getBalance(\n opts: { chain?: Chain; token?: string; source?: 'chain' | 'intents' } = {},\n ): Promise<BalanceResponse> {\n return runWithRetry(\n () => this.client.GET('/wallet/v1/balance', { params: { query: opts } }),\n this.retry,\n );\n }\n\n listTokens(): Promise<TokensResponse> {\n return runWithRetry(() => this.client.GET('/wallet/v1/tokens'), this.retry);\n }\n\n // ------- Wallet write -------\n\n call(opts: CallRequest & Idempotent): Promise<CallResponse> {\n const { idempotencyKey, ...body } = opts;\n return runWithRetry(\n () =>\n this.client.POST('/wallet/v1/call', {\n body: body as CallRequest,\n headers: idempotencyHeader(idempotencyKey),\n }),\n this.retry,\n );\n }\n\n transfer(opts: TransferRequest & Idempotent): Promise<CallResponse> {\n const { idempotencyKey, ...body } = opts;\n return runWithRetry(\n () =>\n this.client.POST('/wallet/v1/transfer', {\n body: body as TransferRequest,\n headers: idempotencyHeader(idempotencyKey),\n }),\n this.retry,\n );\n }\n\n intentsDeposit(opts: IntentsDepositRequest & Idempotent): Promise<IntentsDepositResponse> {\n const { idempotencyKey, ...body } = opts;\n return runWithRetry(\n () =>\n this.client.POST('/wallet/v1/intents/deposit', {\n body: body as IntentsDepositRequest,\n headers: idempotencyHeader(idempotencyKey),\n }),\n this.retry,\n );\n }\n\n withdraw(opts: WithdrawRequest & Idempotent): Promise<WithdrawResponse> {\n const { idempotencyKey, ...body } = opts;\n return runWithRetry(\n () =>\n this.client.POST('/wallet/v1/intents/withdraw', {\n body: body as WithdrawRequest,\n headers: idempotencyHeader(idempotencyKey),\n }),\n this.retry,\n );\n }\n\n withdrawDryRun(opts: WithdrawRequest): Promise<DryRunResponse> {\n return runWithRetry(\n () => this.client.POST('/wallet/v1/intents/withdraw/dry-run', { body: opts }),\n this.retry,\n );\n }\n\n swap(opts: SwapRequest & Idempotent): Promise<SwapResponse> {\n const { idempotencyKey, ...body } = opts;\n return runWithRetry(\n () =>\n this.client.POST('/wallet/v1/intents/swap', {\n body: body as SwapRequest,\n headers: idempotencyHeader(idempotencyKey),\n }),\n this.retry,\n );\n }\n\n swapQuote(opts: SwapRequest): Promise<SwapQuoteResponse> {\n return runWithRetry(\n () => this.client.POST('/wallet/v1/intents/swap/quote', { body: opts }),\n this.retry,\n );\n }\n\n signMessage(opts: SignMessageRequest): Promise<SignMessageResponse> {\n return runWithRetry(\n () => this.client.POST('/wallet/v1/sign-message', { body: opts }),\n this.retry,\n );\n }\n\n // ------- Async request tracking -------\n\n getRequest(id: string): Promise<RequestStatusResponse> {\n return runWithRetry(\n () => this.client.GET('/wallet/v1/requests/{id}', { params: { path: { id } } }),\n this.retry,\n );\n }\n\n listRequests(\n opts: { type?: RequestType; status?: RequestStatus; limit?: number; offset?: number } = {},\n ): Promise<RequestListResponse> {\n return runWithRetry(\n () => this.client.GET('/wallet/v1/requests', { params: { query: opts } }),\n this.retry,\n );\n }\n}\n"]}
|