@deadvault/sdk 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +197 -0
- package/dist/index.cjs +520 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +210 -0
- package/dist/index.d.ts +210 -0
- package/dist/index.js +507 -0
- package/dist/index.js.map +1 -0
- package/package.json +69 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,507 @@
|
|
|
1
|
+
import { privateKeyToAccount } from 'viem/accounts';
|
|
2
|
+
import { optimism, arbitrum, mainnet, base } from 'viem/chains';
|
|
3
|
+
import { http, createPublicClient, createWalletClient, encodeFunctionData } from 'viem';
|
|
4
|
+
|
|
5
|
+
// src/client.ts
|
|
6
|
+
var VAULT_ADDRESSES = {
|
|
7
|
+
8453: "0xF74C1131E11aF8dc10F25bAa977dD0B86d4A5C37",
|
|
8
|
+
// Base
|
|
9
|
+
1: "0xF74C1131E11aF8dc10F25bAa977dD0B86d4A5C37",
|
|
10
|
+
// Ethereum
|
|
11
|
+
42161: "0x33939ede1A19A64EE755F1B5B3284A8E71F68484",
|
|
12
|
+
// Arbitrum One
|
|
13
|
+
10: "0x33939ede1A19A64EE755F1B5B3284A8E71F68484"
|
|
14
|
+
// Optimism
|
|
15
|
+
};
|
|
16
|
+
var RPC_URLS = {
|
|
17
|
+
8453: "https://mainnet.base.org",
|
|
18
|
+
1: "https://ethereum-rpc.publicnode.com",
|
|
19
|
+
42161: "https://arbitrum-one-rpc.publicnode.com",
|
|
20
|
+
10: "https://optimism-rpc.publicnode.com"
|
|
21
|
+
};
|
|
22
|
+
var CHAIN_NAME_TO_ID = {
|
|
23
|
+
"base": 8453,
|
|
24
|
+
"ethereum": 1,
|
|
25
|
+
"arbitrum": 42161,
|
|
26
|
+
"optimism": 10
|
|
27
|
+
};
|
|
28
|
+
var CHAINS = {
|
|
29
|
+
8453: base,
|
|
30
|
+
1: mainnet,
|
|
31
|
+
42161: arbitrum,
|
|
32
|
+
10: optimism
|
|
33
|
+
};
|
|
34
|
+
var DEAD_VAULT_ABI = [
|
|
35
|
+
{
|
|
36
|
+
type: "function",
|
|
37
|
+
name: "deleteSecret",
|
|
38
|
+
inputs: [],
|
|
39
|
+
outputs: [],
|
|
40
|
+
stateMutability: "nonpayable"
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
type: "function",
|
|
44
|
+
name: "getNativeWriteFee",
|
|
45
|
+
inputs: [],
|
|
46
|
+
outputs: [{ name: "", type: "uint256", internalType: "uint256" }],
|
|
47
|
+
stateMutability: "view"
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
type: "function",
|
|
51
|
+
name: "getSecret",
|
|
52
|
+
inputs: [{ name: "agent", type: "address", internalType: "address" }],
|
|
53
|
+
outputs: [{ name: "", type: "bytes", internalType: "bytes" }],
|
|
54
|
+
stateMutability: "view"
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
type: "function",
|
|
58
|
+
name: "hasSecret",
|
|
59
|
+
inputs: [{ name: "agent", type: "address", internalType: "address" }],
|
|
60
|
+
outputs: [{ name: "", type: "bool", internalType: "bool" }],
|
|
61
|
+
stateMutability: "view"
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
type: "function",
|
|
65
|
+
name: "hasUnlimitedPass",
|
|
66
|
+
inputs: [{ name: "agent", type: "address", internalType: "address" }],
|
|
67
|
+
outputs: [{ name: "", type: "bool", internalType: "bool" }],
|
|
68
|
+
stateMutability: "view"
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
type: "function",
|
|
72
|
+
name: "storeSecret",
|
|
73
|
+
inputs: [{ name: "payload", type: "bytes", internalType: "bytes" }],
|
|
74
|
+
outputs: [],
|
|
75
|
+
stateMutability: "payable"
|
|
76
|
+
}
|
|
77
|
+
];
|
|
78
|
+
function makePublicClient(chainId, rpcUrl) {
|
|
79
|
+
const chain = CHAINS[chainId];
|
|
80
|
+
if (!chain) throw new Error(`Unsupported chain ID: ${chainId}`);
|
|
81
|
+
const transport = http(rpcUrl || RPC_URLS[chainId]);
|
|
82
|
+
return createPublicClient({ chain, transport });
|
|
83
|
+
}
|
|
84
|
+
async function readVaultFromChain(client, vaultAddress, userAddress) {
|
|
85
|
+
const addr = userAddress;
|
|
86
|
+
const [hasSecret, rawBytes] = await Promise.all([
|
|
87
|
+
client.readContract({
|
|
88
|
+
address: vaultAddress,
|
|
89
|
+
abi: DEAD_VAULT_ABI,
|
|
90
|
+
functionName: "hasSecret",
|
|
91
|
+
args: [addr]
|
|
92
|
+
}),
|
|
93
|
+
client.readContract({
|
|
94
|
+
address: vaultAddress,
|
|
95
|
+
abi: DEAD_VAULT_ABI,
|
|
96
|
+
functionName: "getSecret",
|
|
97
|
+
args: [addr]
|
|
98
|
+
})
|
|
99
|
+
]);
|
|
100
|
+
let ciphertext = null;
|
|
101
|
+
if (hasSecret && rawBytes) {
|
|
102
|
+
ciphertext = typeof rawBytes === "string" ? rawBytes : "0x" + Array.from(rawBytes).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
103
|
+
}
|
|
104
|
+
return { hasSecret, ciphertext };
|
|
105
|
+
}
|
|
106
|
+
async function readNativeFee(client, vaultAddress) {
|
|
107
|
+
return await client.readContract({
|
|
108
|
+
address: vaultAddress,
|
|
109
|
+
abi: DEAD_VAULT_ABI,
|
|
110
|
+
functionName: "getNativeWriteFee"
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
async function checkUnlimitedPass(client, vaultAddress, userAddress) {
|
|
114
|
+
return await client.readContract({
|
|
115
|
+
address: vaultAddress,
|
|
116
|
+
abi: DEAD_VAULT_ABI,
|
|
117
|
+
functionName: "hasUnlimitedPass",
|
|
118
|
+
args: [userAddress]
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
async function hasVault(client, vaultAddress, userAddress) {
|
|
122
|
+
return await client.readContract({
|
|
123
|
+
address: vaultAddress,
|
|
124
|
+
abi: DEAD_VAULT_ABI,
|
|
125
|
+
functionName: "hasSecret",
|
|
126
|
+
args: [userAddress]
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
async function writeVaultToChain(chainId, vaultAddress, privateKey, payload, value, rpcUrl) {
|
|
130
|
+
const chain = CHAINS[chainId];
|
|
131
|
+
if (!chain) throw new Error(`Unsupported chain ID: ${chainId}`);
|
|
132
|
+
const hex = privateKey.startsWith("0x") ? privateKey : `0x${privateKey}`;
|
|
133
|
+
const account = privateKeyToAccount(hex);
|
|
134
|
+
const walletClient = createWalletClient({
|
|
135
|
+
account,
|
|
136
|
+
chain,
|
|
137
|
+
transport: http(rpcUrl || RPC_URLS[chainId])
|
|
138
|
+
});
|
|
139
|
+
const calldata = encodeFunctionData({
|
|
140
|
+
abi: DEAD_VAULT_ABI,
|
|
141
|
+
functionName: "storeSecret",
|
|
142
|
+
args: [payload]
|
|
143
|
+
});
|
|
144
|
+
const hash = await walletClient.sendTransaction({
|
|
145
|
+
account,
|
|
146
|
+
chain,
|
|
147
|
+
to: vaultAddress,
|
|
148
|
+
data: calldata,
|
|
149
|
+
value
|
|
150
|
+
});
|
|
151
|
+
const publicClient = makePublicClient(chainId, rpcUrl);
|
|
152
|
+
const receipt = await publicClient.waitForTransactionReceipt({ hash });
|
|
153
|
+
return { hash, blockNumber: receipt.blockNumber };
|
|
154
|
+
}
|
|
155
|
+
function getVaultAddress(chainId) {
|
|
156
|
+
const addr = VAULT_ADDRESSES[chainId];
|
|
157
|
+
if (!addr) throw new Error(`No DeadVault contract on chain ${chainId}`);
|
|
158
|
+
return addr;
|
|
159
|
+
}
|
|
160
|
+
async function signMessage(privateKey, message) {
|
|
161
|
+
const hex = privateKey.startsWith("0x") ? privateKey : `0x${privateKey}`;
|
|
162
|
+
const account = privateKeyToAccount(hex);
|
|
163
|
+
return account.signMessage({ message });
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// src/crypto.ts
|
|
167
|
+
var PBKDF2_ITERATIONS = 6e5;
|
|
168
|
+
var MAGIC = new Uint8Array([222, 173, 0]);
|
|
169
|
+
var VERSION_V2 = 2;
|
|
170
|
+
var HEADER_V2 = new Uint8Array([...MAGIC, VERSION_V2]);
|
|
171
|
+
var KDF_SIGN_MESSAGE = "DeadVault Encryption Key Derivation\n\nSign this message to derive your personal encryption key.\nThis signature is used locally and does NOT authorize any transaction or transfer.";
|
|
172
|
+
function detectVersion(packed) {
|
|
173
|
+
if (packed.length >= 4 && packed[0] === 222 && packed[1] === 173 && packed[2] === 0) {
|
|
174
|
+
return { version: packed[3], offset: 4 };
|
|
175
|
+
}
|
|
176
|
+
return { version: 1, offset: 0 };
|
|
177
|
+
}
|
|
178
|
+
function detectVersionFromHex(hexCiphertext) {
|
|
179
|
+
const hex = hexCiphertext.startsWith("0x") ? hexCiphertext.slice(2) : hexCiphertext;
|
|
180
|
+
if (hex.length >= 8 && hex.slice(0, 6).toLowerCase() === "dead00") {
|
|
181
|
+
return parseInt(hex.slice(6, 8), 16);
|
|
182
|
+
}
|
|
183
|
+
return 1;
|
|
184
|
+
}
|
|
185
|
+
function toHex(bytes) {
|
|
186
|
+
return "0x" + Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
187
|
+
}
|
|
188
|
+
function fromHex(hex) {
|
|
189
|
+
const clean = hex.startsWith("0x") ? hex.slice(2) : hex;
|
|
190
|
+
if (clean.length === 0) throw new Error("Cannot decode empty hex string");
|
|
191
|
+
const pairs = clean.match(/.{1,2}/g);
|
|
192
|
+
if (!pairs) throw new Error("Invalid hex string");
|
|
193
|
+
return new Uint8Array(pairs.map((byte) => parseInt(byte, 16)));
|
|
194
|
+
}
|
|
195
|
+
async function deriveKeyV1(password, salt) {
|
|
196
|
+
const enc = new TextEncoder();
|
|
197
|
+
const keyMaterial = await crypto.subtle.importKey("raw", enc.encode(password), "PBKDF2", false, ["deriveKey"]);
|
|
198
|
+
return crypto.subtle.deriveKey(
|
|
199
|
+
{ name: "PBKDF2", salt: salt.buffer.slice(salt.byteOffset, salt.byteOffset + salt.byteLength), iterations: PBKDF2_ITERATIONS, hash: "SHA-256" },
|
|
200
|
+
keyMaterial,
|
|
201
|
+
{ name: "AES-GCM", length: 256 },
|
|
202
|
+
false,
|
|
203
|
+
["encrypt", "decrypt"]
|
|
204
|
+
);
|
|
205
|
+
}
|
|
206
|
+
async function deriveKeyV2(password, walletSignature, salt) {
|
|
207
|
+
const enc = new TextEncoder();
|
|
208
|
+
const combined = enc.encode(password + walletSignature);
|
|
209
|
+
const keyMaterial = await crypto.subtle.importKey("raw", combined, "PBKDF2", false, ["deriveKey"]);
|
|
210
|
+
return crypto.subtle.deriveKey(
|
|
211
|
+
{ name: "PBKDF2", salt: salt.buffer.slice(salt.byteOffset, salt.byteOffset + salt.byteLength), iterations: PBKDF2_ITERATIONS, hash: "SHA-256" },
|
|
212
|
+
keyMaterial,
|
|
213
|
+
{ name: "AES-GCM", length: 256 },
|
|
214
|
+
false,
|
|
215
|
+
["encrypt", "decrypt"]
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
async function encrypt(plaintext, password) {
|
|
219
|
+
const enc = new TextEncoder();
|
|
220
|
+
const salt = crypto.getRandomValues(new Uint8Array(16));
|
|
221
|
+
const iv = crypto.getRandomValues(new Uint8Array(12));
|
|
222
|
+
const key = await deriveKeyV1(password, salt);
|
|
223
|
+
const ct = new Uint8Array(await crypto.subtle.encrypt({ name: "AES-GCM", iv }, key, enc.encode(plaintext)));
|
|
224
|
+
const packed = new Uint8Array(salt.length + iv.length + ct.length);
|
|
225
|
+
packed.set(salt, 0);
|
|
226
|
+
packed.set(iv, salt.length);
|
|
227
|
+
packed.set(ct, salt.length + iv.length);
|
|
228
|
+
return toHex(packed);
|
|
229
|
+
}
|
|
230
|
+
async function encryptV2(plaintext, password, walletSignature) {
|
|
231
|
+
const enc = new TextEncoder();
|
|
232
|
+
const salt = crypto.getRandomValues(new Uint8Array(16));
|
|
233
|
+
const iv = crypto.getRandomValues(new Uint8Array(12));
|
|
234
|
+
const key = await deriveKeyV2(password, walletSignature, salt);
|
|
235
|
+
const ct = new Uint8Array(await crypto.subtle.encrypt({ name: "AES-GCM", iv }, key, enc.encode(plaintext)));
|
|
236
|
+
const packed = new Uint8Array(HEADER_V2.length + salt.length + iv.length + ct.length);
|
|
237
|
+
packed.set(HEADER_V2, 0);
|
|
238
|
+
packed.set(salt, HEADER_V2.length);
|
|
239
|
+
packed.set(iv, HEADER_V2.length + salt.length);
|
|
240
|
+
packed.set(ct, HEADER_V2.length + salt.length + iv.length);
|
|
241
|
+
return toHex(packed);
|
|
242
|
+
}
|
|
243
|
+
async function decrypt(hexCiphertext, password, walletSignature) {
|
|
244
|
+
const packed = fromHex(hexCiphertext);
|
|
245
|
+
const { version, offset } = detectVersion(packed);
|
|
246
|
+
const salt = packed.slice(offset, offset + 16);
|
|
247
|
+
const iv = packed.slice(offset + 16, offset + 28);
|
|
248
|
+
const ciphertext = packed.slice(offset + 28);
|
|
249
|
+
let key;
|
|
250
|
+
if (version === 1) {
|
|
251
|
+
key = await deriveKeyV1(password, salt);
|
|
252
|
+
} else if (version === 2) {
|
|
253
|
+
if (!walletSignature) throw new Error("Wallet signature required for v2 decryption.");
|
|
254
|
+
key = await deriveKeyV2(password, walletSignature, salt);
|
|
255
|
+
} else {
|
|
256
|
+
throw new Error(`Unknown encryption version: ${version}`);
|
|
257
|
+
}
|
|
258
|
+
const plainBuffer = await crypto.subtle.decrypt({ name: "AES-GCM", iv }, key, ciphertext);
|
|
259
|
+
return new TextDecoder().decode(plainBuffer);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// src/totp.ts
|
|
263
|
+
var BASE32_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
|
|
264
|
+
function base32Decode(input) {
|
|
265
|
+
const cleaned = input.replace(/[\s=-]/g, "").toUpperCase();
|
|
266
|
+
const out = [];
|
|
267
|
+
let bits = 0;
|
|
268
|
+
let value = 0;
|
|
269
|
+
for (const char of cleaned) {
|
|
270
|
+
const idx = BASE32_CHARS.indexOf(char);
|
|
271
|
+
if (idx === -1) continue;
|
|
272
|
+
value = value << 5 | idx;
|
|
273
|
+
bits += 5;
|
|
274
|
+
if (bits >= 8) {
|
|
275
|
+
bits -= 8;
|
|
276
|
+
out.push(value >>> bits & 255);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
return new Uint8Array(out);
|
|
280
|
+
}
|
|
281
|
+
async function generateTOTP(params) {
|
|
282
|
+
const { secret, algorithm = "SHA1", digits = 6, period = 30 } = params;
|
|
283
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
284
|
+
const counter = Math.floor(now / period);
|
|
285
|
+
return generateHOTP(secret, counter, algorithm, digits);
|
|
286
|
+
}
|
|
287
|
+
function getTOTPTimeRemaining(period = 30) {
|
|
288
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
289
|
+
return period - now % period;
|
|
290
|
+
}
|
|
291
|
+
async function generateHOTP(base32Secret, counter, algorithm, digits) {
|
|
292
|
+
const key = base32Decode(base32Secret);
|
|
293
|
+
const counterBuf = new ArrayBuffer(8);
|
|
294
|
+
const view = new DataView(counterBuf);
|
|
295
|
+
view.setUint32(4, counter, false);
|
|
296
|
+
const algo = algorithm === "SHA256" ? "SHA-256" : "SHA-1";
|
|
297
|
+
const cryptoKey = await crypto.subtle.importKey(
|
|
298
|
+
"raw",
|
|
299
|
+
key.buffer,
|
|
300
|
+
{ name: "HMAC", hash: algo },
|
|
301
|
+
false,
|
|
302
|
+
["sign"]
|
|
303
|
+
);
|
|
304
|
+
const hmac = await crypto.subtle.sign("HMAC", cryptoKey, counterBuf);
|
|
305
|
+
const hmacBytes = new Uint8Array(hmac);
|
|
306
|
+
const offset = hmacBytes[hmacBytes.length - 1] & 15;
|
|
307
|
+
const code = (hmacBytes[offset] & 127) << 24 | (hmacBytes[offset + 1] & 255) << 16 | (hmacBytes[offset + 2] & 255) << 8 | hmacBytes[offset + 3] & 255;
|
|
308
|
+
const otp = code % 10 ** digits;
|
|
309
|
+
return otp.toString().padStart(digits, "0");
|
|
310
|
+
}
|
|
311
|
+
function isValidTOTPSecret(secret) {
|
|
312
|
+
try {
|
|
313
|
+
const decoded = base32Decode(secret);
|
|
314
|
+
return decoded.length >= 10;
|
|
315
|
+
} catch {
|
|
316
|
+
return false;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// src/client.ts
|
|
321
|
+
var VAULT_DATA_VERSION = 1;
|
|
322
|
+
function parseVault(plaintext) {
|
|
323
|
+
try {
|
|
324
|
+
const parsed = JSON.parse(plaintext);
|
|
325
|
+
if (parsed && typeof parsed === "object" && Array.isArray(parsed.entries)) {
|
|
326
|
+
return parsed;
|
|
327
|
+
}
|
|
328
|
+
return wrapLegacy(plaintext);
|
|
329
|
+
} catch {
|
|
330
|
+
return wrapLegacy(plaintext);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
function wrapLegacy(plaintext) {
|
|
334
|
+
return {
|
|
335
|
+
version: VAULT_DATA_VERSION,
|
|
336
|
+
entries: [
|
|
337
|
+
{
|
|
338
|
+
id: crypto.randomUUID(),
|
|
339
|
+
label: "Legacy Secret",
|
|
340
|
+
secret: plaintext,
|
|
341
|
+
category: "Imported",
|
|
342
|
+
createdAt: Date.now(),
|
|
343
|
+
updatedAt: Date.now()
|
|
344
|
+
}
|
|
345
|
+
]
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
function serializeVault(data) {
|
|
349
|
+
return JSON.stringify(data);
|
|
350
|
+
}
|
|
351
|
+
var DeadVault = class {
|
|
352
|
+
chainId;
|
|
353
|
+
rpcUrl;
|
|
354
|
+
vaultAddress;
|
|
355
|
+
client;
|
|
356
|
+
constructor(config = {}) {
|
|
357
|
+
if (config.chainId) {
|
|
358
|
+
this.chainId = config.chainId;
|
|
359
|
+
} else if (config.chain) {
|
|
360
|
+
const id = CHAIN_NAME_TO_ID[config.chain];
|
|
361
|
+
if (!id) throw new Error(`Unknown chain: "${config.chain}". Use: base, ethereum, arbitrum, optimism`);
|
|
362
|
+
this.chainId = id;
|
|
363
|
+
} else {
|
|
364
|
+
this.chainId = 8453;
|
|
365
|
+
}
|
|
366
|
+
this.rpcUrl = config.rpcUrl;
|
|
367
|
+
this.vaultAddress = getVaultAddress(this.chainId);
|
|
368
|
+
this.client = makePublicClient(this.chainId, this.rpcUrl);
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* Read and decrypt a vault from the chain.
|
|
372
|
+
* Returns the decrypted VaultData with all entries.
|
|
373
|
+
*/
|
|
374
|
+
async read(options) {
|
|
375
|
+
const { address, password, walletSignature } = options;
|
|
376
|
+
const { hasSecret, ciphertext } = await readVaultFromChain(
|
|
377
|
+
this.client,
|
|
378
|
+
this.vaultAddress,
|
|
379
|
+
address
|
|
380
|
+
);
|
|
381
|
+
if (!hasSecret || !ciphertext) {
|
|
382
|
+
return { version: VAULT_DATA_VERSION, entries: [] };
|
|
383
|
+
}
|
|
384
|
+
const version = detectVersionFromHex(ciphertext);
|
|
385
|
+
if (version >= 2 && !walletSignature) {
|
|
386
|
+
throw new Error("This vault uses v2 encryption. Provide walletSignature for decryption.");
|
|
387
|
+
}
|
|
388
|
+
const plaintext = await decrypt(ciphertext, password, walletSignature);
|
|
389
|
+
return parseVault(plaintext);
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Encrypt and write vault data on-chain.
|
|
393
|
+
* Requires a private key for the transaction + wallet signature for v2 encryption.
|
|
394
|
+
*/
|
|
395
|
+
async write(options) {
|
|
396
|
+
const { data, password, privateKey, walletSignature } = options;
|
|
397
|
+
const plaintext = serializeVault(data);
|
|
398
|
+
const ciphertext = await encryptV2(plaintext, password, walletSignature);
|
|
399
|
+
const payload = ciphertext;
|
|
400
|
+
const hex = privateKey.startsWith("0x") ? privateKey : `0x${privateKey}`;
|
|
401
|
+
const account = privateKeyToAccount(hex);
|
|
402
|
+
const hasPass = await checkUnlimitedPass(
|
|
403
|
+
this.client,
|
|
404
|
+
this.vaultAddress,
|
|
405
|
+
account.address
|
|
406
|
+
);
|
|
407
|
+
let fee = 0n;
|
|
408
|
+
if (!hasPass) {
|
|
409
|
+
fee = await readNativeFee(this.client, this.vaultAddress);
|
|
410
|
+
}
|
|
411
|
+
return writeVaultToChain(
|
|
412
|
+
this.chainId,
|
|
413
|
+
this.vaultAddress,
|
|
414
|
+
privateKey,
|
|
415
|
+
payload,
|
|
416
|
+
fee,
|
|
417
|
+
this.rpcUrl
|
|
418
|
+
);
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* Find an entry in vault data by label, category, URL, or custom predicate.
|
|
422
|
+
*/
|
|
423
|
+
findEntry(data, match) {
|
|
424
|
+
if (typeof match === "function") {
|
|
425
|
+
return data.entries.find(match);
|
|
426
|
+
}
|
|
427
|
+
return data.entries.find((e) => {
|
|
428
|
+
if (match.label && !e.label.toLowerCase().includes(match.label.toLowerCase())) return false;
|
|
429
|
+
if (match.category && e.category?.toLowerCase() !== match.category.toLowerCase()) return false;
|
|
430
|
+
if (match.url && !e.url?.toLowerCase().includes(match.url.toLowerCase())) return false;
|
|
431
|
+
return true;
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* Find all matching entries.
|
|
436
|
+
*/
|
|
437
|
+
findEntries(data, match) {
|
|
438
|
+
if (typeof match === "function") {
|
|
439
|
+
return data.entries.filter(match);
|
|
440
|
+
}
|
|
441
|
+
return data.entries.filter((e) => {
|
|
442
|
+
if (match.label && !e.label.toLowerCase().includes(match.label.toLowerCase())) return false;
|
|
443
|
+
if (match.category && e.category?.toLowerCase() !== match.category.toLowerCase()) return false;
|
|
444
|
+
if (match.url && !e.url?.toLowerCase().includes(match.url.toLowerCase())) return false;
|
|
445
|
+
if (match.type && (e.type || "password") !== match.type) return false;
|
|
446
|
+
return true;
|
|
447
|
+
});
|
|
448
|
+
}
|
|
449
|
+
/**
|
|
450
|
+
* Generate a TOTP code from a vault entry.
|
|
451
|
+
* The entry must have type "totp" and contain a base32 secret.
|
|
452
|
+
*/
|
|
453
|
+
async generateTOTP(entry) {
|
|
454
|
+
const params = {
|
|
455
|
+
secret: entry.secret,
|
|
456
|
+
algorithm: entry.totpConfig?.algorithm,
|
|
457
|
+
digits: entry.totpConfig?.digits,
|
|
458
|
+
period: entry.totpConfig?.period
|
|
459
|
+
};
|
|
460
|
+
return generateTOTP(params);
|
|
461
|
+
}
|
|
462
|
+
/**
|
|
463
|
+
* Get the remaining seconds in the current TOTP window.
|
|
464
|
+
*/
|
|
465
|
+
getTOTPTimeRemaining(period = 30) {
|
|
466
|
+
return getTOTPTimeRemaining(period);
|
|
467
|
+
}
|
|
468
|
+
/**
|
|
469
|
+
* Get the write fee for this chain.
|
|
470
|
+
*/
|
|
471
|
+
async getWriteFee() {
|
|
472
|
+
const wei = await readNativeFee(this.client, this.vaultAddress);
|
|
473
|
+
const eth = (Number(wei) / 1e18).toFixed(8);
|
|
474
|
+
return { wei, eth };
|
|
475
|
+
}
|
|
476
|
+
/**
|
|
477
|
+
* Check if an address has an unlimited pass (no fee required).
|
|
478
|
+
*/
|
|
479
|
+
async hasPass(address) {
|
|
480
|
+
return checkUnlimitedPass(this.client, this.vaultAddress, address);
|
|
481
|
+
}
|
|
482
|
+
/**
|
|
483
|
+
* Check if an address has a vault on-chain.
|
|
484
|
+
*/
|
|
485
|
+
async hasVault(address) {
|
|
486
|
+
return hasVault(this.client, this.vaultAddress, address);
|
|
487
|
+
}
|
|
488
|
+
/**
|
|
489
|
+
* Sign the KDF message with a private key.
|
|
490
|
+
* Returns the wallet signature needed for v2 read/write operations.
|
|
491
|
+
*/
|
|
492
|
+
async signKdfMessage(privateKey) {
|
|
493
|
+
return signMessage(privateKey, KDF_SIGN_MESSAGE);
|
|
494
|
+
}
|
|
495
|
+
/** Get the chain ID this client is configured for */
|
|
496
|
+
getChainId() {
|
|
497
|
+
return this.chainId;
|
|
498
|
+
}
|
|
499
|
+
/** Get the vault contract address */
|
|
500
|
+
getVaultAddress() {
|
|
501
|
+
return this.vaultAddress;
|
|
502
|
+
}
|
|
503
|
+
};
|
|
504
|
+
|
|
505
|
+
export { CHAIN_NAME_TO_ID, DeadVault, KDF_SIGN_MESSAGE, VAULT_ADDRESSES, base32Decode, decrypt, detectVersionFromHex, encrypt, encryptV2, generateTOTP, getTOTPTimeRemaining, isValidTOTPSecret };
|
|
506
|
+
//# sourceMappingURL=index.js.map
|
|
507
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/chains.ts","../src/contract.ts","../src/crypto.ts","../src/totp.ts","../src/client.ts"],"names":["privateKeyToAccount"],"mappings":"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","file":"index.js","sourcesContent":["/**\r\n * Chain configuration — contract addresses, RPCs, chain objects, and ABI.\r\n * @module\r\n */\r\nimport { base, mainnet, arbitrum, optimism, type Chain } from \"viem/chains\";\r\n\r\n// ── Contract Addresses ──────────────────────────────\r\n\r\n/** DeadVault proxy addresses per chain ID */\r\nexport const VAULT_ADDRESSES: Record<number, `0x${string}`> = {\r\n 8453: \"0xF74C1131E11aF8dc10F25bAa977dD0B86d4A5C37\", // Base\r\n 1: \"0xF74C1131E11aF8dc10F25bAa977dD0B86d4A5C37\", // Ethereum\r\n 42161: \"0x33939ede1A19A64EE755F1B5B3284A8E71F68484\", // Arbitrum One\r\n 10: \"0x33939ede1A19A64EE755F1B5B3284A8E71F68484\", // Optimism\r\n} as const;\r\n\r\n/** Default public RPC endpoints (rate‑limited, for light use) */\r\nexport const RPC_URLS: Record<number, string> = {\r\n 8453: \"https://mainnet.base.org\",\r\n 1: \"https://ethereum-rpc.publicnode.com\",\r\n 42161: \"https://arbitrum-one-rpc.publicnode.com\",\r\n 10: \"https://optimism-rpc.publicnode.com\",\r\n} as const;\r\n\r\n/** Human‑friendly chain name → chain ID lookup */\r\nexport const CHAIN_NAME_TO_ID: Record<string, number> = {\r\n \"base\": 8453,\r\n \"ethereum\": 1,\r\n \"arbitrum\": 42161,\r\n \"optimism\": 10,\r\n} as const;\r\n\r\n/** viem Chain objects keyed by chain ID */\r\nexport const CHAINS: Record<number, Chain> = {\r\n 8453: base,\r\n 1: mainnet,\r\n 42161: arbitrum,\r\n 10: optimism,\r\n};\r\n\r\n// ── ABI ─────────────────────────────────────────────\r\n\r\n/** Minimal DeadVault ABI (only the functions the SDK uses) */\r\nexport const DEAD_VAULT_ABI = [\r\n {\r\n type: \"function\",\r\n name: \"deleteSecret\",\r\n inputs: [],\r\n outputs: [],\r\n stateMutability: \"nonpayable\",\r\n },\r\n {\r\n type: \"function\",\r\n name: \"getNativeWriteFee\",\r\n inputs: [],\r\n outputs: [{ name: \"\", type: \"uint256\", internalType: \"uint256\" }],\r\n stateMutability: \"view\",\r\n },\r\n {\r\n type: \"function\",\r\n name: \"getSecret\",\r\n inputs: [{ name: \"agent\", type: \"address\", internalType: \"address\" }],\r\n outputs: [{ name: \"\", type: \"bytes\", internalType: \"bytes\" }],\r\n stateMutability: \"view\",\r\n },\r\n {\r\n type: \"function\",\r\n name: \"hasSecret\",\r\n inputs: [{ name: \"agent\", type: \"address\", internalType: \"address\" }],\r\n outputs: [{ name: \"\", type: \"bool\", internalType: \"bool\" }],\r\n stateMutability: \"view\",\r\n },\r\n {\r\n type: \"function\",\r\n name: \"hasUnlimitedPass\",\r\n inputs: [{ name: \"agent\", type: \"address\", internalType: \"address\" }],\r\n outputs: [{ name: \"\", type: \"bool\", internalType: \"bool\" }],\r\n stateMutability: \"view\",\r\n },\r\n {\r\n type: \"function\",\r\n name: \"storeSecret\",\r\n inputs: [{ name: \"payload\", type: \"bytes\", internalType: \"bytes\" }],\r\n outputs: [],\r\n stateMutability: \"payable\",\r\n },\r\n] as const;\r\n","/**\r\n * On-chain contract interactions using viem.\r\n * No browser dependencies — works in Node.js, Deno, Bun, Workers.\r\n */\r\nimport {\r\n createPublicClient,\r\n createWalletClient,\r\n http,\r\n encodeFunctionData,\r\n type PublicClient,\r\n} from \"viem\";\r\nimport { privateKeyToAccount } from \"viem/accounts\";\r\nimport { VAULT_ADDRESSES, RPC_URLS, CHAINS, DEAD_VAULT_ABI } from \"./chains\";\r\n\r\n/** Create a public client for the given chain + optional custom RPC */\r\nexport function makePublicClient(chainId: number, rpcUrl?: string): PublicClient {\r\n const chain = CHAINS[chainId];\r\n if (!chain) throw new Error(`Unsupported chain ID: ${chainId}`);\r\n const transport = http(rpcUrl || RPC_URLS[chainId]);\r\n return createPublicClient({ chain, transport });\r\n}\r\n\r\n/** Read the on-chain encrypted vault blob for an address */\r\nexport async function readVaultFromChain(\r\n client: PublicClient,\r\n vaultAddress: `0x${string}`,\r\n userAddress: string,\r\n): Promise<{ hasSecret: boolean; ciphertext: string | null }> {\r\n const addr = userAddress as `0x${string}`;\r\n\r\n const [hasSecret, rawBytes] = await Promise.all([\r\n client.readContract({\r\n address: vaultAddress,\r\n abi: DEAD_VAULT_ABI,\r\n functionName: \"hasSecret\",\r\n args: [addr],\r\n }),\r\n client.readContract({\r\n address: vaultAddress,\r\n abi: DEAD_VAULT_ABI,\r\n functionName: \"getSecret\",\r\n args: [addr],\r\n }),\r\n ]);\r\n\r\n let ciphertext: string | null = null;\r\n if (hasSecret && rawBytes) {\r\n ciphertext =\r\n typeof rawBytes === \"string\"\r\n ? rawBytes\r\n : \"0x\" +\r\n Array.from(rawBytes as Uint8Array)\r\n .map((b) => b.toString(16).padStart(2, \"0\"))\r\n .join(\"\");\r\n }\r\n\r\n return { hasSecret: hasSecret as boolean, ciphertext };\r\n}\r\n\r\n/** Read the native write fee */\r\nexport async function readNativeFee(\r\n client: PublicClient,\r\n vaultAddress: `0x${string}`,\r\n): Promise<bigint> {\r\n return (await client.readContract({\r\n address: vaultAddress,\r\n abi: DEAD_VAULT_ABI,\r\n functionName: \"getNativeWriteFee\",\r\n })) as bigint;\r\n}\r\n\r\n/** Check if an address has an unlimited pass */\r\nexport async function checkUnlimitedPass(\r\n client: PublicClient,\r\n vaultAddress: `0x${string}`,\r\n userAddress: string,\r\n): Promise<boolean> {\r\n return (await client.readContract({\r\n address: vaultAddress,\r\n abi: DEAD_VAULT_ABI,\r\n functionName: \"hasUnlimitedPass\",\r\n args: [userAddress as `0x${string}`],\r\n })) as boolean;\r\n}\r\n\r\n/** Check if an address has a vault on-chain */\r\nexport async function hasVault(\r\n client: PublicClient,\r\n vaultAddress: `0x${string}`,\r\n userAddress: string,\r\n): Promise<boolean> {\r\n return (await client.readContract({\r\n address: vaultAddress,\r\n abi: DEAD_VAULT_ABI,\r\n functionName: \"hasSecret\",\r\n args: [userAddress as `0x${string}`],\r\n })) as boolean;\r\n}\r\n\r\n/** Write encrypted vault data on-chain */\r\nexport async function writeVaultToChain(\r\n chainId: number,\r\n vaultAddress: `0x${string}`,\r\n privateKey: string,\r\n payload: `0x${string}`,\r\n value: bigint,\r\n rpcUrl?: string,\r\n): Promise<{ hash: string; blockNumber: bigint }> {\r\n const chain = CHAINS[chainId];\r\n if (!chain) throw new Error(`Unsupported chain ID: ${chainId}`);\r\n\r\n const hex = privateKey.startsWith(\"0x\") ? privateKey : `0x${privateKey}`;\r\n const account = privateKeyToAccount(hex as `0x${string}`);\r\n\r\n const walletClient = createWalletClient({\r\n account,\r\n chain,\r\n transport: http(rpcUrl || RPC_URLS[chainId]),\r\n });\r\n\r\n const calldata = encodeFunctionData({\r\n abi: DEAD_VAULT_ABI,\r\n functionName: \"storeSecret\",\r\n args: [payload],\r\n });\r\n\r\n const hash = await walletClient.sendTransaction({\r\n account,\r\n chain,\r\n to: vaultAddress,\r\n data: calldata,\r\n value,\r\n });\r\n\r\n const publicClient = makePublicClient(chainId, rpcUrl);\r\n const receipt = await publicClient.waitForTransactionReceipt({ hash });\r\n\r\n return { hash, blockNumber: receipt.blockNumber };\r\n}\r\n\r\n/** Get the vault contract address for a chain */\r\nexport function getVaultAddress(chainId: number): `0x${string}` {\r\n const addr = VAULT_ADDRESSES[chainId];\r\n if (!addr) throw new Error(`No DeadVault contract on chain ${chainId}`);\r\n return addr;\r\n}\r\n\r\n/** Sign a message with a private key (for v2 encryption KDF) */\r\nexport async function signMessage(privateKey: string, message: string): Promise<string> {\r\n const hex = (privateKey.startsWith(\"0x\") ? privateKey : `0x${privateKey}`) as `0x${string}`;\r\n const account = privateKeyToAccount(hex);\r\n return account.signMessage({ message });\r\n}\r\n","/**\r\n * AES-256-GCM encryption/decryption using Web Crypto API.\r\n * Compatible with Node.js 18+, Deno, Bun, and Cloudflare Workers.\r\n *\r\n * v1: PBKDF2(password, salt, 600k, SHA-256) → AES-256-GCM\r\n * Format: salt(16) || iv(12) || ciphertext\r\n *\r\n * v2: PBKDF2(password + walletSignature, salt, 600k, SHA-256) → AES-256-GCM\r\n * Format: 0xDEAD00 || 0x02 || salt(16) || iv(12) || ciphertext\r\n */\r\n\r\nconst PBKDF2_ITERATIONS = 600_000;\r\nconst MAGIC = new Uint8Array([0xde, 0xad, 0x00]);\r\nconst VERSION_V2 = 0x02;\r\nconst HEADER_V2 = new Uint8Array([...MAGIC, VERSION_V2]);\r\n\r\nexport const KDF_SIGN_MESSAGE =\r\n \"DeadVault Encryption Key Derivation\\n\\n\" +\r\n \"Sign this message to derive your personal encryption key.\\n\" +\r\n \"This signature is used locally and does NOT authorize any transaction or transfer.\";\r\n\r\nfunction detectVersion(packed: Uint8Array): { version: number; offset: number } {\r\n if (packed.length >= 4 && packed[0] === 0xde && packed[1] === 0xad && packed[2] === 0x00) {\r\n return { version: packed[3], offset: 4 };\r\n }\r\n return { version: 1, offset: 0 };\r\n}\r\n\r\nexport function detectVersionFromHex(hexCiphertext: string): number {\r\n const hex = hexCiphertext.startsWith(\"0x\") ? hexCiphertext.slice(2) : hexCiphertext;\r\n if (hex.length >= 8 && hex.slice(0, 6).toLowerCase() === \"dead00\") {\r\n return parseInt(hex.slice(6, 8), 16);\r\n }\r\n return 1;\r\n}\r\n\r\nfunction toHex(bytes: Uint8Array): string {\r\n return \"0x\" + Array.from(bytes).map((b) => b.toString(16).padStart(2, \"0\")).join(\"\");\r\n}\r\n\r\nfunction fromHex(hex: string): Uint8Array {\r\n const clean = hex.startsWith(\"0x\") ? hex.slice(2) : hex;\r\n if (clean.length === 0) throw new Error(\"Cannot decode empty hex string\");\r\n const pairs = clean.match(/.{1,2}/g);\r\n if (!pairs) throw new Error(\"Invalid hex string\");\r\n return new Uint8Array(pairs.map((byte) => parseInt(byte, 16)));\r\n}\r\n\r\nasync function deriveKeyV1(password: string, salt: Uint8Array): Promise<CryptoKey> {\r\n const enc = new TextEncoder();\r\n const keyMaterial = await crypto.subtle.importKey(\"raw\", enc.encode(password), \"PBKDF2\", false, [\"deriveKey\"]);\r\n return crypto.subtle.deriveKey(\r\n { name: \"PBKDF2\", salt: salt.buffer.slice(salt.byteOffset, salt.byteOffset + salt.byteLength) as ArrayBuffer, iterations: PBKDF2_ITERATIONS, hash: \"SHA-256\" },\r\n keyMaterial,\r\n { name: \"AES-GCM\", length: 256 },\r\n false,\r\n [\"encrypt\", \"decrypt\"],\r\n );\r\n}\r\n\r\nasync function deriveKeyV2(password: string, walletSignature: string, salt: Uint8Array): Promise<CryptoKey> {\r\n const enc = new TextEncoder();\r\n const combined = enc.encode(password + walletSignature);\r\n const keyMaterial = await crypto.subtle.importKey(\"raw\", combined, \"PBKDF2\", false, [\"deriveKey\"]);\r\n return crypto.subtle.deriveKey(\r\n { name: \"PBKDF2\", salt: salt.buffer.slice(salt.byteOffset, salt.byteOffset + salt.byteLength) as ArrayBuffer, iterations: PBKDF2_ITERATIONS, hash: \"SHA-256\" },\r\n keyMaterial,\r\n { name: \"AES-GCM\", length: 256 },\r\n false,\r\n [\"encrypt\", \"decrypt\"],\r\n );\r\n}\r\n\r\n/** Encrypt plaintext with password only (v1 format) */\r\nexport async function encrypt(plaintext: string, password: string): Promise<string> {\r\n const enc = new TextEncoder();\r\n const salt = crypto.getRandomValues(new Uint8Array(16));\r\n const iv = crypto.getRandomValues(new Uint8Array(12));\r\n const key = await deriveKeyV1(password, salt);\r\n const ct = new Uint8Array(await crypto.subtle.encrypt({ name: \"AES-GCM\", iv }, key, enc.encode(plaintext)));\r\n const packed = new Uint8Array(salt.length + iv.length + ct.length);\r\n packed.set(salt, 0);\r\n packed.set(iv, salt.length);\r\n packed.set(ct, salt.length + iv.length);\r\n return toHex(packed);\r\n}\r\n\r\n/** Encrypt plaintext with password + wallet signature (v2 format) */\r\nexport async function encryptV2(plaintext: string, password: string, walletSignature: string): Promise<string> {\r\n const enc = new TextEncoder();\r\n const salt = crypto.getRandomValues(new Uint8Array(16));\r\n const iv = crypto.getRandomValues(new Uint8Array(12));\r\n const key = await deriveKeyV2(password, walletSignature, salt);\r\n const ct = new Uint8Array(await crypto.subtle.encrypt({ name: \"AES-GCM\", iv }, key, enc.encode(plaintext)));\r\n const packed = new Uint8Array(HEADER_V2.length + salt.length + iv.length + ct.length);\r\n packed.set(HEADER_V2, 0);\r\n packed.set(salt, HEADER_V2.length);\r\n packed.set(iv, HEADER_V2.length + salt.length);\r\n packed.set(ct, HEADER_V2.length + salt.length + iv.length);\r\n return toHex(packed);\r\n}\r\n\r\n/** Decrypt a hex ciphertext. Auto-detects v1/v2 format. */\r\nexport async function decrypt(hexCiphertext: string, password: string, walletSignature?: string): Promise<string> {\r\n const packed = fromHex(hexCiphertext);\r\n const { version, offset } = detectVersion(packed);\r\n const salt = packed.slice(offset, offset + 16);\r\n const iv = packed.slice(offset + 16, offset + 28);\r\n const ciphertext = packed.slice(offset + 28);\r\n\r\n let key: CryptoKey;\r\n if (version === 1) {\r\n key = await deriveKeyV1(password, salt);\r\n } else if (version === 2) {\r\n if (!walletSignature) throw new Error(\"Wallet signature required for v2 decryption.\");\r\n key = await deriveKeyV2(password, walletSignature, salt);\r\n } else {\r\n throw new Error(`Unknown encryption version: ${version}`);\r\n }\r\n\r\n const plainBuffer = await crypto.subtle.decrypt({ name: \"AES-GCM\", iv }, key, ciphertext);\r\n return new TextDecoder().decode(plainBuffer);\r\n}\r\n","/**\r\n * TOTP (Time-Based One-Time Password) Generator — RFC 6238\r\n * Uses Web Crypto API for HMAC. No external dependencies.\r\n */\r\n\r\nconst BASE32_CHARS = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567\";\r\n\r\n/** Decode a Base32-encoded string */\r\nexport function base32Decode(input: string): Uint8Array {\r\n const cleaned = input.replace(/[\\s=-]/g, \"\").toUpperCase();\r\n const out: number[] = [];\r\n let bits = 0;\r\n let value = 0;\r\n\r\n for (const char of cleaned) {\r\n const idx = BASE32_CHARS.indexOf(char);\r\n if (idx === -1) continue;\r\n value = (value << 5) | idx;\r\n bits += 5;\r\n if (bits >= 8) {\r\n bits -= 8;\r\n out.push((value >>> bits) & 0xff);\r\n }\r\n }\r\n\r\n return new Uint8Array(out);\r\n}\r\n\r\nexport type TOTPAlgorithm = \"SHA1\" | \"SHA256\";\r\n\r\nexport interface TOTPParams {\r\n secret: string; // Base32-encoded secret\r\n algorithm?: TOTPAlgorithm;\r\n digits?: 6 | 8;\r\n period?: number; // seconds (default 30)\r\n}\r\n\r\n/** Generate the current TOTP code */\r\nexport async function generateTOTP(params: TOTPParams): Promise<string> {\r\n const { secret, algorithm = \"SHA1\", digits = 6, period = 30 } = params;\r\n const now = Math.floor(Date.now() / 1000);\r\n const counter = Math.floor(now / period);\r\n return generateHOTP(secret, counter, algorithm, digits);\r\n}\r\n\r\n/** Get remaining seconds in the current TOTP window */\r\nexport function getTOTPTimeRemaining(period = 30): number {\r\n const now = Math.floor(Date.now() / 1000);\r\n return period - (now % period);\r\n}\r\n\r\nasync function generateHOTP(\r\n base32Secret: string,\r\n counter: number,\r\n algorithm: TOTPAlgorithm,\r\n digits: number,\r\n): Promise<string> {\r\n const key = base32Decode(base32Secret);\r\n\r\n const counterBuf = new ArrayBuffer(8);\r\n const view = new DataView(counterBuf);\r\n view.setUint32(4, counter, false);\r\n\r\n const algo = algorithm === \"SHA256\" ? \"SHA-256\" : \"SHA-1\";\r\n const cryptoKey = await crypto.subtle.importKey(\r\n \"raw\",\r\n key.buffer as ArrayBuffer,\r\n { name: \"HMAC\", hash: algo },\r\n false,\r\n [\"sign\"],\r\n );\r\n const hmac = await crypto.subtle.sign(\"HMAC\", cryptoKey, counterBuf);\r\n const hmacBytes = new Uint8Array(hmac);\r\n\r\n const offset = hmacBytes[hmacBytes.length - 1] & 0x0f;\r\n const code =\r\n ((hmacBytes[offset] & 0x7f) << 24) |\r\n ((hmacBytes[offset + 1] & 0xff) << 16) |\r\n ((hmacBytes[offset + 2] & 0xff) << 8) |\r\n (hmacBytes[offset + 3] & 0xff);\r\n\r\n const otp = code % 10 ** digits;\r\n return otp.toString().padStart(digits, \"0\");\r\n}\r\n\r\n/** Validate a base32 TOTP secret — checks it decodes to >= 10 bytes */\r\nexport function isValidTOTPSecret(secret: string): boolean {\r\n try {\r\n const decoded = base32Decode(secret);\r\n return decoded.length >= 10;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n","/**\r\n * DeadVault SDK — Main client class.\r\n *\r\n * Usage:\r\n * const vault = new DeadVault({ chain: \"base\" });\r\n * const data = await vault.read({ address, password, walletSignature });\r\n * const entry = vault.findEntry(data, { label: \"OpenAI\" });\r\n * const code = await vault.generateTOTP(entry);\r\n */\r\n\r\nimport type { PublicClient } from \"viem\";\r\nimport { privateKeyToAccount } from \"viem/accounts\";\r\nimport type {\r\n DeadVaultConfig,\r\n ReadOptions,\r\n WriteOptions,\r\n WriteResult,\r\n FeeInfo,\r\n VaultData,\r\n VaultEntry,\r\n} from \"./types\";\r\nimport { CHAIN_NAME_TO_ID } from \"./chains\";\r\nimport {\r\n makePublicClient,\r\n readVaultFromChain,\r\n readNativeFee,\r\n checkUnlimitedPass,\r\n hasVault as checkHasVault,\r\n writeVaultToChain,\r\n getVaultAddress,\r\n signMessage,\r\n} from \"./contract\";\r\nimport { decrypt, encryptV2, detectVersionFromHex, KDF_SIGN_MESSAGE } from \"./crypto\";\r\nimport { generateTOTP as totpGenerate, getTOTPTimeRemaining, type TOTPParams } from \"./totp\";\r\n\r\nconst VAULT_DATA_VERSION = 1;\r\n\r\nfunction parseVault(plaintext: string): VaultData {\r\n try {\r\n const parsed = JSON.parse(plaintext);\r\n if (parsed && typeof parsed === \"object\" && Array.isArray(parsed.entries)) {\r\n return parsed as VaultData;\r\n }\r\n return wrapLegacy(plaintext);\r\n } catch {\r\n return wrapLegacy(plaintext);\r\n }\r\n}\r\n\r\nfunction wrapLegacy(plaintext: string): VaultData {\r\n return {\r\n version: VAULT_DATA_VERSION,\r\n entries: [\r\n {\r\n id: crypto.randomUUID(),\r\n label: \"Legacy Secret\",\r\n secret: plaintext,\r\n category: \"Imported\",\r\n createdAt: Date.now(),\r\n updatedAt: Date.now(),\r\n },\r\n ],\r\n };\r\n}\r\n\r\nfunction serializeVault(data: VaultData): string {\r\n return JSON.stringify(data);\r\n}\r\n\r\nexport class DeadVault {\r\n private readonly chainId: number;\r\n private readonly rpcUrl?: string;\r\n private readonly vaultAddress: `0x${string}`;\r\n private client: PublicClient;\r\n\r\n constructor(config: DeadVaultConfig = {}) {\r\n if (config.chainId) {\r\n this.chainId = config.chainId;\r\n } else if (config.chain) {\r\n const id = CHAIN_NAME_TO_ID[config.chain];\r\n if (!id) throw new Error(`Unknown chain: \"${config.chain}\". Use: base, ethereum, arbitrum, optimism`);\r\n this.chainId = id;\r\n } else {\r\n this.chainId = 8453; // default: Base\r\n }\r\n\r\n this.rpcUrl = config.rpcUrl;\r\n this.vaultAddress = getVaultAddress(this.chainId);\r\n this.client = makePublicClient(this.chainId, this.rpcUrl);\r\n }\r\n\r\n /**\r\n * Read and decrypt a vault from the chain.\r\n * Returns the decrypted VaultData with all entries.\r\n */\r\n async read(options: ReadOptions): Promise<VaultData> {\r\n const { address, password, walletSignature } = options;\r\n\r\n const { hasSecret, ciphertext } = await readVaultFromChain(\r\n this.client,\r\n this.vaultAddress,\r\n address,\r\n );\r\n\r\n if (!hasSecret || !ciphertext) {\r\n return { version: VAULT_DATA_VERSION, entries: [] };\r\n }\r\n\r\n const version = detectVersionFromHex(ciphertext);\r\n if (version >= 2 && !walletSignature) {\r\n throw new Error(\"This vault uses v2 encryption. Provide walletSignature for decryption.\");\r\n }\r\n\r\n const plaintext = await decrypt(ciphertext, password, walletSignature);\r\n return parseVault(plaintext);\r\n }\r\n\r\n /**\r\n * Encrypt and write vault data on-chain.\r\n * Requires a private key for the transaction + wallet signature for v2 encryption.\r\n */\r\n async write(options: WriteOptions): Promise<WriteResult> {\r\n const { data, password, privateKey, walletSignature } = options;\r\n\r\n const plaintext = serializeVault(data);\r\n const ciphertext = await encryptV2(plaintext, password, walletSignature);\r\n const payload = ciphertext as `0x${string}`;\r\n\r\n // Derive the wallet address from private key for the pass check\r\n const hex = (privateKey.startsWith(\"0x\") ? privateKey : `0x${privateKey}`) as `0x${string}`;\r\n const account = privateKeyToAccount(hex);\r\n\r\n const hasPass = await checkUnlimitedPass(\r\n this.client,\r\n this.vaultAddress,\r\n account.address,\r\n );\r\n\r\n let fee = 0n;\r\n if (!hasPass) {\r\n fee = await readNativeFee(this.client, this.vaultAddress);\r\n }\r\n\r\n return writeVaultToChain(\r\n this.chainId,\r\n this.vaultAddress,\r\n privateKey,\r\n payload,\r\n fee,\r\n this.rpcUrl,\r\n );\r\n }\r\n\r\n /**\r\n * Find an entry in vault data by label, category, URL, or custom predicate.\r\n */\r\n findEntry(\r\n data: VaultData,\r\n match: { label?: string; category?: string; url?: string } | ((entry: VaultEntry) => boolean),\r\n ): VaultEntry | undefined {\r\n if (typeof match === \"function\") {\r\n return data.entries.find(match);\r\n }\r\n return data.entries.find((e) => {\r\n if (match.label && !e.label.toLowerCase().includes(match.label.toLowerCase())) return false;\r\n if (match.category && e.category?.toLowerCase() !== match.category.toLowerCase()) return false;\r\n if (match.url && !e.url?.toLowerCase().includes(match.url.toLowerCase())) return false;\r\n return true;\r\n });\r\n }\r\n\r\n /**\r\n * Find all matching entries.\r\n */\r\n findEntries(\r\n data: VaultData,\r\n match: { label?: string; category?: string; url?: string; type?: \"password\" | \"totp\" } | ((entry: VaultEntry) => boolean),\r\n ): VaultEntry[] {\r\n if (typeof match === \"function\") {\r\n return data.entries.filter(match);\r\n }\r\n return data.entries.filter((e) => {\r\n if (match.label && !e.label.toLowerCase().includes(match.label.toLowerCase())) return false;\r\n if (match.category && e.category?.toLowerCase() !== match.category.toLowerCase()) return false;\r\n if (match.url && !e.url?.toLowerCase().includes(match.url.toLowerCase())) return false;\r\n if (match.type && (e.type || \"password\") !== match.type) return false;\r\n return true;\r\n });\r\n }\r\n\r\n /**\r\n * Generate a TOTP code from a vault entry.\r\n * The entry must have type \"totp\" and contain a base32 secret.\r\n */\r\n async generateTOTP(entry: VaultEntry): Promise<string> {\r\n const params: TOTPParams = {\r\n secret: entry.secret,\r\n algorithm: entry.totpConfig?.algorithm,\r\n digits: entry.totpConfig?.digits,\r\n period: entry.totpConfig?.period,\r\n };\r\n return totpGenerate(params);\r\n }\r\n\r\n /**\r\n * Get the remaining seconds in the current TOTP window.\r\n */\r\n getTOTPTimeRemaining(period = 30): number {\r\n return getTOTPTimeRemaining(period);\r\n }\r\n\r\n /**\r\n * Get the write fee for this chain.\r\n */\r\n async getWriteFee(): Promise<FeeInfo> {\r\n const wei = await readNativeFee(this.client, this.vaultAddress);\r\n const eth = (Number(wei) / 1e18).toFixed(8);\r\n return { wei, eth };\r\n }\r\n\r\n /**\r\n * Check if an address has an unlimited pass (no fee required).\r\n */\r\n async hasPass(address: string): Promise<boolean> {\r\n return checkUnlimitedPass(this.client, this.vaultAddress, address);\r\n }\r\n\r\n /**\r\n * Check if an address has a vault on-chain.\r\n */\r\n async hasVault(address: string): Promise<boolean> {\r\n return checkHasVault(this.client, this.vaultAddress, address);\r\n }\r\n\r\n /**\r\n * Sign the KDF message with a private key.\r\n * Returns the wallet signature needed for v2 read/write operations.\r\n */\r\n async signKdfMessage(privateKey: string): Promise<string> {\r\n return signMessage(privateKey, KDF_SIGN_MESSAGE);\r\n }\r\n\r\n /** Get the chain ID this client is configured for */\r\n getChainId(): number {\r\n return this.chainId;\r\n }\r\n\r\n /** Get the vault contract address */\r\n getVaultAddress(): `0x${string}` {\r\n return this.vaultAddress;\r\n }\r\n}\r\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@deadvault/sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Decentralized credential store SDK for AI agents, servers & scripts",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"default": "./dist/index.js"
|
|
14
|
+
},
|
|
15
|
+
"require": {
|
|
16
|
+
"types": "./dist/index.d.cts",
|
|
17
|
+
"default": "./dist/index.cjs"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"dist",
|
|
23
|
+
"README.md",
|
|
24
|
+
"LICENSE"
|
|
25
|
+
],
|
|
26
|
+
"scripts": {
|
|
27
|
+
"build": "tsup",
|
|
28
|
+
"dev": "tsup --watch",
|
|
29
|
+
"test": "vitest run",
|
|
30
|
+
"typecheck": "tsc --noEmit",
|
|
31
|
+
"clean": "rimraf dist"
|
|
32
|
+
},
|
|
33
|
+
"keywords": [
|
|
34
|
+
"deadvault",
|
|
35
|
+
"vault",
|
|
36
|
+
"password-manager",
|
|
37
|
+
"credential-store",
|
|
38
|
+
"ai-agent",
|
|
39
|
+
"sdk",
|
|
40
|
+
"blockchain",
|
|
41
|
+
"web3",
|
|
42
|
+
"encryption",
|
|
43
|
+
"totp"
|
|
44
|
+
],
|
|
45
|
+
"license": "MIT",
|
|
46
|
+
"sideEffects": false,
|
|
47
|
+
"engines": {
|
|
48
|
+
"node": ">=18"
|
|
49
|
+
},
|
|
50
|
+
"repository": {
|
|
51
|
+
"type": "git",
|
|
52
|
+
"url": "https://github.com/deadvault/deadvault-sdk"
|
|
53
|
+
},
|
|
54
|
+
"homepage": "https://vault.dead.box",
|
|
55
|
+
"bugs": {
|
|
56
|
+
"url": "https://github.com/deadvault/deadvault-sdk/issues"
|
|
57
|
+
},
|
|
58
|
+
"peerDependencies": {
|
|
59
|
+
"viem": "^2.0.0"
|
|
60
|
+
},
|
|
61
|
+
"devDependencies": {
|
|
62
|
+
"@types/node": "^25.4.0",
|
|
63
|
+
"rimraf": "^6.0.0",
|
|
64
|
+
"tsup": "^8.5.0",
|
|
65
|
+
"typescript": "^5.8.0",
|
|
66
|
+
"viem": "^2.23.0",
|
|
67
|
+
"vitest": "^4.0.18"
|
|
68
|
+
}
|
|
69
|
+
}
|