@openfort/openfort-node 0.7.7 → 0.8.1
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/CHANGELOG.md +12 -0
- package/biome.json +2 -1
- package/dist/index.d.mts +4835 -437
- package/dist/index.d.ts +4835 -437
- package/dist/index.js +929 -124
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +813 -118
- package/dist/index.mjs.map +1 -1
- package/examples/README.md +28 -11
- package/examples/{policies → fee-sponsorship}/createPolicy.ts +2 -2
- package/examples/{policies → fee-sponsorship}/createPolicyRule.ts +3 -3
- package/examples/{policies → fee-sponsorship}/disableEnablePolicy.ts +4 -4
- package/examples/fee-sponsorship/getPolicy.ts +30 -0
- package/examples/fee-sponsorship/listPolicies.ts +17 -0
- package/examples/{policies → fee-sponsorship}/listPolicyRules.ts +4 -4
- package/examples/fee-sponsorship/updatePolicy.ts +29 -0
- package/examples/policies/createAccountPolicy.ts +73 -0
- package/examples/policies/createEvmPolicy.ts +149 -0
- package/examples/policies/createSolanaPolicy.ts +176 -0
- package/examples/policies/createTypedDataPolicy.ts +159 -0
- package/examples/policies/deletePolicy.ts +34 -0
- package/examples/policies/getPolicy.ts +24 -13
- package/examples/policies/listPolicies.ts +19 -2
- package/examples/policies/multiRulePolicy.ts +133 -0
- package/examples/policies/updatePolicy.ts +64 -16
- package/examples/policies/validatePolicy.ts +176 -0
- package/examples/transactions/createTransactionIntent.ts +2 -2
- package/examples/transactions/estimateGas.ts +2 -2
- package/examples/transactions/getTransactionIntent.ts +2 -2
- package/openapi.json +2352 -1142
- package/package.json +4 -3
- package/pnpm-workspace.yaml +1 -0
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
// Usage: npx tsx policies/createTypedDataPolicy.ts
|
|
2
|
+
//
|
|
3
|
+
// Creates policies for EVM typed-data signing (EIP-712) and message signing
|
|
4
|
+
// operations.
|
|
5
|
+
|
|
6
|
+
import Openfort, {
|
|
7
|
+
CreatePolicyBodySchema,
|
|
8
|
+
type CreatePolicyBody,
|
|
9
|
+
} from "@openfort/openfort-node";
|
|
10
|
+
import "dotenv/config";
|
|
11
|
+
|
|
12
|
+
const openfort = new Openfort(process.env.OPENFORT_API_KEY!, {
|
|
13
|
+
basePath: process.env.OPENFORT_BASE_URL,
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
// 1. Restrict typed-data signing to specific verifying contracts
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
|
|
20
|
+
const verifyingContractBody: CreatePolicyBody = {
|
|
21
|
+
scope: "project",
|
|
22
|
+
description: "Only allow signing typed data from known contracts",
|
|
23
|
+
rules: [
|
|
24
|
+
{
|
|
25
|
+
action: "accept",
|
|
26
|
+
operation: "signEvmTypedData",
|
|
27
|
+
criteria: [
|
|
28
|
+
{
|
|
29
|
+
type: "evmTypedDataVerifyingContract",
|
|
30
|
+
operator: "in",
|
|
31
|
+
addresses: [
|
|
32
|
+
"0x000000000000000000000000000000000000dEaD",
|
|
33
|
+
"0x1234567890abcdef1234567890abcdef12345678",
|
|
34
|
+
],
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
CreatePolicyBodySchema.parse(verifyingContractBody);
|
|
42
|
+
|
|
43
|
+
const verifyingPolicy = await openfort.policies.create(
|
|
44
|
+
verifyingContractBody,
|
|
45
|
+
);
|
|
46
|
+
console.log("Created verifying-contract typed-data policy:");
|
|
47
|
+
console.log(" ID:", verifyingPolicy.id);
|
|
48
|
+
|
|
49
|
+
// ---------------------------------------------------------------------------
|
|
50
|
+
// 2. Restrict typed-data field values (e.g. limit order amount)
|
|
51
|
+
// ---------------------------------------------------------------------------
|
|
52
|
+
|
|
53
|
+
const fieldBody: CreatePolicyBody = {
|
|
54
|
+
scope: "project",
|
|
55
|
+
description: "Restrict Order.amount to known values",
|
|
56
|
+
rules: [
|
|
57
|
+
{
|
|
58
|
+
action: "accept",
|
|
59
|
+
operation: "signEvmTypedData",
|
|
60
|
+
criteria: [
|
|
61
|
+
{
|
|
62
|
+
type: "evmTypedDataField",
|
|
63
|
+
operator: "in",
|
|
64
|
+
fieldPath: "Order.amount",
|
|
65
|
+
values: ["100", "200", "500"],
|
|
66
|
+
},
|
|
67
|
+
],
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
CreatePolicyBodySchema.parse(fieldBody);
|
|
73
|
+
|
|
74
|
+
const fieldPolicy = await openfort.policies.create(fieldBody);
|
|
75
|
+
console.log("\nCreated typed-data field restriction policy:");
|
|
76
|
+
console.log(" ID:", fieldPolicy.id);
|
|
77
|
+
|
|
78
|
+
// ---------------------------------------------------------------------------
|
|
79
|
+
// 3. Combined: verifying contract + field constraint
|
|
80
|
+
// ---------------------------------------------------------------------------
|
|
81
|
+
|
|
82
|
+
const combinedBody: CreatePolicyBody = {
|
|
83
|
+
scope: "project",
|
|
84
|
+
description: "Accept orders from known contract with capped amount",
|
|
85
|
+
rules: [
|
|
86
|
+
{
|
|
87
|
+
action: "accept",
|
|
88
|
+
operation: "signEvmTypedData",
|
|
89
|
+
criteria: [
|
|
90
|
+
{
|
|
91
|
+
type: "evmTypedDataVerifyingContract",
|
|
92
|
+
operator: "in",
|
|
93
|
+
addresses: ["0x000000000000000000000000000000000000dEaD"],
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
type: "evmTypedDataField",
|
|
97
|
+
operator: "<=",
|
|
98
|
+
fieldPath: "Order.amount",
|
|
99
|
+
value: "1000",
|
|
100
|
+
},
|
|
101
|
+
],
|
|
102
|
+
},
|
|
103
|
+
],
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
CreatePolicyBodySchema.parse(combinedBody);
|
|
107
|
+
|
|
108
|
+
const combinedPolicy = await openfort.policies.create(combinedBody);
|
|
109
|
+
console.log("\nCreated combined typed-data policy:");
|
|
110
|
+
console.log(" ID:", combinedPolicy.id);
|
|
111
|
+
|
|
112
|
+
// ---------------------------------------------------------------------------
|
|
113
|
+
// 4. EVM message signing — restrict to known pattern
|
|
114
|
+
// ---------------------------------------------------------------------------
|
|
115
|
+
|
|
116
|
+
const messageBody: CreatePolicyBody = {
|
|
117
|
+
scope: "project",
|
|
118
|
+
description: "Only allow signing messages that match the login format",
|
|
119
|
+
rules: [
|
|
120
|
+
{
|
|
121
|
+
action: "accept",
|
|
122
|
+
operation: "signEvmMessage",
|
|
123
|
+
criteria: [
|
|
124
|
+
{
|
|
125
|
+
type: "evmMessage",
|
|
126
|
+
operator: "match",
|
|
127
|
+
pattern: "^Sign in to MyApp: nonce=",
|
|
128
|
+
},
|
|
129
|
+
],
|
|
130
|
+
},
|
|
131
|
+
],
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
CreatePolicyBodySchema.parse(messageBody);
|
|
135
|
+
|
|
136
|
+
const messagePolicy = await openfort.policies.create(messageBody);
|
|
137
|
+
console.log("\nCreated EVM message signing policy:");
|
|
138
|
+
console.log(" ID:", messagePolicy.id);
|
|
139
|
+
|
|
140
|
+
// ---------------------------------------------------------------------------
|
|
141
|
+
// 5. Reject all raw hash signing (no criteria = blanket rule)
|
|
142
|
+
// ---------------------------------------------------------------------------
|
|
143
|
+
|
|
144
|
+
const hashBody: CreatePolicyBody = {
|
|
145
|
+
scope: "project",
|
|
146
|
+
description: "Reject all raw hash signing operations",
|
|
147
|
+
rules: [
|
|
148
|
+
{
|
|
149
|
+
action: "reject",
|
|
150
|
+
operation: "signEvmHash",
|
|
151
|
+
},
|
|
152
|
+
],
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
CreatePolicyBodySchema.parse(hashBody);
|
|
156
|
+
|
|
157
|
+
const hashPolicy = await openfort.policies.create(hashBody);
|
|
158
|
+
console.log("\nCreated hash signing rejection policy:");
|
|
159
|
+
console.log(" ID:", hashPolicy.id);
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// Usage: npx tsx policies/deletePolicy.ts
|
|
2
|
+
|
|
3
|
+
import Openfort, {
|
|
4
|
+
CreatePolicyBodySchema,
|
|
5
|
+
type CreatePolicyBody,
|
|
6
|
+
} from "@openfort/openfort-node";
|
|
7
|
+
import "dotenv/config";
|
|
8
|
+
|
|
9
|
+
const openfort = new Openfort(process.env.OPENFORT_API_KEY!, {
|
|
10
|
+
basePath: process.env.OPENFORT_BASE_URL,
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
// Create a policy to delete
|
|
14
|
+
const body: CreatePolicyBody = {
|
|
15
|
+
scope: "project",
|
|
16
|
+
description: "Temporary policy to be deleted",
|
|
17
|
+
rules: [
|
|
18
|
+
{
|
|
19
|
+
action: "reject",
|
|
20
|
+
operation: "signEvmHash",
|
|
21
|
+
},
|
|
22
|
+
],
|
|
23
|
+
};
|
|
24
|
+
CreatePolicyBodySchema.parse(body);
|
|
25
|
+
|
|
26
|
+
const policy = await openfort.policies.create(body);
|
|
27
|
+
console.log("Created policy:", policy.id);
|
|
28
|
+
|
|
29
|
+
// Delete the policy (soft delete)
|
|
30
|
+
const result = await openfort.policies.delete(policy.id);
|
|
31
|
+
|
|
32
|
+
console.log("\nDeleted policy:");
|
|
33
|
+
console.log(" ID:", result.id);
|
|
34
|
+
console.log(" Deleted:", result.deleted);
|
|
@@ -1,22 +1,29 @@
|
|
|
1
1
|
// Usage: npx tsx policies/getPolicy.ts
|
|
2
2
|
|
|
3
|
-
import Openfort
|
|
3
|
+
import Openfort, {
|
|
4
|
+
CreatePolicyBodySchema,
|
|
5
|
+
type CreatePolicyBody,
|
|
6
|
+
} from "@openfort/openfort-node";
|
|
4
7
|
import "dotenv/config";
|
|
5
8
|
|
|
6
9
|
const openfort = new Openfort(process.env.OPENFORT_API_KEY!, {
|
|
7
10
|
basePath: process.env.OPENFORT_BASE_URL,
|
|
8
11
|
});
|
|
9
12
|
|
|
10
|
-
const chainId = Number(process.env.CHAIN_ID) || 80002;
|
|
11
|
-
|
|
12
13
|
// Create a policy first
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
14
|
+
const body: CreatePolicyBody = {
|
|
15
|
+
scope: "project",
|
|
16
|
+
description: "Test policy to retrieve",
|
|
17
|
+
rules: [
|
|
18
|
+
{
|
|
19
|
+
action: "reject",
|
|
20
|
+
operation: "signEvmHash",
|
|
21
|
+
},
|
|
22
|
+
],
|
|
23
|
+
};
|
|
24
|
+
CreatePolicyBodySchema.parse(body);
|
|
25
|
+
|
|
26
|
+
const created = await openfort.policies.create(body);
|
|
20
27
|
console.log("Created policy:", created.id);
|
|
21
28
|
|
|
22
29
|
// Retrieve the policy by ID
|
|
@@ -24,7 +31,11 @@ const policy = await openfort.policies.get(created.id);
|
|
|
24
31
|
|
|
25
32
|
console.log("\nRetrieved policy:");
|
|
26
33
|
console.log(" ID:", policy.id);
|
|
27
|
-
console.log("
|
|
28
|
-
console.log("
|
|
29
|
-
console.log(" Strategy:", policy.strategy.sponsorSchema);
|
|
34
|
+
console.log(" Scope:", policy.scope);
|
|
35
|
+
console.log(" Description:", policy.description);
|
|
30
36
|
console.log(" Enabled:", policy.enabled);
|
|
37
|
+
console.log(" Priority:", policy.priority);
|
|
38
|
+
console.log(" Rules:");
|
|
39
|
+
for (const rule of policy.rules) {
|
|
40
|
+
console.log(` - Action: ${rule.action}, Operation: ${rule.operation}`);
|
|
41
|
+
}
|
|
@@ -12,6 +12,23 @@ const result = await openfort.policies.list({ limit: 10 });
|
|
|
12
12
|
|
|
13
13
|
console.log(`Found ${result.total} policies:`);
|
|
14
14
|
for (const policy of result.data) {
|
|
15
|
-
console.log(` - ${policy.
|
|
16
|
-
console.log(`
|
|
15
|
+
console.log(` - ${policy.id}`);
|
|
16
|
+
console.log(` Scope: ${policy.scope}`);
|
|
17
|
+
console.log(` Description: ${policy.description ?? "(none)"}`);
|
|
18
|
+
console.log(` Enabled: ${policy.enabled}`);
|
|
19
|
+
console.log(` Rules: ${policy.rules.length}`);
|
|
17
20
|
}
|
|
21
|
+
|
|
22
|
+
// List only project-scoped policies
|
|
23
|
+
console.log("\nProject-scoped policies:");
|
|
24
|
+
const projectPolicies = await openfort.policies.list({
|
|
25
|
+
scope: "project",
|
|
26
|
+
});
|
|
27
|
+
console.log(` Found: ${projectPolicies.total}`);
|
|
28
|
+
|
|
29
|
+
// List only account-scoped policies
|
|
30
|
+
console.log("\nAccount-scoped policies:");
|
|
31
|
+
const accountPolicies = await openfort.policies.list({
|
|
32
|
+
scope: "account",
|
|
33
|
+
});
|
|
34
|
+
console.log(` Found: ${accountPolicies.total}`);
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
// Usage: npx tsx policies/multiRulePolicy.ts
|
|
2
|
+
//
|
|
3
|
+
// Creates a comprehensive policy with multiple rules covering different
|
|
4
|
+
// operations (EVM + Solana) in a single policy.
|
|
5
|
+
|
|
6
|
+
import Openfort, {
|
|
7
|
+
CreatePolicyBodySchema,
|
|
8
|
+
type CreatePolicyBody,
|
|
9
|
+
} from "@openfort/openfort-node";
|
|
10
|
+
import "dotenv/config";
|
|
11
|
+
|
|
12
|
+
const openfort = new Openfort(process.env.OPENFORT_API_KEY!, {
|
|
13
|
+
basePath: process.env.OPENFORT_BASE_URL,
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
const body: CreatePolicyBody = {
|
|
17
|
+
scope: "project",
|
|
18
|
+
description: "Comprehensive cross-chain policy",
|
|
19
|
+
priority: 100,
|
|
20
|
+
rules: [
|
|
21
|
+
// Rule 1: Accept EVM transactions under 1 ETH to known addresses
|
|
22
|
+
{
|
|
23
|
+
action: "accept",
|
|
24
|
+
operation: "signEvmTransaction",
|
|
25
|
+
criteria: [
|
|
26
|
+
{
|
|
27
|
+
type: "ethValue",
|
|
28
|
+
operator: "<=",
|
|
29
|
+
ethValue: "1000000000000000000",
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
type: "evmAddress",
|
|
33
|
+
operator: "in",
|
|
34
|
+
addresses: ["0x000000000000000000000000000000000000dEaD"],
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
// Rule 2: Accept EVM sends on specific networks
|
|
40
|
+
{
|
|
41
|
+
action: "accept",
|
|
42
|
+
operation: "sendEvmTransaction",
|
|
43
|
+
criteria: [
|
|
44
|
+
{
|
|
45
|
+
type: "evmNetwork",
|
|
46
|
+
operator: "in",
|
|
47
|
+
chainIds: [1, 137, 8453], // Ethereum, Polygon, Base
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
type: "ethValue",
|
|
51
|
+
operator: "<=",
|
|
52
|
+
ethValue: "500000000000000000",
|
|
53
|
+
},
|
|
54
|
+
],
|
|
55
|
+
},
|
|
56
|
+
|
|
57
|
+
// Rule 3: Accept EVM message signing matching login pattern
|
|
58
|
+
{
|
|
59
|
+
action: "accept",
|
|
60
|
+
operation: "signEvmMessage",
|
|
61
|
+
criteria: [
|
|
62
|
+
{
|
|
63
|
+
type: "evmMessage",
|
|
64
|
+
operator: "match",
|
|
65
|
+
pattern: "^Sign in to",
|
|
66
|
+
},
|
|
67
|
+
],
|
|
68
|
+
},
|
|
69
|
+
|
|
70
|
+
// Rule 4: Reject all raw hash signing
|
|
71
|
+
{
|
|
72
|
+
action: "reject",
|
|
73
|
+
operation: "signEvmHash",
|
|
74
|
+
},
|
|
75
|
+
|
|
76
|
+
// Rule 5: Accept SOL transfers under 5 SOL to known addresses
|
|
77
|
+
{
|
|
78
|
+
action: "accept",
|
|
79
|
+
operation: "signSolTransaction",
|
|
80
|
+
criteria: [
|
|
81
|
+
{
|
|
82
|
+
type: "solValue",
|
|
83
|
+
operator: "<=",
|
|
84
|
+
value: "5000000000", // 5 SOL
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
type: "solAddress",
|
|
88
|
+
operator: "in",
|
|
89
|
+
addresses: ["DtdSSG8ZJRZVv5Jx7K1MeWp7Zxcu19GD5wQRGRpQ9uMF"],
|
|
90
|
+
},
|
|
91
|
+
],
|
|
92
|
+
},
|
|
93
|
+
|
|
94
|
+
// Rule 6: Accept Solana sends on mainnet only
|
|
95
|
+
{
|
|
96
|
+
action: "accept",
|
|
97
|
+
operation: "sendSolTransaction",
|
|
98
|
+
criteria: [
|
|
99
|
+
{
|
|
100
|
+
type: "solNetwork",
|
|
101
|
+
operator: "in",
|
|
102
|
+
networks: ["mainnet-beta"],
|
|
103
|
+
},
|
|
104
|
+
],
|
|
105
|
+
},
|
|
106
|
+
|
|
107
|
+
// Rule 7: Accept SOL message signing with known prefix
|
|
108
|
+
{
|
|
109
|
+
action: "accept",
|
|
110
|
+
operation: "signSolMessage",
|
|
111
|
+
criteria: [
|
|
112
|
+
{
|
|
113
|
+
type: "solMessage",
|
|
114
|
+
operator: "match",
|
|
115
|
+
pattern: "^Verify ownership:",
|
|
116
|
+
},
|
|
117
|
+
],
|
|
118
|
+
},
|
|
119
|
+
],
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
// Validate locally before sending
|
|
123
|
+
CreatePolicyBodySchema.parse(body);
|
|
124
|
+
|
|
125
|
+
const policy = await openfort.policies.create(body);
|
|
126
|
+
|
|
127
|
+
console.log("Created multi-rule policy:");
|
|
128
|
+
console.log(" ID:", policy.id);
|
|
129
|
+
console.log(" Priority:", policy.priority);
|
|
130
|
+
console.log(" Rules:", policy.rules.length);
|
|
131
|
+
for (const rule of policy.rules) {
|
|
132
|
+
console.log(` - ${rule.action} ${rule.operation}`);
|
|
133
|
+
}
|
|
@@ -1,29 +1,77 @@
|
|
|
1
1
|
// Usage: npx tsx policies/updatePolicy.ts
|
|
2
2
|
|
|
3
|
-
import Openfort
|
|
3
|
+
import Openfort, {
|
|
4
|
+
CreatePolicyBodySchema,
|
|
5
|
+
UpdatePolicyBodySchema,
|
|
6
|
+
type CreatePolicyBody,
|
|
7
|
+
type UpdatePolicyBody,
|
|
8
|
+
} from "@openfort/openfort-node";
|
|
4
9
|
import "dotenv/config";
|
|
5
10
|
|
|
6
11
|
const openfort = new Openfort(process.env.OPENFORT_API_KEY!, {
|
|
7
12
|
basePath: process.env.OPENFORT_BASE_URL,
|
|
8
13
|
});
|
|
9
14
|
|
|
10
|
-
const chainId = Number(process.env.CHAIN_ID) || 80002;
|
|
11
|
-
|
|
12
15
|
// Create a policy first
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
const createBody: CreatePolicyBody = {
|
|
17
|
+
scope: "project",
|
|
18
|
+
description: "Original policy — reject high-value transactions",
|
|
19
|
+
rules: [
|
|
20
|
+
{
|
|
21
|
+
action: "reject",
|
|
22
|
+
operation: "signEvmTransaction",
|
|
23
|
+
criteria: [
|
|
24
|
+
{
|
|
25
|
+
type: "ethValue",
|
|
26
|
+
operator: ">",
|
|
27
|
+
ethValue: "1000000000000000000", // 1 ETH
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
};
|
|
33
|
+
CreatePolicyBodySchema.parse(createBody);
|
|
21
34
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
35
|
+
const policy = await openfort.policies.create(createBody);
|
|
36
|
+
console.log("Created policy:", policy.id);
|
|
37
|
+
console.log(" Description:", policy.description);
|
|
38
|
+
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
// Update the policy — lower the threshold and add an address denylist
|
|
41
|
+
// ---------------------------------------------------------------------------
|
|
42
|
+
|
|
43
|
+
const updateBody: UpdatePolicyBody = {
|
|
44
|
+
description: "Updated — reject high-value or denylist transactions",
|
|
45
|
+
rules: [
|
|
46
|
+
{
|
|
47
|
+
action: "reject",
|
|
48
|
+
operation: "signEvmTransaction",
|
|
49
|
+
criteria: [
|
|
50
|
+
{
|
|
51
|
+
type: "ethValue",
|
|
52
|
+
operator: ">",
|
|
53
|
+
ethValue: "500000000000000000", // 0.5 ETH (lowered)
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
action: "reject",
|
|
59
|
+
operation: "sendEvmTransaction",
|
|
60
|
+
criteria: [
|
|
61
|
+
{
|
|
62
|
+
type: "evmAddress",
|
|
63
|
+
operator: "in",
|
|
64
|
+
addresses: ["0x000000000000000000000000000000000000dEaD"],
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
},
|
|
68
|
+
],
|
|
69
|
+
};
|
|
70
|
+
UpdatePolicyBodySchema.parse(updateBody);
|
|
71
|
+
|
|
72
|
+
const updated = await openfort.policies.update(policy.id, updateBody);
|
|
26
73
|
|
|
27
74
|
console.log("\nUpdated policy:");
|
|
28
75
|
console.log(" ID:", updated.id);
|
|
29
|
-
console.log("
|
|
76
|
+
console.log(" Description:", updated.description);
|
|
77
|
+
console.log(" Rules:", updated.rules.length);
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
// Usage: npx tsx policies/validatePolicy.ts
|
|
2
|
+
//
|
|
3
|
+
// Demonstrates client-side validation of policy bodies using the exported
|
|
4
|
+
// Zod schemas. This catches invalid payloads before they reach the API —
|
|
5
|
+
// no network request required.
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
CreatePolicyBodySchema,
|
|
9
|
+
UpdatePolicyBodySchema,
|
|
10
|
+
type CreatePolicyBody,
|
|
11
|
+
} from "@openfort/openfort-node";
|
|
12
|
+
import { ZodError } from "zod";
|
|
13
|
+
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
// 1. Valid policy — validation passes
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
|
|
18
|
+
const validBody: CreatePolicyBody = {
|
|
19
|
+
scope: "project",
|
|
20
|
+
description: "Reject high-value transactions",
|
|
21
|
+
rules: [
|
|
22
|
+
{
|
|
23
|
+
action: "reject",
|
|
24
|
+
operation: "signEvmTransaction",
|
|
25
|
+
criteria: [
|
|
26
|
+
{
|
|
27
|
+
type: "ethValue",
|
|
28
|
+
operator: ">",
|
|
29
|
+
ethValue: "1000000000000000000",
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
},
|
|
33
|
+
],
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const parsed = CreatePolicyBodySchema.parse(validBody);
|
|
37
|
+
console.log("Valid policy parsed successfully!");
|
|
38
|
+
console.log(" Scope:", parsed.scope);
|
|
39
|
+
console.log(" Rules:", parsed.rules.length);
|
|
40
|
+
|
|
41
|
+
// ---------------------------------------------------------------------------
|
|
42
|
+
// 2. Invalid criterion type — validation fails
|
|
43
|
+
// ---------------------------------------------------------------------------
|
|
44
|
+
|
|
45
|
+
console.log("\n--- Invalid criterion type ---");
|
|
46
|
+
try {
|
|
47
|
+
CreatePolicyBodySchema.parse({
|
|
48
|
+
scope: "project",
|
|
49
|
+
rules: [
|
|
50
|
+
{
|
|
51
|
+
action: "reject",
|
|
52
|
+
operation: "signEvmTransaction",
|
|
53
|
+
criteria: [
|
|
54
|
+
{
|
|
55
|
+
type: "INVALID_TYPE", // not a valid criterion
|
|
56
|
+
operator: ">",
|
|
57
|
+
ethValue: "100",
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
});
|
|
63
|
+
} catch (e) {
|
|
64
|
+
if (e instanceof ZodError) {
|
|
65
|
+
console.log("Caught ZodError:", e.issues[0].message);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// ---------------------------------------------------------------------------
|
|
70
|
+
// 3. Invalid EVM address format — validation fails
|
|
71
|
+
// ---------------------------------------------------------------------------
|
|
72
|
+
|
|
73
|
+
console.log("\n--- Invalid EVM address ---");
|
|
74
|
+
try {
|
|
75
|
+
CreatePolicyBodySchema.parse({
|
|
76
|
+
scope: "project",
|
|
77
|
+
rules: [
|
|
78
|
+
{
|
|
79
|
+
action: "accept",
|
|
80
|
+
operation: "sendEvmTransaction",
|
|
81
|
+
criteria: [
|
|
82
|
+
{
|
|
83
|
+
type: "evmAddress",
|
|
84
|
+
operator: "in",
|
|
85
|
+
addresses: ["not-a-hex-address"], // bad format
|
|
86
|
+
},
|
|
87
|
+
],
|
|
88
|
+
},
|
|
89
|
+
],
|
|
90
|
+
});
|
|
91
|
+
} catch (e) {
|
|
92
|
+
if (e instanceof ZodError) {
|
|
93
|
+
console.log("Caught ZodError:", e.issues[0].message);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// ---------------------------------------------------------------------------
|
|
98
|
+
// 4. Wrong criterion for operation — validation fails
|
|
99
|
+
// ---------------------------------------------------------------------------
|
|
100
|
+
|
|
101
|
+
console.log("\n--- Wrong criterion for operation ---");
|
|
102
|
+
try {
|
|
103
|
+
CreatePolicyBodySchema.parse({
|
|
104
|
+
scope: "project",
|
|
105
|
+
rules: [
|
|
106
|
+
{
|
|
107
|
+
action: "accept",
|
|
108
|
+
operation: "signEvmMessage",
|
|
109
|
+
criteria: [
|
|
110
|
+
{
|
|
111
|
+
type: "ethValue", // ethValue is not valid for signEvmMessage
|
|
112
|
+
operator: ">",
|
|
113
|
+
ethValue: "100",
|
|
114
|
+
},
|
|
115
|
+
],
|
|
116
|
+
},
|
|
117
|
+
],
|
|
118
|
+
});
|
|
119
|
+
} catch (e) {
|
|
120
|
+
if (e instanceof ZodError) {
|
|
121
|
+
console.log("Caught ZodError:", e.issues[0].message);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// ---------------------------------------------------------------------------
|
|
126
|
+
// 5. Missing required fields — validation fails
|
|
127
|
+
// ---------------------------------------------------------------------------
|
|
128
|
+
|
|
129
|
+
console.log("\n--- Missing scope ---");
|
|
130
|
+
try {
|
|
131
|
+
CreatePolicyBodySchema.parse({
|
|
132
|
+
// scope is missing
|
|
133
|
+
rules: [
|
|
134
|
+
{
|
|
135
|
+
action: "reject",
|
|
136
|
+
operation: "signEvmHash",
|
|
137
|
+
},
|
|
138
|
+
],
|
|
139
|
+
});
|
|
140
|
+
} catch (e) {
|
|
141
|
+
if (e instanceof ZodError) {
|
|
142
|
+
console.log("Caught ZodError:", e.issues[0].message);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// ---------------------------------------------------------------------------
|
|
147
|
+
// 6. Validate update body
|
|
148
|
+
// ---------------------------------------------------------------------------
|
|
149
|
+
|
|
150
|
+
console.log("\n--- Valid update body ---");
|
|
151
|
+
const updateParsed = UpdatePolicyBodySchema.parse({
|
|
152
|
+
description: "Updated description",
|
|
153
|
+
enabled: false,
|
|
154
|
+
});
|
|
155
|
+
console.log("Update body parsed successfully!");
|
|
156
|
+
console.log(" Description:", updateParsed.description);
|
|
157
|
+
console.log(" Enabled:", updateParsed.enabled);
|
|
158
|
+
|
|
159
|
+
// ---------------------------------------------------------------------------
|
|
160
|
+
// 7. Too many rules — validation fails
|
|
161
|
+
// ---------------------------------------------------------------------------
|
|
162
|
+
|
|
163
|
+
console.log("\n--- Too many rules (> 10) ---");
|
|
164
|
+
try {
|
|
165
|
+
CreatePolicyBodySchema.parse({
|
|
166
|
+
scope: "project",
|
|
167
|
+
rules: Array.from({ length: 11 }, () => ({
|
|
168
|
+
action: "reject",
|
|
169
|
+
operation: "signEvmHash",
|
|
170
|
+
})),
|
|
171
|
+
});
|
|
172
|
+
} catch (e) {
|
|
173
|
+
if (e instanceof ZodError) {
|
|
174
|
+
console.log("Caught ZodError:", e.issues[0].message);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
@@ -10,7 +10,7 @@ const openfort = new Openfort(process.env.OPENFORT_API_KEY!, {
|
|
|
10
10
|
const chainId = Number(process.env.CHAIN_ID) || 80002;
|
|
11
11
|
|
|
12
12
|
// Create a policy for gas sponsorship
|
|
13
|
-
const policy = await openfort.
|
|
13
|
+
const policy = await openfort.feeSponsorship.create({
|
|
14
14
|
name: `TxPolicy-${Date.now()}`,
|
|
15
15
|
chainId,
|
|
16
16
|
strategy: {
|
|
@@ -27,7 +27,7 @@ const contract = await openfort.contracts.create({
|
|
|
27
27
|
});
|
|
28
28
|
|
|
29
29
|
// Create a policy rule to allow all account functions
|
|
30
|
-
await openfort.
|
|
30
|
+
await openfort.feeSponsorship.rules.create({
|
|
31
31
|
type: "contract_functions",
|
|
32
32
|
functionName: "All functions",
|
|
33
33
|
wildcard: true,
|