@zhoujun_aptos/octopus-ts-sdk-min 0.22.6 → 0.22.7
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/dist/common/index.d.ts +39 -4
- package/dist/common/index.js +328 -204
- package/dist/common/index.js.map +1 -1
- package/dist/esm/index.d.mts +39 -4
- package/dist/esm/index.mjs +329 -205
- package/dist/esm/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/esm/index.mjs
CHANGED
|
@@ -2371,11 +2371,82 @@ var worker_config_exports = {};
|
|
|
2371
2371
|
__export(worker_config_exports, {
|
|
2372
2372
|
WorkerConfig: () => WorkerConfig,
|
|
2373
2373
|
get: () => get,
|
|
2374
|
+
getAsync: () => getAsync,
|
|
2374
2375
|
randWorker: () => randWorker,
|
|
2375
2376
|
view: () => view
|
|
2376
2377
|
});
|
|
2377
2378
|
import { AccountAddress, Deserializer as Deserializer10, Network as Network2, Serializer as Serializer11 } from "@aptos-labs/ts-sdk";
|
|
2378
2379
|
import { bytesToHex as bytesToHex10, hexToBytes as hexToBytes5 } from "@noble/curves/utils";
|
|
2380
|
+
|
|
2381
|
+
// src/result.ts
|
|
2382
|
+
var Result = class _Result {
|
|
2383
|
+
isOk;
|
|
2384
|
+
okValue;
|
|
2385
|
+
errValue;
|
|
2386
|
+
extra;
|
|
2387
|
+
constructor({ isOk, okValue, errValue, extra }) {
|
|
2388
|
+
this.isOk = isOk;
|
|
2389
|
+
this.okValue = okValue;
|
|
2390
|
+
this.errValue = errValue;
|
|
2391
|
+
this.extra = extra;
|
|
2392
|
+
}
|
|
2393
|
+
static Ok(args) {
|
|
2394
|
+
return new _Result({ isOk: true, okValue: args.value, extra: args.extra });
|
|
2395
|
+
}
|
|
2396
|
+
static Err(args) {
|
|
2397
|
+
return new _Result({ isOk: false, errValue: args.error, extra: args.extra });
|
|
2398
|
+
}
|
|
2399
|
+
/**
|
|
2400
|
+
* You write a closure that either returns a T or throws, and we wrap it to return a Result<T>.
|
|
2401
|
+
* Your closure is also given an `extra` dictionary to record additional context.
|
|
2402
|
+
*/
|
|
2403
|
+
static capture({ task, recordsExecutionTimeMs = false }) {
|
|
2404
|
+
const start = performance.now();
|
|
2405
|
+
var extra = {};
|
|
2406
|
+
var error;
|
|
2407
|
+
var okValue;
|
|
2408
|
+
try {
|
|
2409
|
+
okValue = task(extra);
|
|
2410
|
+
} catch (caught) {
|
|
2411
|
+
error = caught;
|
|
2412
|
+
} finally {
|
|
2413
|
+
if (recordsExecutionTimeMs) {
|
|
2414
|
+
extra["_sdk_execution_time_ms"] = performance.now() - start;
|
|
2415
|
+
}
|
|
2416
|
+
if (error !== void 0) {
|
|
2417
|
+
return _Result.Err({ error, extra });
|
|
2418
|
+
} else {
|
|
2419
|
+
return _Result.Ok({ value: okValue, extra });
|
|
2420
|
+
}
|
|
2421
|
+
}
|
|
2422
|
+
}
|
|
2423
|
+
/**
|
|
2424
|
+
* You write an async closure that either returns a T or throws, and we wrap it to return a Result<T>.
|
|
2425
|
+
* Your closure is also given an `extra` dictionary to record additional context.
|
|
2426
|
+
*/
|
|
2427
|
+
static async captureAsync({ task, recordsExecutionTimeMs = false }) {
|
|
2428
|
+
var extra = {};
|
|
2429
|
+
const start = performance.now();
|
|
2430
|
+
var error;
|
|
2431
|
+
var okValue;
|
|
2432
|
+
try {
|
|
2433
|
+
okValue = await task(extra);
|
|
2434
|
+
} catch (caught) {
|
|
2435
|
+
error = caught;
|
|
2436
|
+
} finally {
|
|
2437
|
+
if (recordsExecutionTimeMs) {
|
|
2438
|
+
extra["_sdk_execution_time_ms"] = performance.now() - start;
|
|
2439
|
+
}
|
|
2440
|
+
if (error !== void 0) {
|
|
2441
|
+
return _Result.Err({ error, extra });
|
|
2442
|
+
} else {
|
|
2443
|
+
return _Result.Ok({ value: okValue, extra });
|
|
2444
|
+
}
|
|
2445
|
+
}
|
|
2446
|
+
}
|
|
2447
|
+
};
|
|
2448
|
+
|
|
2449
|
+
// src/worker_config.ts
|
|
2379
2450
|
var WorkerConfig = class _WorkerConfig {
|
|
2380
2451
|
expiryTimeMicrosecs;
|
|
2381
2452
|
endpoint;
|
|
@@ -2460,6 +2531,23 @@ async function get(workerEndpoint) {
|
|
|
2460
2531
|
const hex = await response.text();
|
|
2461
2532
|
return WorkerConfig.fromHex(hex);
|
|
2462
2533
|
}
|
|
2534
|
+
async function getAsync(workerEndpoint) {
|
|
2535
|
+
const task = async (extra) => {
|
|
2536
|
+
const url = `${workerEndpoint}/config_bcs`;
|
|
2537
|
+
extra["url"] = url;
|
|
2538
|
+
const response = await fetch(url, {
|
|
2539
|
+
method: "GET"
|
|
2540
|
+
});
|
|
2541
|
+
extra["responseStatus"] = response.status;
|
|
2542
|
+
extra["responseStatusText"] = response.statusText;
|
|
2543
|
+
if (!response.ok) {
|
|
2544
|
+
throw `Failed to fetch worker config: ${response.status} ${response.statusText}`;
|
|
2545
|
+
}
|
|
2546
|
+
const hex = await response.text();
|
|
2547
|
+
return WorkerConfig.fromHex(hex);
|
|
2548
|
+
};
|
|
2549
|
+
return await Result.captureAsync({ task, recordsExecutionTimeMs: true });
|
|
2550
|
+
}
|
|
2463
2551
|
function randWorker() {
|
|
2464
2552
|
const addr = new AccountAddress(utils_exports.randBytes(32));
|
|
2465
2553
|
const encDk = keygen2();
|
|
@@ -2495,7 +2583,7 @@ import { bytesToHex as bytesToHex13, hexToBytes as hexToBytes8 } from "@noble/ha
|
|
|
2495
2583
|
import * as SolanaSDK from "@solana/web3.js";
|
|
2496
2584
|
|
|
2497
2585
|
// src/threshold-ibe/aptos.ts
|
|
2498
|
-
import { AccountAddress as AccountAddress2, AnyPublicKey, AnySignature, Aptos as Aptos2, AptosConfig as AptosConfig2, Deserializer as Deserializer11, Ed25519PublicKey, Ed25519Signature, FederatedKeylessPublicKey, KeylessPublicKey, KeylessSignature, MultiEd25519PublicKey, MultiEd25519Signature, MultiKey, MultiKeySignature, Network as Network3, Serializer as Serializer12 } from "@aptos-labs/ts-sdk";
|
|
2586
|
+
import { AccountAddress as AccountAddress2, AccountPublicKey, AnyPublicKey, AnySignature, Aptos as Aptos2, AptosConfig as AptosConfig2, Deserializer as Deserializer11, Ed25519PublicKey, Ed25519Signature, FederatedKeylessPublicKey, KeylessPublicKey, KeylessSignature, MultiEd25519PublicKey, MultiEd25519Signature, MultiKey, MultiKeySignature, Network as Network3, Serializer as Serializer12 } from "@aptos-labs/ts-sdk";
|
|
2499
2587
|
import { bytesToHex as bytesToHex11, hexToBytes as hexToBytes6 } from "@noble/hashes/utils";
|
|
2500
2588
|
var ContractID = class _ContractID {
|
|
2501
2589
|
chainId;
|
|
@@ -2676,64 +2764,76 @@ var ProofOfPermission = class _ProofOfPermission {
|
|
|
2676
2764
|
}
|
|
2677
2765
|
};
|
|
2678
2766
|
async function verifyPermission({ fullDecryptionDomain, proof }) {
|
|
2679
|
-
const
|
|
2680
|
-
|
|
2767
|
+
const task = async (extra) => {
|
|
2768
|
+
const aptos = createAptos(getChainNameFromChainId(fullDecryptionDomain.getAptosContractID().chainId));
|
|
2769
|
+
const [verifySigResult, checkAuthKeyResult, checkPermissionResult] = await Promise.all([
|
|
2770
|
+
verifySig({ aptos, fullDecryptionDomain, proof }),
|
|
2771
|
+
checkAuthKey({ aptos, userAddr: proof.userAddr, publicKey: proof.publicKey }),
|
|
2772
|
+
checkPermission({ aptos, fullDecryptionDomain, proof })
|
|
2773
|
+
]);
|
|
2774
|
+
extra["verifySigResult"] = verifySigResult;
|
|
2775
|
+
extra["checkAuthKeyResult"] = checkAuthKeyResult;
|
|
2776
|
+
extra["checkPermissionResult"] = checkPermissionResult;
|
|
2777
|
+
if (!verifySigResult.isOk || !checkAuthKeyResult.isOk || !checkPermissionResult.isOk) {
|
|
2778
|
+
throw "one or more sub-checks failed";
|
|
2779
|
+
}
|
|
2780
|
+
};
|
|
2781
|
+
return await Result.captureAsync({ task, recordsExecutionTimeMs: true });
|
|
2782
|
+
}
|
|
2783
|
+
async function verifySig({ aptos, fullDecryptionDomain, proof }) {
|
|
2784
|
+
const task = async (extra) => {
|
|
2681
2785
|
const msgToSign = fullDecryptionDomain.toPrettyMessage();
|
|
2682
2786
|
const msgToSignHex = bytesToHex11(new TextEncoder().encode(msgToSign));
|
|
2683
|
-
const
|
|
2684
|
-
const
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
}
|
|
2787
|
+
const fullMessageSeemsFromPetra = proof.fullMessage.includes(msgToSign);
|
|
2788
|
+
const fullMessageSeemsFromAptosConnect = proof.fullMessage.includes(msgToSignHex);
|
|
2789
|
+
extra["msgToSign"] = msgToSign;
|
|
2790
|
+
extra["msgToSignHex"] = msgToSignHex;
|
|
2791
|
+
extra["fullMessageSeemsFromPetra"] = fullMessageSeemsFromPetra;
|
|
2792
|
+
extra["fullMessageSeemsFromAptosConnect"] = fullMessageSeemsFromAptosConnect;
|
|
2793
|
+
if (!fullMessageSeemsFromPetra && !fullMessageSeemsFromAptosConnect) throw "fullMessage does not contain fullDecryptionDomain or its hex";
|
|
2794
|
+
const sigValid = await proof.publicKey.verifySignatureAsync({
|
|
2795
|
+
aptosConfig: aptos.config,
|
|
2796
|
+
message: proof.fullMessage,
|
|
2797
|
+
signature: proof.signature
|
|
2798
|
+
});
|
|
2799
|
+
if (!sigValid) throw "verifySignatureAsync failed";
|
|
2695
2800
|
};
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
console.log(`onChainHex: ${onChainHex}`);
|
|
2703
|
-
console.log(`userHex : ${userHex}`);
|
|
2704
|
-
return onChainHex === userHex;
|
|
2705
|
-
} catch (error) {
|
|
2706
|
-
return false;
|
|
2801
|
+
return await Result.captureAsync({ task, recordsExecutionTimeMs: true });
|
|
2802
|
+
}
|
|
2803
|
+
async function checkAuthKey({ aptos, userAddr, publicKey }) {
|
|
2804
|
+
const task = async (extra) => {
|
|
2805
|
+
if (!(publicKey instanceof AccountPublicKey)) {
|
|
2806
|
+
throw "publicKey is not an AccountPublicKey";
|
|
2707
2807
|
}
|
|
2808
|
+
const onChainAuthKeyBytes = await getAccountAuthKeyBytes(aptos, userAddr);
|
|
2809
|
+
const userAuthKeyBytes = publicKey.authKey().bcsToBytes();
|
|
2810
|
+
const onChainHex = bytesToHex11(onChainAuthKeyBytes);
|
|
2811
|
+
const userHex = bytesToHex11(userAuthKeyBytes);
|
|
2812
|
+
extra["onChainHex"] = onChainHex;
|
|
2813
|
+
extra["userHex"] = userHex;
|
|
2814
|
+
if (onChainHex !== userHex) throw "on-chain auth key does not match user auth key";
|
|
2708
2815
|
};
|
|
2709
|
-
|
|
2816
|
+
return await Result.captureAsync({ task, recordsExecutionTimeMs: true });
|
|
2817
|
+
}
|
|
2818
|
+
async function checkPermission({ aptos, fullDecryptionDomain, proof }) {
|
|
2819
|
+
const task = async (extra) => {
|
|
2710
2820
|
const contractId = fullDecryptionDomain.getAptosContractID();
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
|
|
2821
|
+
const viewFunctionInvocationResult = await view2({
|
|
2822
|
+
aptos,
|
|
2823
|
+
func: `${contractId.moduleAddr.toStringLong()}::${contractId.moduleName}::${contractId.functionName}`,
|
|
2824
|
+
typeArguments: [],
|
|
2825
|
+
functionArguments: [proof.userAddr, fullDecryptionDomain.domain]
|
|
2826
|
+
});
|
|
2827
|
+
extra["viewFunctionInvocationResult"] = viewFunctionInvocationResult;
|
|
2828
|
+
if (!viewFunctionInvocationResult.isOk) {
|
|
2829
|
+
throw "view function invocation failed";
|
|
2830
|
+
}
|
|
2831
|
+
const returnedMoveValue = viewFunctionInvocationResult.okValue;
|
|
2832
|
+
if (returnedMoveValue?.toString() !== "true") {
|
|
2833
|
+
throw "access control contract return value is not true";
|
|
2721
2834
|
}
|
|
2722
2835
|
};
|
|
2723
|
-
|
|
2724
|
-
taskVerifySig(),
|
|
2725
|
-
taskCheckAuthKey(),
|
|
2726
|
-
taskCheckPermission()
|
|
2727
|
-
]);
|
|
2728
|
-
if (!sigIsValid) {
|
|
2729
|
-
throw new Error("Signature invalid.");
|
|
2730
|
-
}
|
|
2731
|
-
if (!authKeyMatches) {
|
|
2732
|
-
throw new Error("Authentication key mismatch: on-chain key does not match provided public key.");
|
|
2733
|
-
}
|
|
2734
|
-
if (!userIsPermitted) {
|
|
2735
|
-
throw new Error("Permission denied.");
|
|
2736
|
-
}
|
|
2836
|
+
return await Result.captureAsync({ task, recordsExecutionTimeMs: true });
|
|
2737
2837
|
}
|
|
2738
2838
|
function getChainNameFromChainId(chainId) {
|
|
2739
2839
|
if (chainId === 1) {
|
|
@@ -2770,18 +2870,22 @@ async function getAccountAuthKeyBytes(aptos, address) {
|
|
|
2770
2870
|
const accountInfo = await aptos.getAccountInfo({ accountAddress: address });
|
|
2771
2871
|
return hexToBytes6(accountInfo.authentication_key.replace("0x", ""));
|
|
2772
2872
|
}
|
|
2773
|
-
async function view2(aptos, func, typeArguments, functionArguments) {
|
|
2774
|
-
const
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2873
|
+
async function view2({ aptos, func, typeArguments, functionArguments }) {
|
|
2874
|
+
const task = async (extra) => {
|
|
2875
|
+
const returnedMoveValues = await aptos.view({
|
|
2876
|
+
payload: {
|
|
2877
|
+
function: func,
|
|
2878
|
+
typeArguments,
|
|
2879
|
+
functionArguments
|
|
2880
|
+
}
|
|
2881
|
+
});
|
|
2882
|
+
extra["returnedMoveValues"] = returnedMoveValues;
|
|
2883
|
+
if (returnedMoveValues.length === 0) {
|
|
2884
|
+
throw `aptos.view returned an empty list`;
|
|
2779
2885
|
}
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
}
|
|
2784
|
-
return result[0];
|
|
2886
|
+
return returnedMoveValues[0];
|
|
2887
|
+
};
|
|
2888
|
+
return await Result.captureAsync({ task, recordsExecutionTimeMs: true });
|
|
2785
2889
|
}
|
|
2786
2890
|
|
|
2787
2891
|
// src/threshold-ibe/solana.ts
|
|
@@ -2882,76 +2986,107 @@ var ProofOfPermission2 = class _ProofOfPermission {
|
|
|
2882
2986
|
}
|
|
2883
2987
|
};
|
|
2884
2988
|
async function verifyPermission2({ fullDecryptionDomain, proof }) {
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
}
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
instructions = txn.instructions.map((ix) => ({
|
|
2902
|
-
programId: ix.programId,
|
|
2903
|
-
data: Buffer.from(ix.data)
|
|
2904
|
-
}));
|
|
2905
|
-
}
|
|
2906
|
-
if (instructions.length !== 1) {
|
|
2907
|
-
throw new Error(`transaction must contain exactly 1 instruction, found ${instructions.length}`);
|
|
2908
|
-
}
|
|
2909
|
-
const instruction = instructions[0];
|
|
2910
|
-
if (!instruction.programId.equals(fullDecryptionDomain.getSolanaContractID().programId)) {
|
|
2911
|
-
throw new Error(`transaction instruction program ID (${instruction.programId.toString()}) does not match contract program ID`);
|
|
2912
|
-
}
|
|
2913
|
-
const instructionData = instruction.data;
|
|
2914
|
-
if (instructionData.length < 12) {
|
|
2915
|
-
throw new Error("instruction data too short (must be at least 12 bytes: 8-byte discriminator + 4-byte Vec length)");
|
|
2916
|
-
}
|
|
2917
|
-
const paramData = instructionData.slice(8);
|
|
2918
|
-
const vecLength = paramData.readUInt32LE(0);
|
|
2919
|
-
if (paramData.length < 4 + vecLength) {
|
|
2920
|
-
throw new Error(`instruction data incomplete: expected ${4 + vecLength} bytes after discriminator, found ${paramData.length}`);
|
|
2921
|
-
}
|
|
2922
|
-
const fullBlobNameBytes = paramData.slice(4, 4 + vecLength);
|
|
2923
|
-
const expectedParamDataLength = 4 + vecLength;
|
|
2924
|
-
if (paramData.length > expectedParamDataLength) {
|
|
2925
|
-
throw new Error(`instruction data has extra bytes: expected exactly ${expectedParamDataLength} bytes after discriminator, found ${paramData.length}`);
|
|
2989
|
+
var extra = {};
|
|
2990
|
+
try {
|
|
2991
|
+
const txn = proof.inner;
|
|
2992
|
+
const validateTxnResult = validateTxn({ txn, fullDecryptionDomain });
|
|
2993
|
+
if (!validateTxnResult.isOk) {
|
|
2994
|
+
extra["causedBy"] = validateTxnResult.extra;
|
|
2995
|
+
throw "transaction is invalid";
|
|
2996
|
+
}
|
|
2997
|
+
const simulationResult = await assertTransactionSimulationPasses(txn, fullDecryptionDomain.getSolanaContractID().knownChainName);
|
|
2998
|
+
if (!simulationResult.isOk) {
|
|
2999
|
+
extra["causedBy"] = simulationResult.extra;
|
|
3000
|
+
throw "transaction simulation failed";
|
|
3001
|
+
}
|
|
3002
|
+
return Result.Ok({ value: void 0, extra });
|
|
3003
|
+
} catch (error) {
|
|
3004
|
+
return Result.Err({ error, extra });
|
|
2926
3005
|
}
|
|
2927
|
-
|
|
2928
|
-
|
|
3006
|
+
}
|
|
3007
|
+
function validateTxn({ txn, fullDecryptionDomain }) {
|
|
3008
|
+
try {
|
|
3009
|
+
let instructions;
|
|
3010
|
+
if (txn instanceof VersionedTransaction) {
|
|
3011
|
+
const message = txn.message;
|
|
3012
|
+
instructions = message.compiledInstructions.map((ix) => {
|
|
3013
|
+
if (ix.programIdIndex >= message.staticAccountKeys.length) {
|
|
3014
|
+
throw `some program ID index is out of bounds for static account keys (are you using address table lookups? threshold-ibe does not support it yet)`;
|
|
3015
|
+
}
|
|
3016
|
+
const programId = message.staticAccountKeys[ix.programIdIndex];
|
|
3017
|
+
return { programId, data: Buffer.from(ix.data) };
|
|
3018
|
+
});
|
|
3019
|
+
} else {
|
|
3020
|
+
instructions = txn.instructions.map((ix) => ({
|
|
3021
|
+
programId: ix.programId,
|
|
3022
|
+
data: Buffer.from(ix.data)
|
|
3023
|
+
}));
|
|
3024
|
+
}
|
|
3025
|
+
if (instructions.length !== 1) throw `transaction must contain exactly 1 instruction`;
|
|
3026
|
+
const instruction = instructions[0];
|
|
3027
|
+
if (!instruction.programId.equals(fullDecryptionDomain.getSolanaContractID().programId)) {
|
|
3028
|
+
throw `transaction instruction program ID does not match contract program ID`;
|
|
3029
|
+
}
|
|
3030
|
+
const instructionData = instruction.data;
|
|
3031
|
+
if (instructionData.length < 12) {
|
|
3032
|
+
throw "instruction data too short";
|
|
3033
|
+
}
|
|
3034
|
+
const paramData = instructionData.slice(8);
|
|
3035
|
+
const vecLength = paramData.readUInt32LE(0);
|
|
3036
|
+
if (paramData.length < 4 + vecLength) throw `instruction data incomplete`;
|
|
3037
|
+
const domainAsTxnParam = paramData.slice(4, 4 + vecLength);
|
|
3038
|
+
const expectedParamDataLength = 4 + vecLength;
|
|
3039
|
+
if (paramData.length > expectedParamDataLength) {
|
|
3040
|
+
throw `instruction data has extra bytes`;
|
|
3041
|
+
}
|
|
3042
|
+
if (bytesToHex12(domainAsTxnParam) !== bytesToHex12(fullDecryptionDomain.domain)) {
|
|
3043
|
+
throw `instruction parameter does not match decryptionContext.domain`;
|
|
3044
|
+
}
|
|
3045
|
+
return Result.Ok({ value: void 0 });
|
|
3046
|
+
} catch (error) {
|
|
3047
|
+
return Result.Err({ error });
|
|
2929
3048
|
}
|
|
2930
3049
|
}
|
|
2931
3050
|
async function assertTransactionSimulationPasses(txn, chainName) {
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
rpcUrl
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
3051
|
+
var extra = {};
|
|
3052
|
+
var error;
|
|
3053
|
+
const start = performance.now();
|
|
3054
|
+
try {
|
|
3055
|
+
let rpcUrl;
|
|
3056
|
+
if (chainName === "localnet" || chainName === "localhost") {
|
|
3057
|
+
rpcUrl = "http://127.0.0.1:8899";
|
|
3058
|
+
} else if (chainName === "devnet") {
|
|
3059
|
+
rpcUrl = "https://api.devnet.solana.com";
|
|
3060
|
+
} else if (chainName === "testnet") {
|
|
3061
|
+
rpcUrl = "https://api.testnet.solana.com";
|
|
3062
|
+
} else if (chainName === "mainnet-beta") {
|
|
3063
|
+
rpcUrl = "https://api.mainnet-beta.solana.com";
|
|
3064
|
+
} else {
|
|
3065
|
+
extra["chainName"] = chainName;
|
|
3066
|
+
throw `unsupported chain name`;
|
|
3067
|
+
}
|
|
3068
|
+
const connection = new Connection(rpcUrl, "confirmed");
|
|
3069
|
+
let simulation;
|
|
3070
|
+
if (txn instanceof VersionedTransaction) {
|
|
3071
|
+
simulation = await connection.simulateTransaction(txn, {
|
|
3072
|
+
sigVerify: true
|
|
3073
|
+
});
|
|
3074
|
+
} else {
|
|
3075
|
+
simulation = await connection.simulateTransaction(txn);
|
|
3076
|
+
}
|
|
3077
|
+
if (simulation.value.err) {
|
|
3078
|
+
extra["simulationError"] = simulation.value.err;
|
|
3079
|
+
throw `transaction simulation failed`;
|
|
3080
|
+
}
|
|
3081
|
+
} catch (caught) {
|
|
3082
|
+
error = caught;
|
|
3083
|
+
} finally {
|
|
3084
|
+
extra["executionTimeMs"] = performance.now() - start;
|
|
3085
|
+
if (error !== void 0) {
|
|
3086
|
+
return Result.Err({ error, extra });
|
|
3087
|
+
} else {
|
|
3088
|
+
return Result.Ok({ value: void 0, extra });
|
|
3089
|
+
}
|
|
2955
3090
|
}
|
|
2956
3091
|
}
|
|
2957
3092
|
|
|
@@ -3057,11 +3192,16 @@ var EncryptionKey2 = class _EncryptionKey {
|
|
|
3057
3192
|
this.ibeMpks = ibeMpks;
|
|
3058
3193
|
}
|
|
3059
3194
|
static async fetch({ committee }) {
|
|
3060
|
-
const
|
|
3061
|
-
const
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3195
|
+
const task = async (extra) => {
|
|
3196
|
+
const workerConfigGetResults = await Promise.all(committee.workerEndpoints.map(async (endpoint) => {
|
|
3197
|
+
return worker_config_exports.getAsync(endpoint);
|
|
3198
|
+
}));
|
|
3199
|
+
extra["workerConfigGetResults"] = workerConfigGetResults;
|
|
3200
|
+
if (workerConfigGetResults.some((result) => !result.isOk)) throw "failed to get all worker configs";
|
|
3201
|
+
const ibeMpks = workerConfigGetResults.map((result) => result.okValue.ibeMpk);
|
|
3202
|
+
return new _EncryptionKey({ ibeMpks });
|
|
3203
|
+
};
|
|
3204
|
+
return await Result.captureAsync({ task, recordsExecutionTimeMs: true });
|
|
3065
3205
|
}
|
|
3066
3206
|
};
|
|
3067
3207
|
var DecryptionKey2 = class _DecryptionKey {
|
|
@@ -3070,43 +3210,43 @@ var DecryptionKey2 = class _DecryptionKey {
|
|
|
3070
3210
|
this.ibeDecryptionKeys = ibeDecryptionKeys;
|
|
3071
3211
|
}
|
|
3072
3212
|
static async fetch({ committee, contractId, domain, proof }) {
|
|
3073
|
-
const
|
|
3074
|
-
|
|
3213
|
+
const task = async (extra) => {
|
|
3214
|
+
extra["committee"] = committee;
|
|
3215
|
+
const decKeyLoadResults = await Promise.all(committee.workerEndpoints.map(async (_workerEndpoint, index) => {
|
|
3216
|
+
return _DecryptionKey.fetchDecKeyShare({ committee, contractId, domain, proof, index });
|
|
3217
|
+
}));
|
|
3218
|
+
extra["decKeyLoadResults"] = decKeyLoadResults;
|
|
3219
|
+
const numSharesCollected = decKeyLoadResults.filter((loadResult) => loadResult.isOk).length;
|
|
3220
|
+
if (numSharesCollected < committee.threshold) throw `failed to collect enough shares`;
|
|
3221
|
+
const decKeyShares = decKeyLoadResults.map((loadResult) => loadResult.okValue ?? null);
|
|
3222
|
+
return new _DecryptionKey(decKeyShares);
|
|
3223
|
+
};
|
|
3224
|
+
return Result.captureAsync({ task, recordsExecutionTimeMs: true });
|
|
3225
|
+
}
|
|
3226
|
+
static async fetchDecKeyShare({ committee, contractId, domain, proof, index }) {
|
|
3227
|
+
const task = async (extra) => {
|
|
3228
|
+
const targetWorkerEndpoint = committee.workerEndpoints[index];
|
|
3229
|
+
const task2 = WorkerTask.newThresholdIbeDecryptionKey({ committee, contractId, domain, proof });
|
|
3075
3230
|
const controller = new AbortController();
|
|
3076
3231
|
const timeoutId = setTimeout(() => controller.abort(), 5e3);
|
|
3077
3232
|
var response = null;
|
|
3078
3233
|
try {
|
|
3079
|
-
response = await fetch(
|
|
3234
|
+
response = await fetch(targetWorkerEndpoint, {
|
|
3080
3235
|
method: "POST",
|
|
3081
|
-
body:
|
|
3236
|
+
body: task2.toHex(),
|
|
3082
3237
|
signal: controller.signal
|
|
3083
3238
|
});
|
|
3084
3239
|
} catch (error) {
|
|
3085
3240
|
clearTimeout(timeoutId);
|
|
3086
3241
|
}
|
|
3087
|
-
if (response == null)
|
|
3088
|
-
return new WorkerTimedOut();
|
|
3089
|
-
}
|
|
3242
|
+
if (response == null) throw "worker is not responding";
|
|
3090
3243
|
const responseBody = await response.text();
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
|
-
}
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
|
|
3097
|
-
return new CouldNotParseDecryptionKey(responseBody);
|
|
3098
|
-
}
|
|
3099
|
-
}));
|
|
3100
|
-
const numSharesCollected = decKeyLoadResults.filter((loadResult) => loadResult instanceof IdentityPrivateKey2).length;
|
|
3101
|
-
if (numSharesCollected < committee.threshold) {
|
|
3102
|
-
const workerResults = committee.workerEndpoints.map((workerEndpoint, i) => {
|
|
3103
|
-
const result = decKeyLoadResults[i];
|
|
3104
|
-
return `${workerEndpoint}: ${result instanceof IdentityPrivateKey2 ? "Success" : result.toDisplayString()}`;
|
|
3105
|
-
}).join(", ");
|
|
3106
|
-
throw new Error(`Failed to collect enough shares to decrypt. Collected ${numSharesCollected} shares, but needed ${committee.threshold} shares. Worker results: ${workerResults}`);
|
|
3107
|
-
}
|
|
3108
|
-
const decKeys = decKeyLoadResults.map((loadResult) => loadResult instanceof IdentityPrivateKey2 ? loadResult : null);
|
|
3109
|
-
return new _DecryptionKey(decKeys);
|
|
3244
|
+
extra["workerResponseStatus"] = response.status;
|
|
3245
|
+
extra["workerResponseBody"] = responseBody;
|
|
3246
|
+
if (response.status !== 200) throw `worker rejected: ${response.status}`;
|
|
3247
|
+
return IdentityPrivateKey2.fromHex(responseBody);
|
|
3248
|
+
};
|
|
3249
|
+
return Result.captureAsync({ task, recordsExecutionTimeMs: true });
|
|
3110
3250
|
}
|
|
3111
3251
|
};
|
|
3112
3252
|
var Ciphertext7 = class _Ciphertext {
|
|
@@ -3302,41 +3442,25 @@ function decrypt7({ decryptionKey, ciphertext }) {
|
|
|
3302
3442
|
return decrypt6(symmKey, ciphertext.aesCiph);
|
|
3303
3443
|
}
|
|
3304
3444
|
async function verifyAndExtract({ ibeMsk, committee, contractId, domain, proof }) {
|
|
3305
|
-
const
|
|
3306
|
-
|
|
3307
|
-
|
|
3308
|
-
|
|
3309
|
-
|
|
3310
|
-
|
|
3311
|
-
|
|
3312
|
-
|
|
3313
|
-
|
|
3445
|
+
const task = async (extra) => {
|
|
3446
|
+
extra["contractIdScheme"] = contractId.scheme;
|
|
3447
|
+
extra["proofScheme"] = proof.scheme;
|
|
3448
|
+
const decryptionContext = new FullDecryptionDomain({ committee, contractId, domain });
|
|
3449
|
+
if (contractId.scheme == ContractID3.SCHEME_APTOS && proof.scheme == ProofOfPermission3.SCHEME_APTOS) {
|
|
3450
|
+
const aptosResult = await verifyPermission({ fullDecryptionDomain: decryptionContext, proof: proof.inner });
|
|
3451
|
+
extra["verifyAptosResult"] = aptosResult;
|
|
3452
|
+
if (!aptosResult.isOk) throw "aptos verification failed";
|
|
3453
|
+
} else if (contractId.scheme == ContractID3.SCHEME_SOLANA && proof.scheme == ProofOfPermission3.SCHEME_SOLANA) {
|
|
3454
|
+
const solanaResult = await verifyPermission2({ fullDecryptionDomain: decryptionContext, proof: proof.inner });
|
|
3455
|
+
extra["verifySolanaResult"] = solanaResult;
|
|
3456
|
+
if (!solanaResult.isOk) throw "solana verification failed";
|
|
3457
|
+
} else {
|
|
3458
|
+
throw "unsupported scheme combination";
|
|
3459
|
+
}
|
|
3460
|
+
return extract2(ibeMsk, decryptionContext.toBytes());
|
|
3461
|
+
};
|
|
3462
|
+
return Result.captureAsync({ task, recordsExecutionTimeMs: true });
|
|
3314
3463
|
}
|
|
3315
|
-
var WorkerTimedOut = class {
|
|
3316
|
-
toDisplayString() {
|
|
3317
|
-
return "Timed out";
|
|
3318
|
-
}
|
|
3319
|
-
};
|
|
3320
|
-
var WorkerRejected = class {
|
|
3321
|
-
statusCode;
|
|
3322
|
-
responseBody;
|
|
3323
|
-
constructor(statusCode, responseBody) {
|
|
3324
|
-
this.statusCode = statusCode;
|
|
3325
|
-
this.responseBody = responseBody;
|
|
3326
|
-
}
|
|
3327
|
-
toDisplayString() {
|
|
3328
|
-
return `Rejected: ${this.statusCode} ${this.responseBody}`;
|
|
3329
|
-
}
|
|
3330
|
-
};
|
|
3331
|
-
var CouldNotParseDecryptionKey = class {
|
|
3332
|
-
originalHex;
|
|
3333
|
-
constructor(originalHex) {
|
|
3334
|
-
this.originalHex = originalHex;
|
|
3335
|
-
}
|
|
3336
|
-
toDisplayString() {
|
|
3337
|
-
return `Could not parse decryption key: ${this.originalHex}`;
|
|
3338
|
-
}
|
|
3339
|
-
};
|
|
3340
3464
|
|
|
3341
3465
|
// src/worker_task.ts
|
|
3342
3466
|
var TYPE_SILENT_SETUP_DECRYPTION_KEY = 5;
|
|
@@ -3566,16 +3690,16 @@ var DecryptionContext = class _DecryptionContext {
|
|
|
3566
3690
|
clearTimeout(timeoutId);
|
|
3567
3691
|
}
|
|
3568
3692
|
if (response == null) {
|
|
3569
|
-
return new
|
|
3693
|
+
return new WorkerTimedOut();
|
|
3570
3694
|
}
|
|
3571
3695
|
const responseBody = await response.text();
|
|
3572
3696
|
if (response.status !== 200) {
|
|
3573
|
-
return new
|
|
3697
|
+
return new WorkerRejected(response.status, responseBody);
|
|
3574
3698
|
}
|
|
3575
3699
|
try {
|
|
3576
3700
|
return IdentityPrivateKey2.fromHex(responseBody);
|
|
3577
3701
|
} catch (error) {
|
|
3578
|
-
return new
|
|
3702
|
+
return new CouldNotParseDecryptionKey(responseBody);
|
|
3579
3703
|
}
|
|
3580
3704
|
}));
|
|
3581
3705
|
const numSharesCollected = decKeyLoadResults.filter((loadResult) => loadResult instanceof IdentityPrivateKey2).length;
|
|
@@ -3681,12 +3805,12 @@ var Decryptor = class {
|
|
|
3681
3805
|
return decrypt6(symmKey, ciphertext.aesCiph);
|
|
3682
3806
|
}
|
|
3683
3807
|
};
|
|
3684
|
-
var
|
|
3808
|
+
var WorkerTimedOut = class {
|
|
3685
3809
|
toDisplayString() {
|
|
3686
3810
|
return "Timed out";
|
|
3687
3811
|
}
|
|
3688
3812
|
};
|
|
3689
|
-
var
|
|
3813
|
+
var WorkerRejected = class {
|
|
3690
3814
|
statusCode;
|
|
3691
3815
|
responseBody;
|
|
3692
3816
|
constructor(statusCode, responseBody) {
|
|
@@ -3697,7 +3821,7 @@ var WorkerRejected2 = class {
|
|
|
3697
3821
|
return `Rejected: ${this.statusCode} ${this.responseBody}`;
|
|
3698
3822
|
}
|
|
3699
3823
|
};
|
|
3700
|
-
var
|
|
3824
|
+
var CouldNotParseDecryptionKey = class {
|
|
3701
3825
|
originalHex;
|
|
3702
3826
|
constructor(originalHex) {
|
|
3703
3827
|
this.originalHex = originalHex;
|
|
@@ -4261,16 +4385,16 @@ var DecryptionContext2 = class _DecryptionContext {
|
|
|
4261
4385
|
clearTimeout(timeoutId);
|
|
4262
4386
|
}
|
|
4263
4387
|
if (response == null) {
|
|
4264
|
-
return new
|
|
4388
|
+
return new WorkerTimedOut2();
|
|
4265
4389
|
}
|
|
4266
4390
|
const responseBody = await response.text();
|
|
4267
4391
|
if (response.status !== 200) {
|
|
4268
|
-
return new
|
|
4392
|
+
return new WorkerRejected2(response.status, responseBody);
|
|
4269
4393
|
}
|
|
4270
4394
|
try {
|
|
4271
4395
|
return IdentityPrivateKey2.fromHex(responseBody);
|
|
4272
4396
|
} catch (error) {
|
|
4273
|
-
return new
|
|
4397
|
+
return new CouldNotParseDecryptionKey2(responseBody);
|
|
4274
4398
|
}
|
|
4275
4399
|
}));
|
|
4276
4400
|
const numSharesCollected = decKeyLoadResults.filter((loadResult) => loadResult instanceof IdentityPrivateKey2).length;
|
|
@@ -4375,12 +4499,12 @@ var Decryptor2 = class {
|
|
|
4375
4499
|
return decrypt6(symmKey, ciphertext.aesCiph);
|
|
4376
4500
|
}
|
|
4377
4501
|
};
|
|
4378
|
-
var
|
|
4502
|
+
var WorkerTimedOut2 = class {
|
|
4379
4503
|
toDisplayString() {
|
|
4380
4504
|
return "Timed out";
|
|
4381
4505
|
}
|
|
4382
4506
|
};
|
|
4383
|
-
var
|
|
4507
|
+
var WorkerRejected2 = class {
|
|
4384
4508
|
statusCode;
|
|
4385
4509
|
responseBody;
|
|
4386
4510
|
constructor(statusCode, responseBody) {
|
|
@@ -4391,7 +4515,7 @@ var WorkerRejected3 = class {
|
|
|
4391
4515
|
return `Rejected: ${this.statusCode} ${this.responseBody}`;
|
|
4392
4516
|
}
|
|
4393
4517
|
};
|
|
4394
|
-
var
|
|
4518
|
+
var CouldNotParseDecryptionKey2 = class {
|
|
4395
4519
|
originalHex;
|
|
4396
4520
|
constructor(originalHex) {
|
|
4397
4521
|
this.originalHex = originalHex;
|