@whistlex/sdk 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -0
- package/dist/crypto.d.ts +7 -0
- package/dist/crypto.js +10 -0
- package/dist/taco.d.ts +3 -1
- package/dist/taco.js +29 -10
- package/package.json +6 -3
package/README.md
CHANGED
|
@@ -36,6 +36,7 @@ const messageKit = await encryptWithTaco({
|
|
|
36
36
|
poolAddress: "0xPoolAddressPlaceholder", // use actual pool address after createPool
|
|
37
37
|
payload: keyBytes,
|
|
38
38
|
privateKey: process.env.TACO_PRIVATE_KEY
|
|
39
|
+
// or: signer: walletSigner (MCP / injected signer)
|
|
39
40
|
});
|
|
40
41
|
|
|
41
42
|
// 3) On-chain create pool
|
|
@@ -53,6 +54,42 @@ await tx.wait();
|
|
|
53
54
|
// 4) Store metadata via API (see /skill.md for API calls)
|
|
54
55
|
```
|
|
55
56
|
|
|
57
|
+
## Dry Run (No On-chain Submission)
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
POOL_ADDRESS=0xYourPool TACO_PRIVATE_KEY=0xyourkey npm run dry-run
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
This will print:
|
|
64
|
+
- `ciphertextHex` (ready for on-chain calldata)
|
|
65
|
+
- `messageKit` (TACo wrapped DEK)
|
|
66
|
+
|
|
67
|
+
### Using a Signer (MCP / Injected)
|
|
68
|
+
|
|
69
|
+
If you have a signer (e.g., Phantom MCP), pass it directly:
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
const messageKit = await encryptWithTaco({
|
|
73
|
+
poolAddress,
|
|
74
|
+
payload: keyBytes,
|
|
75
|
+
signer // wallet signer
|
|
76
|
+
});
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Decrypt Intel (TACo)
|
|
80
|
+
|
|
81
|
+
```ts
|
|
82
|
+
import { decryptIntelWithTaco } from "@whistlex/sdk";
|
|
83
|
+
|
|
84
|
+
const plaintext = await decryptIntelWithTaco({
|
|
85
|
+
ciphertext,
|
|
86
|
+
messageKit,
|
|
87
|
+
contributorAddress,
|
|
88
|
+
privateKey: process.env.TACO_PRIVATE_KEY
|
|
89
|
+
// or signer
|
|
90
|
+
});
|
|
91
|
+
```
|
|
92
|
+
|
|
56
93
|
## Notes
|
|
57
94
|
|
|
58
95
|
- **Intel is encrypted locally**. The SDK never sends plaintext to WhistleX.
|
package/dist/crypto.d.ts
CHANGED
|
@@ -20,6 +20,13 @@ export declare function decryptIntelWithKey(params: {
|
|
|
20
20
|
ciphertext: string;
|
|
21
21
|
keyBytes: Uint8Array;
|
|
22
22
|
}): Promise<string>;
|
|
23
|
+
export declare function decryptIntelWithTaco(params: {
|
|
24
|
+
ciphertext: string;
|
|
25
|
+
messageKit: string;
|
|
26
|
+
contributorAddress?: string;
|
|
27
|
+
privateKey?: string;
|
|
28
|
+
signer?: any;
|
|
29
|
+
}): Promise<string>;
|
|
23
30
|
export declare const symmetricEncoding: {
|
|
24
31
|
bytesToHex: typeof bytesToHex;
|
|
25
32
|
hexToBytes: typeof hexToBytes;
|
package/dist/crypto.js
CHANGED
|
@@ -89,4 +89,14 @@ export async function decryptIntelWithKey(params) {
|
|
|
89
89
|
const plainBuffer = await subtle.decrypt({ name: "AES-GCM", iv: toArrayBuffer(ivBytes) }, aesKey, toArrayBuffer(cipherBytes));
|
|
90
90
|
return new TextDecoder().decode(plainBuffer);
|
|
91
91
|
}
|
|
92
|
+
export async function decryptIntelWithTaco(params) {
|
|
93
|
+
const { decryptWithTaco } = await import("./taco.js");
|
|
94
|
+
const keyBytes = await decryptWithTaco({
|
|
95
|
+
messageKit: params.messageKit,
|
|
96
|
+
contributorAddress: params.contributorAddress,
|
|
97
|
+
privateKey: params.privateKey,
|
|
98
|
+
signer: params.signer
|
|
99
|
+
});
|
|
100
|
+
return decryptIntelWithKey({ ciphertext: params.ciphertext, keyBytes });
|
|
101
|
+
}
|
|
92
102
|
export const symmetricEncoding = { bytesToHex, hexToBytes };
|
package/dist/taco.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import { providers, Wallet } from "ethers";
|
|
1
2
|
export declare const DEFAULT_POLYGON_AMOY_RPC_URL = "https://polygon-amoy.drpc.org";
|
|
2
3
|
export declare const DEFAULT_TACO_RITUAL_ID = 6;
|
|
3
4
|
export declare const DEFAULT_CONDITION_CHAIN_ID = 80002;
|
|
4
5
|
export interface TacoConfig {
|
|
5
6
|
privateKey?: string;
|
|
7
|
+
signer?: providers.JsonRpcSigner | Wallet;
|
|
6
8
|
dkgRpcUrl?: string;
|
|
7
9
|
conditionRpcUrl?: string;
|
|
8
10
|
conditionChainId?: number;
|
|
@@ -41,4 +43,4 @@ export declare function encryptWithTaco(params: EncryptWithTacoParams): Promise<
|
|
|
41
43
|
export declare function decryptWithTaco(params: TacoConfig & {
|
|
42
44
|
messageKit: string;
|
|
43
45
|
contributorAddress?: string;
|
|
44
|
-
}): Promise<
|
|
46
|
+
}): Promise<Uint8Array>;
|
package/dist/taco.js
CHANGED
|
@@ -6,21 +6,40 @@ export const DEFAULT_CONDITION_CHAIN_ID = 80002;
|
|
|
6
6
|
function resolveTacoConfig(config) {
|
|
7
7
|
return {
|
|
8
8
|
key: config.privateKey,
|
|
9
|
+
signer: config.signer,
|
|
9
10
|
dkg: config.dkgRpcUrl || process.env.TACO_DKG_RPC_URL || DEFAULT_POLYGON_AMOY_RPC_URL,
|
|
10
11
|
condition: config.conditionRpcUrl || process.env.TACO_CONDITION_RPC_URL || DEFAULT_POLYGON_AMOY_RPC_URL,
|
|
11
12
|
conditionChain: config.conditionChainId || DEFAULT_CONDITION_CHAIN_ID,
|
|
12
13
|
ritual: config.ritualId || DEFAULT_TACO_RITUAL_ID
|
|
13
14
|
};
|
|
14
15
|
}
|
|
15
|
-
async function resolveConditionSigner(provider, key) {
|
|
16
|
+
async function resolveConditionSigner(provider, key, signer) {
|
|
17
|
+
if (signer)
|
|
18
|
+
return signer;
|
|
16
19
|
if (!key) {
|
|
17
|
-
throw new Error("TACo
|
|
20
|
+
throw new Error("TACo signer is required. Provide privateKey or signer.");
|
|
18
21
|
}
|
|
19
22
|
return new Wallet(key, provider);
|
|
20
23
|
}
|
|
21
24
|
function toHexString(bytes) {
|
|
22
25
|
return Buffer.from(bytes).toString("hex");
|
|
23
26
|
}
|
|
27
|
+
function parseMessageKitBytes(serialized) {
|
|
28
|
+
const normalized = serialized.trim();
|
|
29
|
+
const hex = normalized.startsWith("0x") ? normalized.slice(2) : normalized;
|
|
30
|
+
try {
|
|
31
|
+
return Uint8Array.from(Buffer.from(hex, "hex"));
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
// fallthrough to base64
|
|
35
|
+
}
|
|
36
|
+
try {
|
|
37
|
+
return Uint8Array.from(Buffer.from(normalized, "base64"));
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
throw new Error("Unsupported messageKit encoding; expected hex or base64");
|
|
41
|
+
}
|
|
42
|
+
}
|
|
24
43
|
function encodePayload(data) {
|
|
25
44
|
const normalized = data.trim();
|
|
26
45
|
const hexMatch = normalized.match(/^0x[0-9a-fA-F]+$/);
|
|
@@ -65,11 +84,11 @@ export async function encryptWithTaco(params) {
|
|
|
65
84
|
if (!ContractCondition) {
|
|
66
85
|
throw new Error("encryptWithTaco: ContractCondition not available");
|
|
67
86
|
}
|
|
68
|
-
const { key, dkg, condition, conditionChain, ritual } = resolveTacoConfig(params);
|
|
87
|
+
const { key, signer, dkg, condition, conditionChain, ritual } = resolveTacoConfig(params);
|
|
69
88
|
await initialize();
|
|
70
89
|
const dkgProvider = new providers.JsonRpcProvider(dkg);
|
|
71
90
|
const conditionProvider = new providers.JsonRpcProvider(condition);
|
|
72
|
-
const encryptorSigner = await resolveConditionSigner(conditionProvider, key);
|
|
91
|
+
const encryptorSigner = await resolveConditionSigner(conditionProvider, key, signer);
|
|
73
92
|
const conditionInstance = new ContractCondition({
|
|
74
93
|
method: "canDecrypt",
|
|
75
94
|
parameters: [":contributor"],
|
|
@@ -83,7 +102,7 @@ export async function encryptWithTaco(params) {
|
|
|
83
102
|
if (typeof kit === "string")
|
|
84
103
|
return kit;
|
|
85
104
|
if (kit?.toBytes)
|
|
86
|
-
return toHexString(kit.toBytes())
|
|
105
|
+
return `0x${toHexString(kit.toBytes())}`;
|
|
87
106
|
if (kit?.toString)
|
|
88
107
|
return kit.toString();
|
|
89
108
|
return JSON.stringify(kit);
|
|
@@ -101,17 +120,17 @@ export async function decryptWithTaco(params) {
|
|
|
101
120
|
const ConditionContext = conditions?.context?.ConditionContext;
|
|
102
121
|
if (!ConditionContext)
|
|
103
122
|
throw new Error("decryptWithTaco: ConditionContext missing");
|
|
104
|
-
const { key, condition, conditionChain, ritual, dkg } = resolveTacoConfig(params);
|
|
123
|
+
const { key, signer, condition, conditionChain, ritual, dkg } = resolveTacoConfig(params);
|
|
105
124
|
await initialize();
|
|
106
125
|
const conditionProvider = new providers.JsonRpcProvider(condition);
|
|
107
|
-
const decryptorSigner = await resolveConditionSigner(conditionProvider, key);
|
|
126
|
+
const decryptorSigner = await resolveConditionSigner(conditionProvider, key, signer);
|
|
108
127
|
const decryptorAddress = await decryptorSigner.getAddress();
|
|
109
|
-
const kitBytes =
|
|
110
|
-
const kit = ThresholdMessageKit.fromBytes(
|
|
128
|
+
const kitBytes = parseMessageKitBytes(messageKit);
|
|
129
|
+
const kit = ThresholdMessageKit.fromBytes(kitBytes);
|
|
111
130
|
const context = ConditionContext.fromMessageKit(kit);
|
|
112
131
|
context.addCustomContextParameterValues({
|
|
113
132
|
":contributor": contributorAddress ? utils.getAddress(contributorAddress) : decryptorAddress
|
|
114
133
|
});
|
|
115
134
|
const decryptedBytes = await decrypt(conditionProvider, domains.TESTNET || domains.tapir, kit, context, domains.TESTNET?.porterUris);
|
|
116
|
-
return
|
|
135
|
+
return decryptedBytes;
|
|
117
136
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@whistlex/sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "WhistleX SDK for local encryption, TACo wrapping, and on-chain pool calldata",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -11,10 +11,13 @@
|
|
|
11
11
|
"types": "./dist/index.d.ts"
|
|
12
12
|
}
|
|
13
13
|
},
|
|
14
|
-
"files": [
|
|
14
|
+
"files": [
|
|
15
|
+
"dist"
|
|
16
|
+
],
|
|
15
17
|
"scripts": {
|
|
16
18
|
"build": "tsc -p tsconfig.json",
|
|
17
|
-
"clean": "rm -rf dist"
|
|
19
|
+
"clean": "rm -rf dist",
|
|
20
|
+
"dry-run": "node ./scripts/dry-run.mjs"
|
|
18
21
|
},
|
|
19
22
|
"dependencies": {
|
|
20
23
|
"@nucypher/taco": "0.6.0",
|