@opensea/wallet-adapters 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -8
- package/dist/ethers.d.ts +1 -1
- package/dist/{index-DqqC-Sa8.d.ts → index-BbwVMCvI.d.ts} +65 -2
- package/dist/index.d.ts +222 -12
- package/dist/index.js +312 -57
- package/dist/index.js.map +1 -1
- package/dist/viem.d.ts +1 -1
- package/package.json +20 -8
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@ Provider-agnostic wallet adapters for signing and sending transactions across ma
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
7
|
- **Provider-agnostic interface** — unified `WalletAdapter` abstraction with capabilities declaration
|
|
8
|
-
- **Managed providers** — Privy, Turnkey, Fireblocks (handle gas/nonce server-side)
|
|
8
|
+
- **Managed providers** — Privy, Turnkey, Fireblocks, Bankr (handle gas/nonce server-side)
|
|
9
9
|
- **Local providers** — PrivateKey (handle gas/nonce client-side via RPC)
|
|
10
10
|
- **Framework bridges** — optional adapters for viem and ethers.js
|
|
11
11
|
- **Zero heavy dependencies** — core uses Web Crypto + `@noble/hashes` / `@noble/curves`
|
|
@@ -25,7 +25,7 @@ pnpm add @opensea/wallet-adapters
|
|
|
25
25
|
import { createWalletFromEnv } from "@opensea/wallet-adapters"
|
|
26
26
|
|
|
27
27
|
// Auto-detects provider from environment variables
|
|
28
|
-
// Priority: Privy > Fireblocks > Turnkey > PrivateKey
|
|
28
|
+
// Priority: Privy > Fireblocks > Turnkey > Bankr > PrivateKey
|
|
29
29
|
const wallet = createWalletFromEnv()
|
|
30
30
|
|
|
31
31
|
const address = await wallet.getAddress()
|
|
@@ -74,6 +74,17 @@ const wallet = TurnkeyAdapter.fromEnv()
|
|
|
74
74
|
// TURNKEY_ORGANIZATION_ID, TURNKEY_WALLET_ADDRESS, TURNKEY_RPC_URL
|
|
75
75
|
```
|
|
76
76
|
|
|
77
|
+
### Bankr
|
|
78
|
+
|
|
79
|
+
Managed agent wallet via Bankr's Wallet API. Auth is a single API key; the provider handles gas, nonce, and broadcast.
|
|
80
|
+
|
|
81
|
+
```ts
|
|
82
|
+
import { BankrAdapter } from "@opensea/wallet-adapters"
|
|
83
|
+
|
|
84
|
+
const wallet = BankrAdapter.fromEnv()
|
|
85
|
+
// Requires: BANKR_API_KEY
|
|
86
|
+
```
|
|
87
|
+
|
|
77
88
|
### PrivateKey
|
|
78
89
|
|
|
79
90
|
Local signing for development and testing.
|
|
@@ -120,12 +131,12 @@ if (wallet.capabilities.managedGas) {
|
|
|
120
131
|
}
|
|
121
132
|
```
|
|
122
133
|
|
|
123
|
-
| Capability | Privy | Fireblocks | Turnkey | PrivateKey |
|
|
124
|
-
|
|
125
|
-
| `signMessage` | true | true | true | true |
|
|
126
|
-
| `signTypedData` | true | true | true | true |
|
|
127
|
-
| `managedGas` | true | true | false | false |
|
|
128
|
-
| `managedNonce` | true | true | false | false |
|
|
134
|
+
| Capability | Privy | Fireblocks | Turnkey | Bankr | PrivateKey |
|
|
135
|
+
|------------|-------|------------|---------|-------|------------|
|
|
136
|
+
| `signMessage` | true | true | true | true | true |
|
|
137
|
+
| `signTypedData` | true | true | true | true | true |
|
|
138
|
+
| `managedGas` | true | true | false | true | false |
|
|
139
|
+
| `managedNonce` | true | true | false | true | false |
|
|
129
140
|
|
|
130
141
|
## Observability
|
|
131
142
|
|
package/dist/ethers.d.ts
CHANGED
|
@@ -5,6 +5,61 @@
|
|
|
5
5
|
* Designed to be provider-agnostic and extensible for future signing
|
|
6
6
|
* capabilities (EIP-712, EIP-191, batch transactions, etc.).
|
|
7
7
|
*/
|
|
8
|
+
/**
|
|
9
|
+
* Provider-shaped wallet metadata used by the `opensea wallet info` CLI
|
|
10
|
+
* command and by callers auditing the security posture of an agent wallet.
|
|
11
|
+
*
|
|
12
|
+
* Each variant surfaces only what the provider's API actually exposes for
|
|
13
|
+
* the calling credentials. Fields whose absence indicates a hardening gap
|
|
14
|
+
* (no on-chain policy enforcement, no off-machine credential gating
|
|
15
|
+
* administrative changes, etc.) are intentionally surfaced as falsy values
|
|
16
|
+
* rather than hidden, so callers can warn the user.
|
|
17
|
+
*/
|
|
18
|
+
type WalletInfo = {
|
|
19
|
+
provider: "privy";
|
|
20
|
+
address: string;
|
|
21
|
+
chainType: string;
|
|
22
|
+
policyIds: string[];
|
|
23
|
+
ownerKeyId: string | null;
|
|
24
|
+
additionalSignerCount: number;
|
|
25
|
+
/**
|
|
26
|
+
* True iff the wallet has an `owner_id` set, in which case all
|
|
27
|
+
* `/v1/wallets/{id}/rpc` requests must carry an authorization
|
|
28
|
+
* signature from the owner's key quorum. False means the env app
|
|
29
|
+
* secret can sign and rewrite policy unilaterally.
|
|
30
|
+
*/
|
|
31
|
+
ownerEnforcesAuthKey: boolean;
|
|
32
|
+
} | {
|
|
33
|
+
provider: "turnkey";
|
|
34
|
+
address: string;
|
|
35
|
+
organizationId: string;
|
|
36
|
+
userId: string;
|
|
37
|
+
username: string;
|
|
38
|
+
/**
|
|
39
|
+
* True iff the calling API user is in the organization's root
|
|
40
|
+
* quorum. Root users bypass Turnkey's policy engine entirely, so a
|
|
41
|
+
* leaked root API key has the same blast radius as a raw private
|
|
42
|
+
* key — sign, mutate, export, all unconstrained.
|
|
43
|
+
*/
|
|
44
|
+
isRootUser: boolean;
|
|
45
|
+
} | {
|
|
46
|
+
provider: "fireblocks";
|
|
47
|
+
address: string;
|
|
48
|
+
vaultId: string;
|
|
49
|
+
/**
|
|
50
|
+
* Fireblocks does not expose API-user role via API. The CLI
|
|
51
|
+
* surfaces a static reminder to verify the role at the console.
|
|
52
|
+
*/
|
|
53
|
+
roleIntrospectable: false;
|
|
54
|
+
} | {
|
|
55
|
+
provider: "bankr";
|
|
56
|
+
address: string;
|
|
57
|
+
/**
|
|
58
|
+
* Bankr does not expose key-scope flags via API. The CLI surfaces
|
|
59
|
+
* a static reminder to verify scope at bankr.bot/api.
|
|
60
|
+
*/
|
|
61
|
+
scopeIntrospectable: false;
|
|
62
|
+
};
|
|
8
63
|
interface TransactionRequest {
|
|
9
64
|
to: string;
|
|
10
65
|
data: string;
|
|
@@ -53,6 +108,14 @@ interface WalletAdapter {
|
|
|
53
108
|
signMessage?(request: SignMessageRequest): Promise<string>;
|
|
54
109
|
/** Sign EIP-712 typed data. Throws if not supported. */
|
|
55
110
|
signTypedData?(request: SignTypedDataRequest): Promise<string>;
|
|
111
|
+
/**
|
|
112
|
+
* Read-only metadata about the wallet's security posture. Used by the
|
|
113
|
+
* `opensea wallet info` CLI to surface hardening gaps (no policy, no
|
|
114
|
+
* authorization-key gating, root-user API key, etc.). Optional because
|
|
115
|
+
* not every adapter has a meaningful introspection surface — the
|
|
116
|
+
* private-key adapter, for instance, has nothing to report.
|
|
117
|
+
*/
|
|
118
|
+
getWalletInfo?(): Promise<WalletInfo>;
|
|
56
119
|
/** Optional RPC URL for read operations (gas estimation, nonce, etc.) */
|
|
57
120
|
getRpcUrl?(): string;
|
|
58
121
|
/** Optional hook called before each adapter request (for metrics/logging) */
|
|
@@ -74,7 +137,7 @@ interface WalletCapabilities {
|
|
|
74
137
|
/** Whether the provider manages nonce internally */
|
|
75
138
|
managedNonce: boolean;
|
|
76
139
|
}
|
|
77
|
-
type WalletProvider = "privy" | "turnkey" | "fireblocks" | "private-key";
|
|
140
|
+
type WalletProvider = "privy" | "turnkey" | "fireblocks" | "bankr" | "private-key";
|
|
78
141
|
declare const WALLET_PROVIDERS: WalletProvider[];
|
|
79
142
|
|
|
80
|
-
export { type SignMessageRequest as S, type TransactionRequest as T, type WalletAdapter as W, type WalletCapabilities as a, type
|
|
143
|
+
export { type SignMessageRequest as S, type TransactionRequest as T, type WalletAdapter as W, type WalletCapabilities as a, type WalletInfo as b, type TransactionResult as c, type SignTypedDataRequest as d, type WalletProvider as e, WALLET_PROVIDERS as f };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,83 @@
|
|
|
1
|
-
import { W as WalletAdapter, a as WalletCapabilities, T as TransactionRequest,
|
|
2
|
-
export {
|
|
1
|
+
import { W as WalletAdapter, a as WalletCapabilities, b as WalletInfo, T as TransactionRequest, c as TransactionResult, S as SignMessageRequest, d as SignTypedDataRequest, e as WalletProvider } from './index-BbwVMCvI.js';
|
|
2
|
+
export { f as WALLET_PROVIDERS } from './index-BbwVMCvI.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Bankr wallet adapter.
|
|
6
|
+
*
|
|
7
|
+
* Uses Bankr's Wallet API to sign and send transactions via a managed
|
|
8
|
+
* agent wallet. Authentication is done via API key in the X-API-Key header.
|
|
9
|
+
*
|
|
10
|
+
* # Security model
|
|
11
|
+
*
|
|
12
|
+
* This adapter is **signing-only by design.** It exposes only the
|
|
13
|
+
* primitives an agent needs: `getAddress`, `sendTransaction`,
|
|
14
|
+
* `signMessage`, `signTypedData`, and `getWalletInfo`. Future
|
|
15
|
+
* contributors: do not add scope-mutation or key-management surfaces
|
|
16
|
+
* here — Bankr does not expose them via API anyway, and adding
|
|
17
|
+
* adapter-side wrappers around dashboard ops would be a footgun.
|
|
18
|
+
*
|
|
19
|
+
* Effective hardening is done at the API key configuration level on
|
|
20
|
+
* bankr.bot/api, not in this adapter:
|
|
21
|
+
*
|
|
22
|
+
* 1. For monitoring-only agents, enable the key's `readOnly` flag —
|
|
23
|
+
* `/wallet/sign` and `/wallet/submit` will return 403.
|
|
24
|
+
*
|
|
25
|
+
* 2. For signing agents, set `allowedRecipients` (an EVM/Solana
|
|
26
|
+
* address allowlist) and `allowedIps` (CIDR allowlist) on the
|
|
27
|
+
* key. Disable `agentApiEnabled` if the agent does not need
|
|
28
|
+
* Bankr's prompt API.
|
|
29
|
+
*
|
|
30
|
+
* 3. Set per-key daily message limits at bankr.bot/api.
|
|
31
|
+
*
|
|
32
|
+
* 4. Bankr does not expose key-scope flags via API, so
|
|
33
|
+
* `getWalletInfo()` cannot verify these settings at runtime —
|
|
34
|
+
* `opensea wallet info` reminds the user to verify scope at the
|
|
35
|
+
* dashboard. Re-confirm after any key rotation.
|
|
36
|
+
*
|
|
37
|
+
* 5. Bankr keys cannot enforce aggregate dollar/ETH spend caps; daily
|
|
38
|
+
* message-quota limits are not the same thing. Use the hot/cold
|
|
39
|
+
* wallet float pattern documented in
|
|
40
|
+
* `packages/skill/opensea-wallet/references/wallet-funding.md`.
|
|
41
|
+
*
|
|
42
|
+
* Required environment variables:
|
|
43
|
+
* BANKR_API_KEY — Bankr API key with Wallet API access enabled
|
|
44
|
+
*
|
|
45
|
+
* Optional:
|
|
46
|
+
* BANKR_API_BASE_URL — Override the Bankr API base URL
|
|
47
|
+
*
|
|
48
|
+
* @see https://docs.bankr.bot/agent-api/authentication
|
|
49
|
+
* @see https://docs.bankr.bot/agent-api/access-control
|
|
50
|
+
*/
|
|
51
|
+
|
|
52
|
+
interface BankrConfig {
|
|
53
|
+
apiKey: string;
|
|
54
|
+
baseUrl?: string;
|
|
55
|
+
}
|
|
56
|
+
declare class BankrAdapter implements WalletAdapter {
|
|
57
|
+
readonly name = "bankr";
|
|
58
|
+
readonly capabilities: WalletCapabilities;
|
|
59
|
+
onRequest?: (method: string, params: unknown) => void;
|
|
60
|
+
onResponse?: (method: string, result: unknown, durationMs: number) => void;
|
|
61
|
+
private config;
|
|
62
|
+
private cachedAddress?;
|
|
63
|
+
constructor(config: BankrConfig);
|
|
64
|
+
static fromEnv(): BankrAdapter;
|
|
65
|
+
private get baseUrl();
|
|
66
|
+
private get authHeaders();
|
|
67
|
+
getAddress(): Promise<string>;
|
|
68
|
+
getWalletInfo(): Promise<WalletInfo>;
|
|
69
|
+
sendTransaction(tx: TransactionRequest): Promise<TransactionResult>;
|
|
70
|
+
signMessage(request: SignMessageRequest): Promise<string>;
|
|
71
|
+
signTypedData(request: SignTypedDataRequest): Promise<string>;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* AUTO-GENERATED by scripts/sync-chains.ts — DO NOT EDIT.
|
|
76
|
+
* Source of truth: OpenSea REST API + scripts/chain-data.json
|
|
77
|
+
* Run `pnpm sync-chains` to regenerate.
|
|
78
|
+
*/
|
|
79
|
+
/** Map EVM chain IDs to Fireblocks asset IDs. */
|
|
80
|
+
declare const CHAIN_TO_FIREBLOCKS_ASSET: Record<number, string>;
|
|
3
81
|
|
|
4
82
|
/**
|
|
5
83
|
* Fireblocks wallet adapter.
|
|
@@ -7,8 +85,43 @@ export { e as WALLET_PROVIDERS } from './index-DqqC-Sa8.js';
|
|
|
7
85
|
* Uses Fireblocks' REST API to sign and send transactions through their
|
|
8
86
|
* enterprise-grade MPC custody infrastructure.
|
|
9
87
|
*
|
|
88
|
+
* # Security model
|
|
89
|
+
*
|
|
90
|
+
* This adapter is **signing-only by design.** It exposes only the
|
|
91
|
+
* primitives an agent needs to sign and send transactions:
|
|
92
|
+
* `getAddress`, `sendTransaction`, `signMessage`, `signTypedData`, and
|
|
93
|
+
* `getWalletInfo`. Future contributors: **do not add
|
|
94
|
+
* `createTransactionAuthPolicy`, `updateUser`, `createApiUser`,
|
|
95
|
+
* `whitelistAddress`, or any other administrative endpoint to this
|
|
96
|
+
* adapter.** If they exist, an agent will find and use them.
|
|
97
|
+
*
|
|
98
|
+
* Effective hardening requires creating the API key with the **`Signer`
|
|
99
|
+
* role** and nothing broader:
|
|
100
|
+
*
|
|
101
|
+
* 1. Fireblocks supports nine API key roles: Admin, Signer,
|
|
102
|
+
* NCW_SIGNER, Non-Signing Admin, Approver, Editor, NCW_ADMIN,
|
|
103
|
+
* Viewer, and Security Auditor. Only `Signer` (or `NCW_SIGNER`)
|
|
104
|
+
* gives signing capability without governance access. Do not use
|
|
105
|
+
* `Admin` for an agent.
|
|
106
|
+
*
|
|
107
|
+
* 2. Fireblocks does not expose API-user role via API — there is no
|
|
108
|
+
* `/v1/users/me` introspection endpoint, and `GET /v1/users/{id}`
|
|
109
|
+
* itself requires admin role. `getWalletInfo()` therefore cannot
|
|
110
|
+
* verify the calling key's role at runtime; verify it manually at
|
|
111
|
+
* console.fireblocks.io and re-confirm whenever you rotate the key.
|
|
112
|
+
*
|
|
113
|
+
* 3. TAP changes require admin quorum approval at the console — a
|
|
114
|
+
* leaked Signer-role key cannot rewrite TAP. This is structurally
|
|
115
|
+
* stronger than Privy or Turnkey, but only if the key is actually
|
|
116
|
+
* `Signer` rather than `Admin`.
|
|
117
|
+
*
|
|
118
|
+
* 4. TAP rules cap per-tx values; aggregate (daily/weekly) caps are
|
|
119
|
+
* not a TAP primitive. Use the hot/cold wallet float pattern
|
|
120
|
+
* documented in
|
|
121
|
+
* `packages/skill/opensea-wallet/references/wallet-funding.md`.
|
|
122
|
+
*
|
|
10
123
|
* Required environment variables:
|
|
11
|
-
* FIREBLOCKS_API_KEY — Fireblocks API key
|
|
124
|
+
* FIREBLOCKS_API_KEY — Fireblocks API key (must be Signer role)
|
|
12
125
|
* FIREBLOCKS_API_SECRET — Fireblocks API secret (RSA private key, PEM-encoded)
|
|
13
126
|
* FIREBLOCKS_VAULT_ID — Fireblocks vault account ID
|
|
14
127
|
*
|
|
@@ -17,11 +130,10 @@ export { e as WALLET_PROVIDERS } from './index-DqqC-Sa8.js';
|
|
|
17
130
|
* FIREBLOCKS_ASSET_ID — Override the Fireblocks asset ID
|
|
18
131
|
* FIREBLOCKS_MAX_POLL_ATTEMPTS — Override max polling attempts (default: 60 = 120s)
|
|
19
132
|
*
|
|
20
|
-
* @see https://developers.fireblocks.com/docs/
|
|
133
|
+
* @see https://developers.fireblocks.com/docs/manage-api-keys
|
|
134
|
+
* @see https://developers.fireblocks.com/docs/manage-users
|
|
21
135
|
*/
|
|
22
136
|
|
|
23
|
-
/** Map EVM chain IDs to Fireblocks asset IDs. */
|
|
24
|
-
declare const CHAIN_TO_FIREBLOCKS_ASSET: Record<number, string>;
|
|
25
137
|
interface FireblocksConfig {
|
|
26
138
|
apiKey: string;
|
|
27
139
|
apiSecret: string;
|
|
@@ -45,6 +157,7 @@ declare class FireblocksAdapter implements WalletAdapter {
|
|
|
45
157
|
private hashBody;
|
|
46
158
|
private resolveAssetId;
|
|
47
159
|
getAddress(): Promise<string>;
|
|
160
|
+
getWalletInfo(): Promise<WalletInfo>;
|
|
48
161
|
sendTransaction(tx: TransactionRequest): Promise<TransactionResult>;
|
|
49
162
|
signMessage(request: SignMessageRequest): Promise<string>;
|
|
50
163
|
signTypedData(request: SignTypedDataRequest): Promise<string>;
|
|
@@ -98,16 +211,58 @@ declare class PrivateKeyAdapter implements WalletAdapter {
|
|
|
98
211
|
* Transactions are governed by Privy's programmable policy engine —
|
|
99
212
|
* policies are evaluated in a trusted execution environment before signing.
|
|
100
213
|
*
|
|
214
|
+
* # Security model
|
|
215
|
+
*
|
|
216
|
+
* This adapter is **signing-only by design.** It exposes only the
|
|
217
|
+
* primitives an agent needs to sign transactions and read wallet
|
|
218
|
+
* metadata: `getAddress`, `sendTransaction`, `signMessage`,
|
|
219
|
+
* `signTypedData`, and `getWalletInfo`. It deliberately does not, and
|
|
220
|
+
* should not, expose policy mutation, owner-key rotation, additional-
|
|
221
|
+
* signer changes, key export, or wallet deletion. Future contributors:
|
|
222
|
+
* **do not add `setPolicy`, `rotateOwner`, `addSigner`, or similar
|
|
223
|
+
* mutation methods to this adapter.** If they exist, an agent will find
|
|
224
|
+
* and use them — including raising its own spending cap.
|
|
225
|
+
*
|
|
226
|
+
* Effective hardening requires Privy-side configuration in addition to
|
|
227
|
+
* this adapter's defaults:
|
|
228
|
+
*
|
|
229
|
+
* 1. Create the wallet with an `owner_id` (a key quorum). The owner's
|
|
230
|
+
* private key MUST live outside the agent environment — on a
|
|
231
|
+
* trusted operator machine, in a hardware wallet, or in a separate
|
|
232
|
+
* vault. The owner gates all `PATCH /v1/wallets/{id}` and similar
|
|
233
|
+
* administrative operations.
|
|
234
|
+
*
|
|
235
|
+
* 2. Register the agent's signing key as an `additional_signer` on the
|
|
236
|
+
* wallet, with `override_policy_ids` set to the policy you want
|
|
237
|
+
* the agent to be subject to. The agent's signing key may live in
|
|
238
|
+
* env (`PRIVY_AUTH_SIGNING_KEY`) — it has signing power but cannot
|
|
239
|
+
* mutate policy, signers, or owner.
|
|
240
|
+
*
|
|
241
|
+
* 3. Apply a Privy policy that caps per-tx spend, allowlists
|
|
242
|
+
* contracts, and restricts chains. Policies are stateless per-tx
|
|
243
|
+
* evaluators — they cannot enforce aggregate (daily/weekly)
|
|
244
|
+
* caps. Use the hot/cold wallet float pattern documented in
|
|
245
|
+
* `packages/skill/opensea-wallet/references/wallet-funding.md`
|
|
246
|
+
* for aggregate ceilings.
|
|
247
|
+
*
|
|
101
248
|
* Required environment variables:
|
|
102
249
|
* PRIVY_APP_ID — Privy application ID
|
|
103
250
|
* PRIVY_APP_SECRET — Privy application secret
|
|
104
251
|
* PRIVY_WALLET_ID — Wallet ID to use for signing
|
|
105
252
|
*
|
|
106
253
|
* Optional:
|
|
107
|
-
* PRIVY_API_BASE_URL
|
|
254
|
+
* PRIVY_API_BASE_URL — Override the Privy API base URL
|
|
255
|
+
* PRIVY_AUTH_SIGNING_KEY — Base64-encoded PKCS8 P-256 private key for
|
|
256
|
+
* an `additional_signer` on this wallet. When
|
|
257
|
+
* set, the adapter signs every POST /rpc
|
|
258
|
+
* request with it and attaches the
|
|
259
|
+
* `privy-authorization-signature` header.
|
|
260
|
+
* Required when the wallet has an `owner_id`
|
|
261
|
+
* set; ignored when it does not.
|
|
108
262
|
*
|
|
109
|
-
* @see https://docs.privy.io/wallets/wallets
|
|
263
|
+
* @see https://docs.privy.io/wallets/wallets
|
|
110
264
|
* @see https://docs.privy.io/controls/policies/overview
|
|
265
|
+
* @see https://docs.privy.io/controls/authorization-keys/overview
|
|
111
266
|
*/
|
|
112
267
|
|
|
113
268
|
interface PrivyConfig {
|
|
@@ -115,6 +270,15 @@ interface PrivyConfig {
|
|
|
115
270
|
appSecret: string;
|
|
116
271
|
walletId: string;
|
|
117
272
|
baseUrl?: string;
|
|
273
|
+
/**
|
|
274
|
+
* Optional base64-encoded PKCS8 P-256 authorization private key.
|
|
275
|
+
* When set, every POST /v1/wallets/{id}/rpc request is signed with it
|
|
276
|
+
* and the resulting signature is attached as
|
|
277
|
+
* `privy-authorization-signature`. Use this when the wallet has an
|
|
278
|
+
* `owner_id` configured and the agent's key is registered as an
|
|
279
|
+
* `additional_signer`.
|
|
280
|
+
*/
|
|
281
|
+
authSigningKey?: string;
|
|
118
282
|
}
|
|
119
283
|
declare class PrivyAdapter implements WalletAdapter {
|
|
120
284
|
readonly name = "privy";
|
|
@@ -126,8 +290,16 @@ declare class PrivyAdapter implements WalletAdapter {
|
|
|
126
290
|
constructor(config: PrivyConfig);
|
|
127
291
|
static fromEnv(): PrivyAdapter;
|
|
128
292
|
private get baseUrl();
|
|
129
|
-
private get
|
|
293
|
+
private get basicAuthHeaders();
|
|
294
|
+
/**
|
|
295
|
+
* Build headers for a POST /rpc call, including the authorization
|
|
296
|
+
* signature when `authSigningKey` is configured. Lazy-imports
|
|
297
|
+
* `@privy-io/node` so users who don't enable auth-key signing don't
|
|
298
|
+
* need the optional peer dependency installed.
|
|
299
|
+
*/
|
|
300
|
+
private rpcHeaders;
|
|
130
301
|
getAddress(): Promise<string>;
|
|
302
|
+
getWalletInfo(): Promise<WalletInfo>;
|
|
131
303
|
sendTransaction(tx: TransactionRequest): Promise<TransactionResult>;
|
|
132
304
|
signMessage(request: SignMessageRequest): Promise<string>;
|
|
133
305
|
signTypedData(request: SignTypedDataRequest): Promise<string>;
|
|
@@ -140,6 +312,42 @@ declare class PrivyAdapter implements WalletAdapter {
|
|
|
140
312
|
* signing infrastructure. Authentication uses Turnkey's stamp scheme:
|
|
141
313
|
* each request body is hashed and signed with a P-256 ECDSA key.
|
|
142
314
|
*
|
|
315
|
+
* # Security model
|
|
316
|
+
*
|
|
317
|
+
* This adapter is **signing-only by design.** It exposes only the
|
|
318
|
+
* primitives an agent needs to sign transactions and read user
|
|
319
|
+
* metadata: `getAddress`, `sendTransaction`, `signMessage`,
|
|
320
|
+
* `signTypedData`, and `getWalletInfo`. Future contributors: **do not
|
|
321
|
+
* add `createPolicy`, `deletePolicy`, `createApiKeys`, `updateUser`,
|
|
322
|
+
* `exportWallet`, or any other administrative activity submission to
|
|
323
|
+
* this adapter.** If they exist, an agent will find and use them.
|
|
324
|
+
*
|
|
325
|
+
* Effective hardening requires creating the API user as a **non-root
|
|
326
|
+
* user** with a tightly scoped sign-only policy:
|
|
327
|
+
*
|
|
328
|
+
* 1. Root users in Turnkey bypass the policy engine entirely. A
|
|
329
|
+
* leaked root-user API key has the same blast radius as a raw
|
|
330
|
+
* private key — it can sign anything, mutate any policy, mint new
|
|
331
|
+
* wallets, and export keys. Do not use a root user as the agent's
|
|
332
|
+
* API user.
|
|
333
|
+
*
|
|
334
|
+
* 2. Create a non-root API user, then attach a policy that allows
|
|
335
|
+
* only `ACTIVITY_TYPE_SIGN_TRANSACTION_V2` (and
|
|
336
|
+
* `ACTIVITY_TYPE_SIGN_RAW_PAYLOAD_V2` if EIP-712 is needed) for
|
|
337
|
+
* the wallet addresses the agent should be able to sign for.
|
|
338
|
+
* Default-deny on everything else; Turnkey policies default to
|
|
339
|
+
* deny so this is mostly a matter of writing the allowlist.
|
|
340
|
+
*
|
|
341
|
+
* 3. Note that Turnkey policies are stateless per-activity
|
|
342
|
+
* evaluators — they cannot enforce aggregate (daily/weekly) caps.
|
|
343
|
+
* Use the hot/cold wallet float pattern documented in
|
|
344
|
+
* `packages/skill/opensea-wallet/references/wallet-funding.md`
|
|
345
|
+
* for aggregate ceilings.
|
|
346
|
+
*
|
|
347
|
+
* `getWalletInfo()` calls `whoami` and `get_organization` to surface
|
|
348
|
+
* whether the API user is in the root quorum, so `opensea wallet info`
|
|
349
|
+
* can warn loudly if the agent is running as root.
|
|
350
|
+
*
|
|
143
351
|
* Required environment variables:
|
|
144
352
|
* TURNKEY_API_PUBLIC_KEY — Turnkey API public key (hex-encoded)
|
|
145
353
|
* TURNKEY_API_PRIVATE_KEY — Turnkey API private key (hex-encoded P-256)
|
|
@@ -151,7 +359,8 @@ declare class PrivyAdapter implements WalletAdapter {
|
|
|
151
359
|
* TURNKEY_API_BASE_URL — Override the Turnkey API base URL
|
|
152
360
|
* TURNKEY_PRIVATE_KEY_ID — Turnkey private key ID (for signing with a specific key)
|
|
153
361
|
*
|
|
154
|
-
* @see https://docs.turnkey.com/
|
|
362
|
+
* @see https://docs.turnkey.com/concepts/policies/overview
|
|
363
|
+
* @see https://docs.turnkey.com/concepts/users/best-practices
|
|
155
364
|
*/
|
|
156
365
|
|
|
157
366
|
interface TurnkeyConfig {
|
|
@@ -176,6 +385,7 @@ declare class TurnkeyAdapter implements WalletAdapter {
|
|
|
176
385
|
private stamp;
|
|
177
386
|
private signedRequest;
|
|
178
387
|
getAddress(): Promise<string>;
|
|
388
|
+
getWalletInfo(): Promise<WalletInfo>;
|
|
179
389
|
sendTransaction(tx: TransactionRequest): Promise<TransactionResult>;
|
|
180
390
|
signMessage(request: SignMessageRequest): Promise<string>;
|
|
181
391
|
signTypedData(request: SignTypedDataRequest): Promise<string>;
|
|
@@ -188,11 +398,11 @@ declare class TurnkeyAdapter implements WalletAdapter {
|
|
|
188
398
|
* Auto-detection factory that creates a WalletAdapter based on
|
|
189
399
|
* which environment variables are present.
|
|
190
400
|
*
|
|
191
|
-
* Priority: Privy > Fireblocks > Turnkey > PrivateKey
|
|
401
|
+
* Priority: Privy > Fireblocks > Turnkey > Bankr > PrivateKey
|
|
192
402
|
*/
|
|
193
403
|
|
|
194
404
|
declare function createWalletFromEnv(): WalletAdapter;
|
|
195
405
|
declare function createWalletForProvider(provider: WalletProvider): WalletAdapter;
|
|
196
406
|
declare function detectProvider(): WalletProvider | null;
|
|
197
407
|
|
|
198
|
-
export { CHAIN_TO_FIREBLOCKS_ASSET, FireblocksAdapter, type FireblocksConfig, PrivateKeyAdapter, type PrivateKeyConfig, PrivyAdapter, type PrivyConfig, SignMessageRequest, SignTypedDataRequest, TransactionRequest, TransactionResult, TurnkeyAdapter, type TurnkeyConfig, WalletAdapter, WalletCapabilities, WalletProvider, createWalletForProvider, createWalletFromEnv, detectProvider };
|
|
408
|
+
export { BankrAdapter, type BankrConfig, CHAIN_TO_FIREBLOCKS_ASSET, FireblocksAdapter, type FireblocksConfig, PrivateKeyAdapter, type PrivateKeyConfig, PrivyAdapter, type PrivyConfig, SignMessageRequest, SignTypedDataRequest, TransactionRequest, TransactionResult, TurnkeyAdapter, type TurnkeyConfig, WalletAdapter, WalletCapabilities, WalletInfo, WalletProvider, createWalletForProvider, createWalletFromEnv, detectProvider };
|