@wiimdy/openfunderse-sdk 0.1.1 → 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 +3 -3
- package/dist/attestation-verifier.d.ts +1 -2
- package/dist/attestation-verifier.js +1 -13
- package/dist/canonical.d.ts +2 -2
- package/dist/canonical.js +16 -11
- package/dist/eip712.d.ts +0 -56
- package/dist/eip712.js +0 -33
- package/dist/hash.d.ts +4 -2
- package/dist/hash.js +29 -17
- package/dist/relayer-utils.d.ts +6 -7
- package/dist/relayer-utils.js +29 -12
- package/dist/types.d.ts +12 -21
- package/package.json +4 -2
- package/dist/dist_bak_vercel_repro/attestation-verifier.d.ts +0 -11
- package/dist/dist_bak_vercel_repro/attestation-verifier.js +0 -60
- package/dist/dist_bak_vercel_repro/attestation.d.ts +0 -4
- package/dist/dist_bak_vercel_repro/attestation.js +0 -16
- package/dist/dist_bak_vercel_repro/canonical.d.ts +0 -3
- package/dist/dist_bak_vercel_repro/canonical.js +0 -37
- package/dist/dist_bak_vercel_repro/eip712.d.ts +0 -112
- package/dist/dist_bak_vercel_repro/eip712.js +0 -74
- package/dist/dist_bak_vercel_repro/erc1271.d.ts +0 -4
- package/dist/dist_bak_vercel_repro/erc1271.js +0 -24
- package/dist/dist_bak_vercel_repro/execution-data.d.ts +0 -3
- package/dist/dist_bak_vercel_repro/execution-data.js +0 -66
- package/dist/dist_bak_vercel_repro/hash.d.ts +0 -16
- package/dist/dist_bak_vercel_repro/hash.js +0 -67
- package/dist/dist_bak_vercel_repro/index.d.ts +0 -14
- package/dist/dist_bak_vercel_repro/index.js +0 -14
- package/dist/dist_bak_vercel_repro/nadfun-types.d.ts +0 -29
- package/dist/dist_bak_vercel_repro/nadfun-types.js +0 -1
- package/dist/dist_bak_vercel_repro/ordering.d.ts +0 -5
- package/dist/dist_bak_vercel_repro/ordering.js +0 -22
- package/dist/dist_bak_vercel_repro/relayer-utils.d.ts +0 -29
- package/dist/dist_bak_vercel_repro/relayer-utils.js +0 -108
- package/dist/dist_bak_vercel_repro/scope.d.ts +0 -5
- package/dist/dist_bak_vercel_repro/scope.js +0 -26
- package/dist/dist_bak_vercel_repro/types.d.ts +0 -106
- package/dist/dist_bak_vercel_repro/types.js +0 -1
- package/dist/dist_bak_vercel_repro/validate.d.ts +0 -2
- package/dist/dist_bak_vercel_repro/validate.js +0 -12
- package/dist/dist_bak_vercel_repro/weighted-attestation.d.ts +0 -19
- package/dist/dist_bak_vercel_repro/weighted-attestation.js +0 -62
package/README.md
CHANGED
|
@@ -6,9 +6,9 @@ Claw의 공통 프로토콜 SDK (최소 범위):
|
|
|
6
6
|
- Monorepo canonical utility layer shared by contracts tests, relayer, and agents.
|
|
7
7
|
- Owns protocol hashing/typed-data rules so all components use identical verification logic.
|
|
8
8
|
|
|
9
|
-
- canonical hashing (`
|
|
10
|
-
- EIP-712 attestation typed data + verify/recover
|
|
11
|
-
- weighted threshold 유틸
|
|
9
|
+
- canonical hashing (`allocationClaimHash`, `intentHash`, `snapshotHash`)
|
|
10
|
+
- EIP-712 intent attestation typed data + verify/recover
|
|
11
|
+
- weighted threshold 유틸 (intent verifier set)
|
|
12
12
|
- intent execution route 해시 유틸 (`intentExecutionAllowlistHash`, `intentExecutionCallHash`)
|
|
13
13
|
- NadFun adapter 실행데이터 인코딩/디코딩 (`encodeNadfunExecutionDataV1`)
|
|
14
14
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type IntentAttestationMessage } from "./eip712.js";
|
|
2
2
|
import type { Eip712DomainInput, Hex } from "./types.js";
|
|
3
3
|
export interface VerificationResult {
|
|
4
4
|
ok: boolean;
|
|
@@ -6,6 +6,5 @@ export interface VerificationResult {
|
|
|
6
6
|
recovered?: `0x${string}`;
|
|
7
7
|
error?: string;
|
|
8
8
|
}
|
|
9
|
-
export declare function verifyClaimAttestationEnvelope(domain: Eip712DomainInput, message: ClaimAttestationMessage, signature: Hex): Promise<VerificationResult>;
|
|
10
9
|
export declare function verifyIntentAttestationEnvelope(domain: Eip712DomainInput, message: IntentAttestationMessage, signature: Hex): Promise<VerificationResult>;
|
|
11
10
|
export declare function reachedThreshold(validCount: number, threshold: number): boolean;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { intentAttestationDigest, recoverIntentAttester } from "./eip712.js";
|
|
2
2
|
import { assertNotExpired } from "./attestation.js";
|
|
3
3
|
async function verifyEnvelope(verifier, computeDigest, recoverAddress) {
|
|
4
4
|
try {
|
|
@@ -25,18 +25,6 @@ async function verifyEnvelope(verifier, computeDigest, recoverAddress) {
|
|
|
25
25
|
};
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
|
-
export async function verifyClaimAttestationEnvelope(domain, message, signature) {
|
|
29
|
-
try {
|
|
30
|
-
assertNotExpired(message.expiresAt);
|
|
31
|
-
}
|
|
32
|
-
catch (error) {
|
|
33
|
-
return {
|
|
34
|
-
ok: false,
|
|
35
|
-
error: error instanceof Error ? error.message : String(error)
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
return verifyEnvelope(message.verifier, () => claimAttestationDigest(domain, message), () => recoverClaimAttester(domain, message, signature));
|
|
39
|
-
}
|
|
40
28
|
export async function verifyIntentAttestationEnvelope(domain, message, signature) {
|
|
41
29
|
try {
|
|
42
30
|
assertNotExpired(message.expiresAt);
|
package/dist/canonical.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export declare function
|
|
1
|
+
import type { AllocationClaimV1, TradeIntent } from "./types.js";
|
|
2
|
+
export declare function canonicalAllocationClaim(input: AllocationClaimV1): AllocationClaimV1;
|
|
3
3
|
export declare function canonicalIntent(input: TradeIntent): TradeIntent;
|
package/dist/canonical.js
CHANGED
|
@@ -5,19 +5,24 @@ function normalizeText(value) {
|
|
|
5
5
|
function normalizeAddress(value) {
|
|
6
6
|
return getAddress(value);
|
|
7
7
|
}
|
|
8
|
-
|
|
8
|
+
function normalizeWeights(weights) {
|
|
9
|
+
return weights.map((weight) => {
|
|
10
|
+
if (weight < 0n) {
|
|
11
|
+
throw new Error("targetWeights must be non-negative");
|
|
12
|
+
}
|
|
13
|
+
return weight;
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
export function canonicalAllocationClaim(input) {
|
|
17
|
+
if (input.claimVersion !== "v1") {
|
|
18
|
+
throw new Error(`unsupported claimVersion: ${input.claimVersion}`);
|
|
19
|
+
}
|
|
9
20
|
return {
|
|
10
21
|
...input,
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
extracted: normalizeText(input.extracted),
|
|
16
|
-
extractedType: normalizeText(input.extractedType),
|
|
17
|
-
evidenceType: normalizeText(input.evidenceType),
|
|
18
|
-
evidenceURI: normalizeText(input.evidenceURI),
|
|
19
|
-
crawler: normalizeAddress(input.crawler),
|
|
20
|
-
notes: input.notes === undefined ? undefined : normalizeText(input.notes)
|
|
22
|
+
claimVersion: "v1",
|
|
23
|
+
fundId: normalizeText(input.fundId),
|
|
24
|
+
participant: normalizeAddress(input.participant),
|
|
25
|
+
targetWeights: normalizeWeights(input.targetWeights)
|
|
21
26
|
};
|
|
22
27
|
}
|
|
23
28
|
export function canonicalIntent(input) {
|
package/dist/eip712.d.ts
CHANGED
|
@@ -1,22 +1,4 @@
|
|
|
1
1
|
import type { Address, Eip712DomainInput, Hex } from "./types.js";
|
|
2
|
-
export declare const CLAIM_ATTESTATION_TYPES: {
|
|
3
|
-
readonly ClaimAttestation: readonly [{
|
|
4
|
-
readonly name: "claimHash";
|
|
5
|
-
readonly type: "bytes32";
|
|
6
|
-
}, {
|
|
7
|
-
readonly name: "epochId";
|
|
8
|
-
readonly type: "uint64";
|
|
9
|
-
}, {
|
|
10
|
-
readonly name: "verifier";
|
|
11
|
-
readonly type: "address";
|
|
12
|
-
}, {
|
|
13
|
-
readonly name: "expiresAt";
|
|
14
|
-
readonly type: "uint64";
|
|
15
|
-
}, {
|
|
16
|
-
readonly name: "nonce";
|
|
17
|
-
readonly type: "uint256";
|
|
18
|
-
}];
|
|
19
|
-
};
|
|
20
2
|
export declare const INTENT_ATTESTATION_TYPES: {
|
|
21
3
|
readonly IntentAttestation: readonly [{
|
|
22
4
|
readonly name: "intentHash";
|
|
@@ -32,13 +14,6 @@ export declare const INTENT_ATTESTATION_TYPES: {
|
|
|
32
14
|
readonly type: "uint256";
|
|
33
15
|
}];
|
|
34
16
|
};
|
|
35
|
-
export interface ClaimAttestationMessage {
|
|
36
|
-
claimHash: Hex;
|
|
37
|
-
epochId: bigint;
|
|
38
|
-
verifier: Address;
|
|
39
|
-
expiresAt: bigint;
|
|
40
|
-
nonce: bigint;
|
|
41
|
-
}
|
|
42
17
|
export interface IntentAttestationMessage {
|
|
43
18
|
intentHash: Hex;
|
|
44
19
|
verifier: Address;
|
|
@@ -51,34 +26,6 @@ export declare function toEip712Domain(input: Eip712DomainInput): {
|
|
|
51
26
|
chainId: bigint;
|
|
52
27
|
verifyingContract: `0x${string}`;
|
|
53
28
|
};
|
|
54
|
-
export declare function claimAttestationTypedData(domain: Eip712DomainInput, message: ClaimAttestationMessage): {
|
|
55
|
-
domain: {
|
|
56
|
-
name: string;
|
|
57
|
-
version: string;
|
|
58
|
-
chainId: bigint;
|
|
59
|
-
verifyingContract: `0x${string}`;
|
|
60
|
-
};
|
|
61
|
-
types: {
|
|
62
|
-
readonly ClaimAttestation: readonly [{
|
|
63
|
-
readonly name: "claimHash";
|
|
64
|
-
readonly type: "bytes32";
|
|
65
|
-
}, {
|
|
66
|
-
readonly name: "epochId";
|
|
67
|
-
readonly type: "uint64";
|
|
68
|
-
}, {
|
|
69
|
-
readonly name: "verifier";
|
|
70
|
-
readonly type: "address";
|
|
71
|
-
}, {
|
|
72
|
-
readonly name: "expiresAt";
|
|
73
|
-
readonly type: "uint64";
|
|
74
|
-
}, {
|
|
75
|
-
readonly name: "nonce";
|
|
76
|
-
readonly type: "uint256";
|
|
77
|
-
}];
|
|
78
|
-
};
|
|
79
|
-
primaryType: "ClaimAttestation";
|
|
80
|
-
message: ClaimAttestationMessage;
|
|
81
|
-
};
|
|
82
29
|
export declare function intentAttestationTypedData(domain: Eip712DomainInput, message: IntentAttestationMessage): {
|
|
83
30
|
domain: {
|
|
84
31
|
name: string;
|
|
@@ -104,9 +51,6 @@ export declare function intentAttestationTypedData(domain: Eip712DomainInput, me
|
|
|
104
51
|
primaryType: "IntentAttestation";
|
|
105
52
|
message: IntentAttestationMessage;
|
|
106
53
|
};
|
|
107
|
-
export declare function claimAttestationDigest(domain: Eip712DomainInput, message: ClaimAttestationMessage): Hex;
|
|
108
54
|
export declare function intentAttestationDigest(domain: Eip712DomainInput, message: IntentAttestationMessage): Hex;
|
|
109
|
-
export declare function verifyClaimAttestation(domain: Eip712DomainInput, message: ClaimAttestationMessage, signature: Hex): Promise<boolean>;
|
|
110
55
|
export declare function verifyIntentAttestation(domain: Eip712DomainInput, message: IntentAttestationMessage, signature: Hex): Promise<boolean>;
|
|
111
|
-
export declare function recoverClaimAttester(domain: Eip712DomainInput, message: ClaimAttestationMessage, signature: Hex): Promise<Address>;
|
|
112
56
|
export declare function recoverIntentAttester(domain: Eip712DomainInput, message: IntentAttestationMessage, signature: Hex): Promise<Address>;
|
package/dist/eip712.js
CHANGED
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
import { hashTypedData, recoverTypedDataAddress, verifyTypedData } from "viem";
|
|
2
|
-
export const CLAIM_ATTESTATION_TYPES = {
|
|
3
|
-
ClaimAttestation: [
|
|
4
|
-
{ name: "claimHash", type: "bytes32" },
|
|
5
|
-
{ name: "epochId", type: "uint64" },
|
|
6
|
-
{ name: "verifier", type: "address" },
|
|
7
|
-
{ name: "expiresAt", type: "uint64" },
|
|
8
|
-
{ name: "nonce", type: "uint256" }
|
|
9
|
-
]
|
|
10
|
-
};
|
|
11
2
|
export const INTENT_ATTESTATION_TYPES = {
|
|
12
3
|
IntentAttestation: [
|
|
13
4
|
{ name: "intentHash", type: "bytes32" },
|
|
@@ -24,14 +15,6 @@ export function toEip712Domain(input) {
|
|
|
24
15
|
verifyingContract: input.verifyingContract
|
|
25
16
|
};
|
|
26
17
|
}
|
|
27
|
-
export function claimAttestationTypedData(domain, message) {
|
|
28
|
-
return {
|
|
29
|
-
domain: toEip712Domain(domain),
|
|
30
|
-
types: CLAIM_ATTESTATION_TYPES,
|
|
31
|
-
primaryType: "ClaimAttestation",
|
|
32
|
-
message
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
18
|
export function intentAttestationTypedData(domain, message) {
|
|
36
19
|
return {
|
|
37
20
|
domain: toEip712Domain(domain),
|
|
@@ -40,19 +23,9 @@ export function intentAttestationTypedData(domain, message) {
|
|
|
40
23
|
message
|
|
41
24
|
};
|
|
42
25
|
}
|
|
43
|
-
export function claimAttestationDigest(domain, message) {
|
|
44
|
-
return hashTypedData(claimAttestationTypedData(domain, message));
|
|
45
|
-
}
|
|
46
26
|
export function intentAttestationDigest(domain, message) {
|
|
47
27
|
return hashTypedData(intentAttestationTypedData(domain, message));
|
|
48
28
|
}
|
|
49
|
-
export async function verifyClaimAttestation(domain, message, signature) {
|
|
50
|
-
return verifyTypedData({
|
|
51
|
-
...claimAttestationTypedData(domain, message),
|
|
52
|
-
address: message.verifier,
|
|
53
|
-
signature
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
29
|
export async function verifyIntentAttestation(domain, message, signature) {
|
|
57
30
|
return verifyTypedData({
|
|
58
31
|
...intentAttestationTypedData(domain, message),
|
|
@@ -60,12 +33,6 @@ export async function verifyIntentAttestation(domain, message, signature) {
|
|
|
60
33
|
signature
|
|
61
34
|
});
|
|
62
35
|
}
|
|
63
|
-
export async function recoverClaimAttester(domain, message, signature) {
|
|
64
|
-
return recoverTypedDataAddress({
|
|
65
|
-
...claimAttestationTypedData(domain, message),
|
|
66
|
-
signature
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
36
|
export async function recoverIntentAttester(domain, message, signature) {
|
|
70
37
|
return recoverTypedDataAddress({
|
|
71
38
|
...intentAttestationTypedData(domain, message),
|
package/dist/hash.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import type { Address,
|
|
2
|
-
export declare function
|
|
1
|
+
import type { Address, AllocationClaimV1, Hex, TradeIntent } from "./types.js";
|
|
2
|
+
export declare function allocationClaimHash(claim: AllocationClaimV1): Hex;
|
|
3
3
|
export declare function intentHash(intent: TradeIntent): Hex;
|
|
4
4
|
export declare function snapshotHash(epochId: bigint, orderedClaimHashes: Hex[]): Hex;
|
|
5
5
|
export declare function canonicalOrderedClaimHashes(claimHashes: Hex[]): Hex[];
|
|
6
6
|
export declare function snapshotHashFromUnordered(epochId: bigint, claimHashes: Hex[]): Hex;
|
|
7
|
+
export declare const epochStateHash: typeof snapshotHash;
|
|
8
|
+
export declare const epochStateHashFromUnordered: typeof snapshotHashFromUnordered;
|
|
7
9
|
export declare function reasonHash(reason: string): Hex;
|
|
8
10
|
/**
|
|
9
11
|
* Canonical allowlist hash for intent execution route.
|
package/dist/hash.js
CHANGED
|
@@ -1,23 +1,33 @@
|
|
|
1
1
|
import { encodeAbiParameters, keccak256, parseAbiParameters, toHex } from "viem";
|
|
2
|
-
import {
|
|
2
|
+
import { canonicalAllocationClaim, canonicalIntent } from "./canonical.js";
|
|
3
3
|
import { assertStrictlySortedHex, uniqueSortedBytes32Hex } from "./ordering.js";
|
|
4
4
|
import { assertUint16, assertUint64 } from "./validate.js";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
5
|
+
function assertUint256NonNegative(value, label) {
|
|
6
|
+
if (value < 0n) {
|
|
7
|
+
throw new Error(`${label} must be uint256`);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export function allocationClaimHash(claim) {
|
|
11
|
+
const v = canonicalAllocationClaim(claim);
|
|
12
|
+
assertUint64(v.epochId, "epochId");
|
|
13
|
+
assertUint64(v.horizonSec, "horizonSec");
|
|
14
|
+
assertUint64(v.submittedAt, "submittedAt");
|
|
15
|
+
assertUint256NonNegative(v.nonce, "nonce");
|
|
16
|
+
if (v.targetWeights.length === 0) {
|
|
17
|
+
throw new Error("targetWeights must not be empty");
|
|
18
|
+
}
|
|
19
|
+
v.targetWeights.forEach((weight, idx) => {
|
|
20
|
+
assertUint256NonNegative(weight, `targetWeights[${idx}]`);
|
|
21
|
+
});
|
|
22
|
+
return keccak256(encodeAbiParameters(parseAbiParameters("string claimVersion,string fundId,uint64 epochId,address participant,uint256[] targetWeights,uint64 horizonSec,uint256 nonce,uint64 submittedAt"), [
|
|
23
|
+
v.claimVersion,
|
|
24
|
+
v.fundId,
|
|
25
|
+
v.epochId,
|
|
26
|
+
v.participant,
|
|
27
|
+
v.targetWeights,
|
|
28
|
+
v.horizonSec,
|
|
29
|
+
v.nonce,
|
|
30
|
+
v.submittedAt
|
|
21
31
|
]));
|
|
22
32
|
}
|
|
23
33
|
export function intentHash(intent) {
|
|
@@ -49,6 +59,8 @@ export function snapshotHashFromUnordered(epochId, claimHashes) {
|
|
|
49
59
|
const orderedClaimHashes = canonicalOrderedClaimHashes(claimHashes);
|
|
50
60
|
return snapshotHash(epochId, orderedClaimHashes);
|
|
51
61
|
}
|
|
62
|
+
export const epochStateHash = snapshotHash;
|
|
63
|
+
export const epochStateHashFromUnordered = snapshotHashFromUnordered;
|
|
52
64
|
export function reasonHash(reason) {
|
|
53
65
|
return keccak256(toHex(reason.normalize("NFC").trim()));
|
|
54
66
|
}
|
package/dist/relayer-utils.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export declare function
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
}): CanonicalClaimRecord;
|
|
1
|
+
import type { AllocationClaimV1, CanonicalAllocationClaimRecord, CanonicalIntentRecord, CoreExecutionRequestInput, Hex, IntentExecutionRouteInput, IntentConstraints, TradeIntent } from "./types.js";
|
|
2
|
+
export declare function buildCanonicalAllocationClaimRecord(input: {
|
|
3
|
+
claim: AllocationClaimV1;
|
|
4
|
+
}): CanonicalAllocationClaimRecord;
|
|
6
5
|
export declare function buildIntentConstraints(input: {
|
|
7
6
|
allowlistHash: Hex;
|
|
8
7
|
maxSlippageBps: bigint;
|
|
@@ -15,12 +14,12 @@ export declare function buildCanonicalIntentRecord(input: {
|
|
|
15
14
|
maxNotional: bigint;
|
|
16
15
|
now?: bigint;
|
|
17
16
|
}): CanonicalIntentRecord;
|
|
18
|
-
export declare function
|
|
17
|
+
export declare function buildEpochStateRecord(input: {
|
|
19
18
|
epochId: bigint;
|
|
20
19
|
claimHashes: Hex[];
|
|
21
20
|
}): {
|
|
22
21
|
epochId: bigint;
|
|
23
|
-
|
|
22
|
+
epochStateHash: `0x${string}`;
|
|
24
23
|
};
|
|
25
24
|
export declare function buildIntentAllowlistHashFromRoute(route: IntentExecutionRouteInput): Hex;
|
|
26
25
|
export declare function buildCoreExecutionRequestFromIntent(input: {
|
package/dist/relayer-utils.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { keccak256 } from "viem";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { canonicalAllocationClaim, canonicalIntent } from "./canonical.js";
|
|
3
|
+
import { allocationClaimHash, intentExecutionAllowlistHash, intentHash, snapshotHashFromUnordered } from "./hash.js";
|
|
4
4
|
import { assertUint16, assertUint64 } from "./validate.js";
|
|
5
5
|
function assertPositive(value, label) {
|
|
6
6
|
if (value <= 0n) {
|
|
@@ -12,15 +12,32 @@ function assertHex32(value, label) {
|
|
|
12
12
|
throw new Error(`${label} must be 0x-prefixed 32-byte hex`);
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
function assertWeightsSumPositive(weights) {
|
|
16
|
+
const sum = weights.reduce((acc, w) => acc + w, 0n);
|
|
17
|
+
if (sum <= 0n) {
|
|
18
|
+
throw new Error("targetWeights sum must be positive");
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export function buildCanonicalAllocationClaimRecord(input) {
|
|
22
|
+
assertUint64(input.claim.epochId, "epochId");
|
|
23
|
+
assertUint64(input.claim.horizonSec, "horizonSec");
|
|
24
|
+
assertUint64(input.claim.submittedAt, "submittedAt");
|
|
25
|
+
if (input.claim.nonce < 0n) {
|
|
26
|
+
throw new Error("nonce must be non-negative");
|
|
27
|
+
}
|
|
28
|
+
const claim = canonicalAllocationClaim(input.claim);
|
|
29
|
+
if (claim.targetWeights.length === 0) {
|
|
30
|
+
throw new Error("targetWeights must not be empty");
|
|
31
|
+
}
|
|
32
|
+
claim.targetWeights.forEach((weight, idx) => {
|
|
33
|
+
if (weight < 0n) {
|
|
34
|
+
throw new Error(`targetWeights[${idx}] must be non-negative`);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
assertWeightsSumPositive(claim.targetWeights);
|
|
20
38
|
return {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
claimHash: hash
|
|
39
|
+
claim,
|
|
40
|
+
claimHash: allocationClaimHash(claim)
|
|
24
41
|
};
|
|
25
42
|
}
|
|
26
43
|
export function buildIntentConstraints(input) {
|
|
@@ -56,7 +73,7 @@ export function buildCanonicalIntentRecord(input) {
|
|
|
56
73
|
constraints
|
|
57
74
|
};
|
|
58
75
|
}
|
|
59
|
-
export function
|
|
76
|
+
export function buildEpochStateRecord(input) {
|
|
60
77
|
assertUint64(input.epochId, "epochId");
|
|
61
78
|
if (input.claimHashes.length === 0) {
|
|
62
79
|
throw new Error("claimHashes must not be empty");
|
|
@@ -64,7 +81,7 @@ export function buildCanonicalSnapshotRecord(input) {
|
|
|
64
81
|
const hash = snapshotHashFromUnordered(input.epochId, input.claimHashes);
|
|
65
82
|
return {
|
|
66
83
|
epochId: input.epochId,
|
|
67
|
-
|
|
84
|
+
epochStateHash: hash
|
|
68
85
|
};
|
|
69
86
|
}
|
|
70
87
|
export function buildIntentAllowlistHashFromRoute(route) {
|
package/dist/types.d.ts
CHANGED
|
@@ -1,18 +1,14 @@
|
|
|
1
1
|
export type Hex = `0x${string}`;
|
|
2
2
|
export type Address = `0x${string}`;
|
|
3
|
-
export interface
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
evidenceType: string;
|
|
13
|
-
evidenceURI: string;
|
|
14
|
-
crawler: Address;
|
|
15
|
-
notes?: string;
|
|
3
|
+
export interface AllocationClaimV1 {
|
|
4
|
+
claimVersion: "v1";
|
|
5
|
+
fundId: string;
|
|
6
|
+
epochId: bigint;
|
|
7
|
+
participant: Address;
|
|
8
|
+
targetWeights: bigint[];
|
|
9
|
+
horizonSec: bigint;
|
|
10
|
+
nonce: bigint;
|
|
11
|
+
submittedAt: bigint;
|
|
16
12
|
}
|
|
17
13
|
export interface TradeIntent {
|
|
18
14
|
intentVersion: string;
|
|
@@ -38,16 +34,12 @@ export interface ProtocolScope {
|
|
|
38
34
|
roomId: string;
|
|
39
35
|
epochId: bigint;
|
|
40
36
|
}
|
|
41
|
-
export type SubjectType = "
|
|
37
|
+
export type SubjectType = "INTENT";
|
|
42
38
|
export interface AttestationMeta {
|
|
43
39
|
verifier: Address;
|
|
44
40
|
expiresAt: bigint;
|
|
45
41
|
nonce: bigint;
|
|
46
42
|
}
|
|
47
|
-
export interface ClaimAttestationDraft extends AttestationMeta {
|
|
48
|
-
claimHash: Hex;
|
|
49
|
-
epochId: bigint;
|
|
50
|
-
}
|
|
51
43
|
export interface IntentAttestationDraft extends AttestationMeta {
|
|
52
44
|
intentHash: Hex;
|
|
53
45
|
}
|
|
@@ -94,9 +86,8 @@ export interface CoreExecutionRequestInput {
|
|
|
94
86
|
adapter: Address;
|
|
95
87
|
adapterData: Hex;
|
|
96
88
|
}
|
|
97
|
-
export interface
|
|
98
|
-
|
|
99
|
-
epochId: bigint;
|
|
89
|
+
export interface CanonicalAllocationClaimRecord {
|
|
90
|
+
claim: AllocationClaimV1;
|
|
100
91
|
claimHash: Hex;
|
|
101
92
|
}
|
|
102
93
|
export interface CanonicalIntentRecord {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wiimdy/openfunderse-sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Canonical hashing and EIP-712 helpers for Claw protocol components.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -17,11 +17,13 @@
|
|
|
17
17
|
"README.md"
|
|
18
18
|
],
|
|
19
19
|
"scripts": {
|
|
20
|
+
"prebuild": "npm run clean",
|
|
20
21
|
"build": "tsc -p tsconfig.json",
|
|
21
22
|
"clean": "rm -rf dist",
|
|
22
23
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
23
24
|
"test": "npm run build && node --test test/**/*.test.mjs",
|
|
24
|
-
"intent:compute:nadfun": "npm run build && node scripts/compute-nadfun-intent.mjs"
|
|
25
|
+
"intent:compute:nadfun": "npm run build && node scripts/compute-nadfun-intent.mjs",
|
|
26
|
+
"prepublishOnly": "npm run build"
|
|
25
27
|
},
|
|
26
28
|
"dependencies": {
|
|
27
29
|
"viem": "^2.38.2"
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { type ClaimAttestationMessage, type IntentAttestationMessage } from "./eip712.js";
|
|
2
|
-
import type { Eip712DomainInput, Hex } from "./types.js";
|
|
3
|
-
export interface VerificationResult {
|
|
4
|
-
ok: boolean;
|
|
5
|
-
digest?: Hex;
|
|
6
|
-
recovered?: `0x${string}`;
|
|
7
|
-
error?: string;
|
|
8
|
-
}
|
|
9
|
-
export declare function verifyClaimAttestationEnvelope(domain: Eip712DomainInput, message: ClaimAttestationMessage, signature: Hex): Promise<VerificationResult>;
|
|
10
|
-
export declare function verifyIntentAttestationEnvelope(domain: Eip712DomainInput, message: IntentAttestationMessage, signature: Hex): Promise<VerificationResult>;
|
|
11
|
-
export declare function reachedThreshold(validCount: number, threshold: number): boolean;
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { claimAttestationDigest, intentAttestationDigest, recoverClaimAttester, recoverIntentAttester } from "./eip712.js";
|
|
2
|
-
import { assertNotExpired } from "./attestation.js";
|
|
3
|
-
async function verifyEnvelope(verifier, computeDigest, recoverAddress) {
|
|
4
|
-
try {
|
|
5
|
-
const digest = computeDigest();
|
|
6
|
-
const recovered = await recoverAddress();
|
|
7
|
-
if (recovered.toLowerCase() !== verifier.toLowerCase()) {
|
|
8
|
-
return {
|
|
9
|
-
ok: false,
|
|
10
|
-
digest,
|
|
11
|
-
recovered,
|
|
12
|
-
error: "signature does not recover claimed verifier"
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
return {
|
|
16
|
-
ok: true,
|
|
17
|
-
digest,
|
|
18
|
-
recovered
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
catch (error) {
|
|
22
|
-
return {
|
|
23
|
-
ok: false,
|
|
24
|
-
error: error instanceof Error ? error.message : String(error)
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
export async function verifyClaimAttestationEnvelope(domain, message, signature) {
|
|
29
|
-
try {
|
|
30
|
-
assertNotExpired(message.expiresAt);
|
|
31
|
-
}
|
|
32
|
-
catch (error) {
|
|
33
|
-
return {
|
|
34
|
-
ok: false,
|
|
35
|
-
error: error instanceof Error ? error.message : String(error)
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
return verifyEnvelope(message.verifier, () => claimAttestationDigest(domain, message), () => recoverClaimAttester(domain, message, signature));
|
|
39
|
-
}
|
|
40
|
-
export async function verifyIntentAttestationEnvelope(domain, message, signature) {
|
|
41
|
-
try {
|
|
42
|
-
assertNotExpired(message.expiresAt);
|
|
43
|
-
}
|
|
44
|
-
catch (error) {
|
|
45
|
-
return {
|
|
46
|
-
ok: false,
|
|
47
|
-
error: error instanceof Error ? error.message : String(error)
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
return verifyEnvelope(message.verifier, () => intentAttestationDigest(domain, message), () => recoverIntentAttester(domain, message, signature));
|
|
51
|
-
}
|
|
52
|
-
export function reachedThreshold(validCount, threshold) {
|
|
53
|
-
if (!Number.isInteger(validCount) || validCount < 0) {
|
|
54
|
-
throw new Error("validCount must be a non-negative integer");
|
|
55
|
-
}
|
|
56
|
-
if (!Number.isInteger(threshold) || threshold <= 0) {
|
|
57
|
-
throw new Error("threshold must be a positive integer");
|
|
58
|
-
}
|
|
59
|
-
return validCount >= threshold;
|
|
60
|
-
}
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
export declare function unixNow(): bigint;
|
|
2
|
-
export declare function isExpired(expiresAt: bigint, now?: bigint): boolean;
|
|
3
|
-
export declare function assertNotExpired(expiresAt: bigint, now?: bigint): void;
|
|
4
|
-
export declare function assertNonceStrictlyIncreases(lastNonce: bigint | null, incomingNonce: bigint): void;
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
export function unixNow() {
|
|
2
|
-
return BigInt(Math.floor(Date.now() / 1000));
|
|
3
|
-
}
|
|
4
|
-
export function isExpired(expiresAt, now = unixNow()) {
|
|
5
|
-
return expiresAt <= now;
|
|
6
|
-
}
|
|
7
|
-
export function assertNotExpired(expiresAt, now = unixNow()) {
|
|
8
|
-
if (isExpired(expiresAt, now)) {
|
|
9
|
-
throw new Error(`signature expired: expiresAt=${expiresAt.toString(10)}, now=${now.toString(10)}`);
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
export function assertNonceStrictlyIncreases(lastNonce, incomingNonce) {
|
|
13
|
-
if (lastNonce !== null && incomingNonce <= lastNonce) {
|
|
14
|
-
throw new Error(`nonce must strictly increase: last=${lastNonce.toString(10)}, incoming=${incomingNonce.toString(10)}`);
|
|
15
|
-
}
|
|
16
|
-
}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { getAddress } from "viem";
|
|
2
|
-
function normalizeText(value) {
|
|
3
|
-
return value.normalize("NFC").trim();
|
|
4
|
-
}
|
|
5
|
-
function normalizeAddress(value) {
|
|
6
|
-
return getAddress(value);
|
|
7
|
-
}
|
|
8
|
-
export function canonicalClaim(input) {
|
|
9
|
-
return {
|
|
10
|
-
...input,
|
|
11
|
-
schemaId: normalizeText(input.schemaId),
|
|
12
|
-
sourceType: normalizeText(input.sourceType),
|
|
13
|
-
sourceRef: normalizeText(input.sourceRef),
|
|
14
|
-
selector: normalizeText(input.selector),
|
|
15
|
-
extracted: normalizeText(input.extracted),
|
|
16
|
-
extractedType: normalizeText(input.extractedType),
|
|
17
|
-
evidenceType: normalizeText(input.evidenceType),
|
|
18
|
-
evidenceURI: normalizeText(input.evidenceURI),
|
|
19
|
-
crawler: normalizeAddress(input.crawler),
|
|
20
|
-
notes: input.notes === undefined ? undefined : normalizeText(input.notes)
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
|
-
export function canonicalIntent(input) {
|
|
24
|
-
const normalizedAction = normalizeText(input.action).toUpperCase();
|
|
25
|
-
if (normalizedAction !== "BUY" && normalizedAction !== "SELL") {
|
|
26
|
-
throw new Error(`invalid action: ${input.action}`);
|
|
27
|
-
}
|
|
28
|
-
return {
|
|
29
|
-
...input,
|
|
30
|
-
intentVersion: normalizeText(input.intentVersion),
|
|
31
|
-
vault: normalizeAddress(input.vault),
|
|
32
|
-
action: normalizedAction,
|
|
33
|
-
tokenIn: normalizeAddress(input.tokenIn),
|
|
34
|
-
tokenOut: normalizeAddress(input.tokenOut),
|
|
35
|
-
reason: input.reason === undefined ? undefined : normalizeText(input.reason)
|
|
36
|
-
};
|
|
37
|
-
}
|