clanker-wallet 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Clanker Wallet 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,94 @@
1
+ # @clanker-wallet/sdk
2
+
3
+ TypeScript SDK for AI agents to request human-approved Ethereum transactions over an E2E encrypted relay.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @clanker-wallet/sdk
9
+ ```
10
+
11
+ ## Quickstart
12
+
13
+ ```typescript
14
+ import { ClankerWallet } from '@clanker-wallet/sdk'
15
+
16
+ const wallet = new ClankerWallet({ agentName: 'my-trading-bot' })
17
+
18
+ // Pair with human's web app (scan QR code to get pairing JSON)
19
+ wallet.pair(pairingJson)
20
+
21
+ // Request a transaction — blocks until human approves or rejects
22
+ const txHash = await wallet.requestTx({
23
+ chain_id: 1,
24
+ transaction: { to: '0x...', value: '1000000000000000000', data: '0x' },
25
+ context: { reason: 'Buy tokens', urgency: 'medium' },
26
+ })
27
+
28
+ console.log('tx hash:', txHash)
29
+ ```
30
+
31
+ ## How It Works
32
+
33
+ - **E2E encrypted** — agent and human derive an X25519 shared secret. The relay only sees ciphertext.
34
+ - **Relay transport** — lightweight WebSocket relay forwards encrypted messages between agent and human. No private keys touch the server.
35
+ - **Human approval** — the human reviews transaction details in the Clanker Wallet web app and signs with their own wallet (MetaMask, WalletConnect, etc).
36
+
37
+ ## API
38
+
39
+ ### `new ClankerWallet(options?)`
40
+
41
+ | Option | Type | Description |
42
+ |--------|------|-------------|
43
+ | `agentName` | `string` | Display name shown to human (optional) |
44
+ | `secretKey` | `Uint8Array` | 32-byte secret key to restore identity. Omit to generate new keypair. |
45
+
46
+ ### Properties
47
+
48
+ | Property | Type | Description |
49
+ |----------|------|-------------|
50
+ | `publicKey` | `Uint8Array` | Agent's X25519 public key |
51
+ | `secretKey` | `Uint8Array` | Agent's X25519 secret key (save this to persist identity) |
52
+ | `agentId` | `string` | Derived agent identifier (`agent_<pubkey_prefix>`) |
53
+ | `paired` | `boolean` | Whether `pair()` has been called |
54
+
55
+ ### `wallet.pair(qrData: string): PairingData`
56
+
57
+ Parse pairing JSON (from the web app's QR code) and store the human's public key and relay URL. Returns the parsed `PairingData`.
58
+
59
+ ### `wallet.requestTx(options): Promise<string>`
60
+
61
+ Send a transaction request and wait for human response. Resolves with the transaction hash on approval. Throws on rejection, timeout, or connection error.
62
+
63
+ | Option | Type | Description |
64
+ |--------|------|-------------|
65
+ | `chain_id` | `number` | Target chain (1 = mainnet, 137 = polygon, etc) |
66
+ | `transaction` | `{ to, value, data }` | Transaction parameters (`value` in wei) |
67
+ | `context` | `{ reason?, urgency?, expected_outcome? }` | Optional context shown to human |
68
+ | `timeout_ms` | `number` | Timeout in ms (default: 1 hour) |
69
+
70
+ ## Persisting Agent Identity
71
+
72
+ Save `wallet.secretKey` between sessions to keep the same agent identity:
73
+
74
+ ```typescript
75
+ import { writeFileSync, readFileSync, existsSync } from 'fs'
76
+
77
+ // Restore or create
78
+ const secretKey = existsSync('.agent-key')
79
+ ? new Uint8Array(readFileSync('.agent-key'))
80
+ : undefined
81
+
82
+ const wallet = new ClankerWallet({ secretKey })
83
+
84
+ // Save for next time
85
+ if (!secretKey) writeFileSync('.agent-key', wallet.secretKey)
86
+ ```
87
+
88
+ ## Web App
89
+
90
+ The human-facing web app is at [clanker-wallet.vercel.app](https://clanker-wallet.vercel.app). Connect a wallet, scan the QR code from your agent, and approve transactions.
91
+
92
+ ## License
93
+
94
+ MIT
@@ -0,0 +1,31 @@
1
+ import { TypedEmitter } from './events.js';
2
+ import type { PairingData, RequestTxOptions } from './types.js';
3
+ export interface ClankerWalletOptions {
4
+ /** agent display name (informational) */
5
+ agentName?: string;
6
+ /** 32-byte secret key to restore identity. if omitted, generates a new keypair. */
7
+ secretKey?: Uint8Array;
8
+ }
9
+ export declare class ClankerWallet extends TypedEmitter {
10
+ readonly publicKey: Uint8Array;
11
+ readonly secretKey: Uint8Array;
12
+ readonly agentId: string;
13
+ /** Ed25519 public key for signing TxRequests */
14
+ readonly signingPublicKey: Uint8Array;
15
+ private readonly signingSecretKey;
16
+ private humanPubkey;
17
+ private humanPubkeyHex;
18
+ private relayUrl;
19
+ private humanWallet;
20
+ constructor(options?: ClankerWalletOptions);
21
+ /** whether this agent has been paired with a human */
22
+ get paired(): boolean;
23
+ /** parse QR/pairing data and store the human's pubkey + relay url */
24
+ pair(qrData: string): PairingData;
25
+ /**
26
+ * send a transaction request to the paired human and wait for their response.
27
+ * resolves with tx hash on approval.
28
+ * throws on rejection, timeout, or connection error.
29
+ */
30
+ requestTx(options: RequestTxOptions): Promise<string>;
31
+ }
package/dist/client.js ADDED
@@ -0,0 +1,192 @@
1
+ import { encryptMessage, decryptMessage, toHex, fromHex, generateKeypair, keypairFromSecret, signingKeypairFromSeed, signMessage } from './crypto.js';
2
+ import { TypedEmitter } from './events.js';
3
+ const DEFAULT_TIMEOUT_MS = 3_600_000; // 1 hour
4
+ export class ClankerWallet extends TypedEmitter {
5
+ publicKey;
6
+ secretKey;
7
+ agentId;
8
+ /** Ed25519 public key for signing TxRequests */
9
+ signingPublicKey;
10
+ signingSecretKey;
11
+ humanPubkey = null;
12
+ humanPubkeyHex = null;
13
+ relayUrl = null;
14
+ humanWallet = null;
15
+ constructor(options = {}) {
16
+ super();
17
+ const kp = options.secretKey
18
+ ? keypairFromSecret(options.secretKey)
19
+ : generateKeypair();
20
+ this.publicKey = kp.publicKey;
21
+ this.secretKey = kp.secretKey;
22
+ this.agentId = `agent_${toHex(kp.publicKey).slice(0, 12)}`;
23
+ // derive Ed25519 signing keypair from the x25519 secret key (first 32 bytes = seed)
24
+ const signingKp = signingKeypairFromSeed(kp.secretKey);
25
+ this.signingPublicKey = signingKp.publicKey;
26
+ this.signingSecretKey = signingKp.secretKey;
27
+ }
28
+ /** whether this agent has been paired with a human */
29
+ get paired() {
30
+ return this.humanPubkey !== null;
31
+ }
32
+ /** parse QR/pairing data and store the human's pubkey + relay url */
33
+ pair(qrData) {
34
+ const data = JSON.parse(qrData);
35
+ if (data.version !== 1) {
36
+ throw new Error(`unsupported pairing version: ${data.version}`);
37
+ }
38
+ if (!data.pubkey || !data.relay) {
39
+ throw new Error('invalid pairing data: missing pubkey or relay');
40
+ }
41
+ this.humanPubkey = fromHex(data.pubkey);
42
+ this.humanPubkeyHex = data.pubkey;
43
+ this.relayUrl = data.relay;
44
+ this.humanWallet = data.wallet || null;
45
+ this.emit('paired', { relay: data.relay, wallet: data.wallet || '' });
46
+ return data;
47
+ }
48
+ /**
49
+ * send a transaction request to the paired human and wait for their response.
50
+ * resolves with tx hash on approval.
51
+ * throws on rejection, timeout, or connection error.
52
+ */
53
+ async requestTx(options) {
54
+ if (!this.humanPubkey || !this.humanPubkeyHex || !this.relayUrl) {
55
+ throw new Error('not paired — call pair() first');
56
+ }
57
+ const timeoutMs = options.timeout_ms ?? DEFAULT_TIMEOUT_MS;
58
+ const requestId = `req_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
59
+ const txRequest = {
60
+ request_id: requestId,
61
+ agent_id: this.agentId,
62
+ timestamp: new Date().toISOString(),
63
+ chain_id: options.chain_id,
64
+ transaction: options.transaction,
65
+ context: options.context,
66
+ signature: '', // set below after signing
67
+ };
68
+ // sign the request (signature field empty during signing, then filled)
69
+ const sigPayload = JSON.stringify(txRequest);
70
+ txRequest.signature = signMessage(sigPayload, this.signingSecretKey);
71
+ const humanPubkey = this.humanPubkey;
72
+ const humanPubkeyHex = this.humanPubkeyHex;
73
+ const relayUrl = this.relayUrl;
74
+ const secretKey = this.secretKey;
75
+ const agentPubkeyHex = toHex(this.publicKey);
76
+ const signingPubkeyHex = toHex(this.signingPublicKey);
77
+ return new Promise((resolve, reject) => {
78
+ let ws;
79
+ let timer;
80
+ let settled = false;
81
+ const cleanup = () => {
82
+ settled = true;
83
+ clearTimeout(timer);
84
+ if (ws && ws.readyState <= WebSocket.OPEN) {
85
+ ws.close();
86
+ }
87
+ };
88
+ timer = setTimeout(() => {
89
+ if (!settled) {
90
+ cleanup();
91
+ this.emit('error', { message: `request ${requestId} timed out after ${timeoutMs}ms` });
92
+ reject(new Error(`request ${requestId} timed out after ${timeoutMs}ms`));
93
+ }
94
+ }, timeoutMs);
95
+ this.emit('connecting', { relay: relayUrl });
96
+ try {
97
+ ws = new WebSocket(relayUrl);
98
+ }
99
+ catch (err) {
100
+ cleanup();
101
+ this.emit('error', { message: `failed to connect to relay: ${err}` });
102
+ reject(new Error(`failed to connect to relay: ${err}`));
103
+ return;
104
+ }
105
+ ws.addEventListener('error', () => {
106
+ if (!settled) {
107
+ cleanup();
108
+ this.emit('error', { message: 'relay connection error' });
109
+ reject(new Error('relay connection error'));
110
+ }
111
+ });
112
+ ws.addEventListener('close', () => {
113
+ this.emit('disconnected', {});
114
+ if (!settled) {
115
+ cleanup();
116
+ reject(new Error('relay connection closed unexpectedly'));
117
+ }
118
+ });
119
+ ws.addEventListener('open', () => {
120
+ // join the human's room
121
+ ws.send(JSON.stringify({ type: 'join', room: humanPubkeyHex }));
122
+ });
123
+ ws.addEventListener('message', (event) => {
124
+ if (settled)
125
+ return;
126
+ let msg;
127
+ try {
128
+ msg = JSON.parse(event.data);
129
+ }
130
+ catch {
131
+ return; // ignore non-JSON
132
+ }
133
+ if (msg.type === 'joined') {
134
+ this.emit('connected', { room: humanPubkeyHex });
135
+ // room joined — send the encrypted tx request
136
+ const plaintext = JSON.stringify(txRequest);
137
+ const ciphertext = encryptMessage(plaintext, humanPubkey, secretKey);
138
+ const envelope = {
139
+ sender_pubkey: agentPubkeyHex,
140
+ ciphertext,
141
+ signing_pubkey: signingPubkeyHex,
142
+ };
143
+ ws.send(JSON.stringify({
144
+ type: 'message',
145
+ room: humanPubkeyHex,
146
+ payload: JSON.stringify(envelope),
147
+ }));
148
+ this.emit('request_sent', { request_id: requestId });
149
+ return;
150
+ }
151
+ if (msg.type === 'message') {
152
+ // try to decrypt as TxResponse
153
+ try {
154
+ const envelope = JSON.parse(msg.payload);
155
+ const plaintext = decryptMessage(envelope.ciphertext, fromHex(envelope.sender_pubkey), secretKey);
156
+ if (!plaintext)
157
+ return; // not for us or decryption failed
158
+ const response = JSON.parse(plaintext);
159
+ if (response.request_id !== requestId)
160
+ return; // not our response
161
+ this.emit('response', {
162
+ request_id: response.request_id,
163
+ status: response.status,
164
+ tx_hash: response.tx_hash,
165
+ });
166
+ cleanup();
167
+ if (response.status === 'approved' && response.tx_hash) {
168
+ resolve(response.tx_hash);
169
+ }
170
+ else if (response.status === 'rejected') {
171
+ reject(new Error(`request ${requestId} rejected by human`));
172
+ }
173
+ else if (response.error) {
174
+ reject(new Error(`request ${requestId} failed: ${response.error}`));
175
+ }
176
+ else {
177
+ reject(new Error(`request ${requestId}: unexpected response status "${response.status}"`));
178
+ }
179
+ }
180
+ catch {
181
+ // ignore messages that aren't valid envelopes
182
+ }
183
+ }
184
+ if (msg.type === 'error') {
185
+ cleanup();
186
+ this.emit('error', { message: `relay error: ${msg.message}` });
187
+ reject(new Error(`relay error: ${msg.message}`));
188
+ }
189
+ });
190
+ });
191
+ }
192
+ }
@@ -0,0 +1,20 @@
1
+ import nacl from 'tweetnacl';
2
+ /** generate a random x25519 keypair for the agent's identity */
3
+ export declare function generateKeypair(): nacl.BoxKeyPair;
4
+ /** restore keypair from a 32-byte secret key */
5
+ export declare function keypairFromSecret(secretKey: Uint8Array): nacl.BoxKeyPair;
6
+ /** encrypt a message using nacl.box. returns base64(nonce + ciphertext). */
7
+ export declare function encryptMessage(message: string, recipientPublicKey: Uint8Array, senderSecretKey: Uint8Array): string;
8
+ /** decrypt a nacl.box message. payload = base64(nonce + ciphertext). */
9
+ export declare function decryptMessage(base64Payload: string, senderPublicKey: Uint8Array, recipientSecretKey: Uint8Array): string | null;
10
+ /** hex-encode bytes (no 0x prefix) */
11
+ export declare function toHex(bytes: Uint8Array): string;
12
+ /** hex string → Uint8Array (strips 0x prefix if present) */
13
+ export declare function fromHex(hex: string): Uint8Array;
14
+ /** derive an Ed25519 signing keypair from a 32-byte seed */
15
+ export declare function signingKeypairFromSeed(seed: Uint8Array): nacl.SignKeyPair;
16
+ /** sign a message string with an Ed25519 secret key. returns base64(signature). */
17
+ export declare function signMessage(message: string, signingSecretKey: Uint8Array): string;
18
+ /** verify a detached Ed25519 signature. signature is base64-encoded. */
19
+ export declare function verifySignature(message: string, base64Signature: string, signingPublicKey: Uint8Array): boolean;
20
+ export declare function bytesToBase64(bytes: Uint8Array): string;
package/dist/crypto.js ADDED
@@ -0,0 +1,77 @@
1
+ import nacl from 'tweetnacl';
2
+ /** generate a random x25519 keypair for the agent's identity */
3
+ export function generateKeypair() {
4
+ return nacl.box.keyPair();
5
+ }
6
+ /** restore keypair from a 32-byte secret key */
7
+ export function keypairFromSecret(secretKey) {
8
+ return nacl.box.keyPair.fromSecretKey(secretKey);
9
+ }
10
+ /** encrypt a message using nacl.box. returns base64(nonce + ciphertext). */
11
+ export function encryptMessage(message, recipientPublicKey, senderSecretKey) {
12
+ const nonce = nacl.randomBytes(nacl.box.nonceLength);
13
+ const encoded = new TextEncoder().encode(message);
14
+ const ciphertext = nacl.box(encoded, nonce, recipientPublicKey, senderSecretKey);
15
+ const combined = new Uint8Array(nonce.length + ciphertext.length);
16
+ combined.set(nonce);
17
+ combined.set(ciphertext, nonce.length);
18
+ return bytesToBase64(combined);
19
+ }
20
+ /** decrypt a nacl.box message. payload = base64(nonce + ciphertext). */
21
+ export function decryptMessage(base64Payload, senderPublicKey, recipientSecretKey) {
22
+ const raw = base64ToBytes(base64Payload);
23
+ if (raw.length <= nacl.box.nonceLength)
24
+ return null;
25
+ const nonce = raw.slice(0, nacl.box.nonceLength);
26
+ const ciphertext = raw.slice(nacl.box.nonceLength);
27
+ const plaintext = nacl.box.open(ciphertext, nonce, senderPublicKey, recipientSecretKey);
28
+ if (!plaintext)
29
+ return null;
30
+ return new TextDecoder().decode(plaintext);
31
+ }
32
+ /** hex-encode bytes (no 0x prefix) */
33
+ export function toHex(bytes) {
34
+ return Array.from(bytes)
35
+ .map((b) => b.toString(16).padStart(2, '0'))
36
+ .join('');
37
+ }
38
+ /** hex string → Uint8Array (strips 0x prefix if present) */
39
+ export function fromHex(hex) {
40
+ const clean = hex.startsWith('0x') ? hex.slice(2) : hex;
41
+ const bytes = new Uint8Array(clean.length / 2);
42
+ for (let i = 0; i < bytes.length; i++) {
43
+ bytes[i] = parseInt(clean.slice(i * 2, i * 2 + 2), 16);
44
+ }
45
+ return bytes;
46
+ }
47
+ /** derive an Ed25519 signing keypair from a 32-byte seed */
48
+ export function signingKeypairFromSeed(seed) {
49
+ return nacl.sign.keyPair.fromSeed(seed);
50
+ }
51
+ /** sign a message string with an Ed25519 secret key. returns base64(signature). */
52
+ export function signMessage(message, signingSecretKey) {
53
+ const encoded = new TextEncoder().encode(message);
54
+ const signature = nacl.sign.detached(encoded, signingSecretKey);
55
+ return bytesToBase64(signature);
56
+ }
57
+ /** verify a detached Ed25519 signature. signature is base64-encoded. */
58
+ export function verifySignature(message, base64Signature, signingPublicKey) {
59
+ const encoded = new TextEncoder().encode(message);
60
+ const signature = base64ToBytes(base64Signature);
61
+ return nacl.sign.detached.verify(encoded, signature, signingPublicKey);
62
+ }
63
+ function base64ToBytes(b64) {
64
+ const binary = atob(b64);
65
+ const bytes = new Uint8Array(binary.length);
66
+ for (let i = 0; i < binary.length; i++) {
67
+ bytes[i] = binary.charCodeAt(i);
68
+ }
69
+ return bytes;
70
+ }
71
+ export function bytesToBase64(bytes) {
72
+ let binary = '';
73
+ for (let i = 0; i < bytes.length; i++) {
74
+ binary += String.fromCharCode(bytes[i]);
75
+ }
76
+ return btoa(binary);
77
+ }
@@ -0,0 +1,32 @@
1
+ export type EventMap = {
2
+ paired: {
3
+ relay: string;
4
+ wallet: string;
5
+ };
6
+ connecting: {
7
+ relay: string;
8
+ };
9
+ connected: {
10
+ room: string;
11
+ };
12
+ request_sent: {
13
+ request_id: string;
14
+ };
15
+ response: {
16
+ request_id: string;
17
+ status: 'approved' | 'rejected';
18
+ tx_hash?: string;
19
+ };
20
+ error: {
21
+ message: string;
22
+ };
23
+ disconnected: {};
24
+ };
25
+ type Handler<T> = (data: T) => void;
26
+ export declare class TypedEmitter {
27
+ private _listeners;
28
+ on<K extends keyof EventMap>(event: K, handler: Handler<EventMap[K]>): this;
29
+ off<K extends keyof EventMap>(event: K, handler: Handler<EventMap[K]>): this;
30
+ protected emit<K extends keyof EventMap>(event: K, data: EventMap[K]): void;
31
+ }
32
+ export {};
package/dist/events.js ADDED
@@ -0,0 +1,19 @@
1
+ export class TypedEmitter {
2
+ _listeners = new Map();
3
+ on(event, handler) {
4
+ let set = this._listeners.get(event);
5
+ if (!set) {
6
+ set = new Set();
7
+ this._listeners.set(event, set);
8
+ }
9
+ set.add(handler);
10
+ return this;
11
+ }
12
+ off(event, handler) {
13
+ this._listeners.get(event)?.delete(handler);
14
+ return this;
15
+ }
16
+ emit(event, data) {
17
+ this._listeners.get(event)?.forEach((h) => h(data));
18
+ }
19
+ }
@@ -0,0 +1,6 @@
1
+ export { ClankerWallet } from './client.js';
2
+ export type { ClankerWalletOptions } from './client.js';
3
+ export { TypedEmitter } from './events.js';
4
+ export type { EventMap } from './events.js';
5
+ export { generateKeypair, keypairFromSecret, encryptMessage, decryptMessage, toHex, fromHex, signingKeypairFromSeed, signMessage, verifySignature, bytesToBase64 } from './crypto.js';
6
+ export type { Transaction, TxContext, TxRequest, TxResponse, AgentEnvelope, PairingData, RequestTxOptions, } from './types.js';
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export { ClankerWallet } from './client.js';
2
+ export { TypedEmitter } from './events.js';
3
+ export { generateKeypair, keypairFromSecret, encryptMessage, decryptMessage, toHex, fromHex, signingKeypairFromSeed, signMessage, verifySignature, bytesToBase64 } from './crypto.js';
@@ -0,0 +1,51 @@
1
+ /** transaction to send */
2
+ export interface Transaction {
3
+ to: string;
4
+ value: string;
5
+ data: string;
6
+ }
7
+ /** optional context about the transaction */
8
+ export interface TxContext {
9
+ reason?: string;
10
+ urgency?: string;
11
+ expected_outcome?: string;
12
+ }
13
+ /** full tx request sent to the human (matches web app TxRequest) */
14
+ export interface TxRequest {
15
+ request_id: string;
16
+ agent_id: string;
17
+ timestamp: string;
18
+ chain_id: number;
19
+ transaction: Transaction;
20
+ context?: TxContext;
21
+ signature: string;
22
+ }
23
+ /** response from the human (decrypted) */
24
+ export interface TxResponse {
25
+ request_id: string;
26
+ status: 'approved' | 'rejected';
27
+ tx_hash?: string;
28
+ error?: string;
29
+ }
30
+ /** wire format sent over relay */
31
+ export interface AgentEnvelope {
32
+ sender_pubkey: string;
33
+ ciphertext: string;
34
+ /** Ed25519 public key (hex) for verifying TxRequest signatures */
35
+ signing_pubkey?: string;
36
+ }
37
+ /** pairing data from QR code */
38
+ export interface PairingData {
39
+ version: number;
40
+ pubkey: string;
41
+ relay: string;
42
+ wallet: string;
43
+ }
44
+ /** options for requestTx */
45
+ export interface RequestTxOptions {
46
+ chain_id: number;
47
+ transaction: Transaction;
48
+ context?: TxContext;
49
+ /** timeout in ms (default: 3_600_000 = 1hr) */
50
+ timeout_ms?: number;
51
+ }
package/dist/types.js ADDED
@@ -0,0 +1 @@
1
+ export {};
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "clanker-wallet",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "import": "./dist/index.js",
10
+ "types": "./dist/index.d.ts"
11
+ }
12
+ },
13
+ "files": ["dist", "README.md", "LICENSE"],
14
+ "license": "MIT",
15
+ "author": "Clanker Wallet Contributors",
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git+https://github.com/almogdepaz/ClankerWallet.git",
19
+ "directory": "sdk"
20
+ },
21
+ "homepage": "https://github.com/almogdepaz/ClankerWallet/tree/main/sdk#readme",
22
+ "keywords": ["wallet", "ai-agent", "ethereum", "e2e-encrypted", "transaction-approval"],
23
+ "scripts": {
24
+ "build": "tsc -p tsconfig.build.json",
25
+ "dev": "tsc --watch",
26
+ "test": "vitest run",
27
+ "typecheck": "tsc --noEmit",
28
+ "prepublishOnly": "npm run build"
29
+ },
30
+ "dependencies": {
31
+ "tweetnacl": "^1.0.3"
32
+ },
33
+ "devDependencies": {
34
+ "@types/bun": "^1.3.8",
35
+ "typescript": "^5.4.0",
36
+ "vitest": "^2.1.0"
37
+ }
38
+ }