@openfort/openfort-node 0.9.3 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/index.d.mts +274 -84
  3. package/dist/index.d.ts +274 -84
  4. package/dist/index.js +423 -35
  5. package/dist/index.js.map +1 -1
  6. package/dist/index.mjs +423 -45
  7. package/dist/index.mjs.map +1 -1
  8. package/examples/evm/policies/createAccountPolicy.ts +68 -0
  9. package/examples/evm/policies/createProjectPolicy.ts +53 -0
  10. package/examples/evm/policies/deletePolicy.ts +34 -0
  11. package/examples/evm/policies/getPolicyById.ts +34 -0
  12. package/examples/evm/policies/listAccountPolicies.ts +11 -0
  13. package/examples/evm/policies/listPolicies.ts +11 -0
  14. package/examples/evm/policies/listProjectPolicies.ts +11 -0
  15. package/examples/evm/policies/signTypedDataPolicy.ts +35 -0
  16. package/examples/evm/policies/updatePolicy.ts +44 -0
  17. package/examples/evm/policies/validation.ts +45 -0
  18. package/examples/evm/transactions/sendTransaction.ts +44 -0
  19. package/examples/package.json +13 -0
  20. package/examples/pnpm-lock.yaml +933 -0
  21. package/examples/solana/policies/createSolAllowlistPolicy.ts +27 -0
  22. package/examples/solana/policies/createSolMessagePolicy.ts +29 -0
  23. package/examples/solana/policies/createSplTokenLimitsPolicy.ts +33 -0
  24. package/examples/solana/transactions/sendRawTransaction.ts +23 -0
  25. package/examples/solana/transactions/sendTransaction.ts +37 -0
  26. package/examples/solana/transactions/transfer.ts +44 -0
  27. package/knip.json +10 -1
  28. package/package.json +42 -4
  29. package/tsconfig.json +2 -3
  30. package/examples/policies/createAccountPolicy.ts +0 -71
  31. package/examples/policies/createEvmPolicy.ts +0 -149
  32. package/examples/policies/createSolanaPolicy.ts +0 -176
  33. package/examples/policies/createTypedDataPolicy.ts +0 -159
  34. package/examples/policies/deletePolicy.ts +0 -34
  35. package/examples/policies/getPolicy.ts +0 -41
  36. package/examples/policies/listPolicies.ts +0 -34
  37. package/examples/policies/multiRulePolicy.ts +0 -133
  38. package/examples/policies/updatePolicy.ts +0 -77
  39. package/examples/policies/validatePolicy.ts +0 -176
  40. /package/examples/{contracts → evm/contracts}/createContract.ts +0 -0
  41. /package/examples/{contracts → evm/contracts}/listContracts.ts +0 -0
  42. /package/examples/{transactions → evm/transactionIntents}/createTransactionIntent.ts +0 -0
  43. /package/examples/{transactions → evm/transactionIntents}/estimateGas.ts +0 -0
  44. /package/examples/{transactions → evm/transactionIntents}/getTransactionIntent.ts +0 -0
  45. /package/examples/{transactions → evm/transactionIntents}/listTransactionIntents.ts +0 -0
@@ -0,0 +1,27 @@
1
+ // Usage: pnpm tsx solana/policies/createSolAllowlistPolicy.ts
2
+
3
+ import Openfort from "@openfort/openfort-node";
4
+ import "dotenv/config";
5
+
6
+ const openfort = new Openfort(process.env.OPENFORT_API_KEY!, {
7
+ basePath: process.env.OPENFORT_BASE_URL,
8
+ });
9
+
10
+ const policy = await openfort.policies.create({
11
+ scope: "account",
12
+ description: "SOL Allowlist Policy",
13
+ rules: [
14
+ {
15
+ action: "accept",
16
+ operation: "signSolTransaction",
17
+ criteria: [
18
+ {
19
+ type: "solAddress",
20
+ addresses: ["DtdSSG8ZJRZVv5Jx7K1MeWp7Zxcu19GD5wQRGRpQ9uMF"],
21
+ operator: "in",
22
+ },
23
+ ],
24
+ },
25
+ ],
26
+ });
27
+ console.log("Created sol allowlist policy: ", policy.id);
@@ -0,0 +1,29 @@
1
+ // Usage: pnpm tsx solana/policies/createSolMessagePolicy.ts
2
+
3
+ import Openfort from "@openfort/openfort-node";
4
+ import "dotenv/config";
5
+
6
+ const openfort = new Openfort(process.env.OPENFORT_API_KEY!, {
7
+ basePath: process.env.OPENFORT_BASE_URL,
8
+ });
9
+
10
+ // Create a policy that only allows signing messages starting with "Openfort:"
11
+ const policy = await openfort.policies.create({
12
+ scope: "account",
13
+ description: "Allow messages with Openfort prefix only",
14
+ rules: [
15
+ {
16
+ action: "accept",
17
+ operation: "signSolMessage",
18
+ criteria: [
19
+ {
20
+ type: "solMessage",
21
+ operator: "match",
22
+ pattern: "^Openfort:.*",
23
+ },
24
+ ],
25
+ },
26
+ ],
27
+ });
28
+
29
+ console.log("Created sol message policy: ", policy.id);
@@ -0,0 +1,33 @@
1
+ // Usage: pnpm tsx solana/policies/createSplTokenLimitsPolicy.ts
2
+
3
+ import Openfort from "@openfort/openfort-node";
4
+ import "dotenv/config";
5
+
6
+ const openfort = new Openfort(process.env.OPENFORT_API_KEY!, {
7
+ basePath: process.env.OPENFORT_BASE_URL,
8
+ });
9
+
10
+ // Create a policy that allows sending up to 1 USDC on Solana devnet
11
+ const policy = await openfort.policies.create({
12
+ scope: "account",
13
+ description: "SPL Token Limits Policy",
14
+ rules: [
15
+ {
16
+ action: "accept",
17
+ operation: "sendSolTransaction",
18
+ criteria: [
19
+ {
20
+ type: "splValue",
21
+ value: "1000000",
22
+ operator: "<=",
23
+ },
24
+ {
25
+ type: "mintAddress",
26
+ addresses: ["4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU"],
27
+ operator: "in",
28
+ },
29
+ ],
30
+ },
31
+ ],
32
+ });
33
+ console.log("Created spl token limits policy: ", policy.id);
@@ -0,0 +1,23 @@
1
+ // Usage: pnpm tsx solana/transactions/sendRawTransaction.ts
2
+
3
+ import Openfort from "@openfort/openfort-node";
4
+ import "dotenv/config";
5
+
6
+ const openfort = new Openfort(process.env.OPENFORT_API_KEY!, {
7
+ basePath: process.env.OPENFORT_BASE_URL,
8
+ walletSecret: process.env.OPENFORT_WALLET_SECRET,
9
+ publishableKey: process.env.OPENFORT_PUBLISHABLE_KEY,
10
+ });
11
+
12
+ const account = await openfort.accounts.solana.backend.get({
13
+ address: "o24A5URLU3JNKg7AoeUrPsfsAo1NQeeAB4uQViAkpjq",
14
+ });
15
+ console.log("Solana account:", account.address);
16
+
17
+ const base64Transaction = "AgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAIAAgVNIUjL89213czrp82aA7pwQtVnJ433tRk70i1jD6x8RgvJ6NInwPBPRE1nsK0uFlw4un64nQPWoQ5z6rMgnEa401TyQ9UGEEZNtkD5WCpVzr4hzSQjxMXpK3bGAFWS+d8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMGRm/lIRcy/+ytunLDm+e8jOW7xfcSayxDmzpAAAAALajv1ShJYnJUlo8NjFHgtGjF+2MgsBy4LMtqcDvTyfUDBAAJA0BCDwAAAAAABAAFAkANAwADAgECDAIAAAAKAAAAAAAAAAA=";
18
+
19
+ const result = await account.sendRawTransaction({
20
+ cluster: "devnet",
21
+ transaction: base64Transaction,
22
+ });
23
+ console.log("Transaction signature:", result.signature);
@@ -0,0 +1,37 @@
1
+ // Usage: pnpm tsx solana/transactions/sendTransaction.ts
2
+ //
3
+ // Low-level example using raw instructions.
4
+ // For simple transfers, see solana/transfer.ts instead.
5
+
6
+ import Openfort from "@openfort/openfort-node";
7
+ import { getTransferSolInstruction } from "@solana-program/system";
8
+ import { address, createNoopSigner } from "@solana/kit";
9
+ import "dotenv/config";
10
+
11
+ const openfort = new Openfort(process.env.OPENFORT_API_KEY!, {
12
+ basePath: process.env.OPENFORT_BASE_URL,
13
+ walletSecret: process.env.OPENFORT_WALLET_SECRET,
14
+ publishableKey: process.env.OPENFORT_PUBLISHABLE_KEY,
15
+ });
16
+
17
+ const account = await openfort.accounts.solana.backend.get({
18
+ address: "o24A5URLU3JNKg7AoeUrPsfsAo1NQeeAB4uQViAkpjq",
19
+ });
20
+ console.log("Solana account:", account.address);
21
+
22
+ const DESTINATION = address("FDx9mfVqTvXUaSPQDELwDtGgMqxirmAFsEK2s4YsKfsc");
23
+
24
+ // Build a raw SOL transfer instruction
25
+ const solTransferIx = getTransferSolInstruction({
26
+ source: createNoopSigner(address(account.address)),
27
+ destination: DESTINATION,
28
+ amount: 10n,
29
+ });
30
+
31
+
32
+ const result = await openfort.accounts.solana.backend.sendTransaction({
33
+ account,
34
+ cluster: "devnet",
35
+ instructions: [solTransferIx],
36
+ });
37
+ console.log("Transaction signature:", result.signature);
@@ -0,0 +1,44 @@
1
+ // Usage: pnpm tsx solana/transactions/transfer.ts
2
+
3
+ import Openfort from "@openfort/openfort-node";
4
+ import "dotenv/config";
5
+
6
+ const openfort = new Openfort(process.env.OPENFORT_API_KEY!, {
7
+ basePath: process.env.OPENFORT_BASE_URL,
8
+ walletSecret: process.env.OPENFORT_WALLET_SECRET,
9
+ publishableKey: process.env.OPENFORT_PUBLISHABLE_KEY,
10
+ });
11
+
12
+ // Prefunded devnet account with some SOL and USDC for testing transfers
13
+ const account = await openfort.accounts.solana.backend.get({
14
+ address: "o24A5URLU3JNKg7AoeUrPsfsAo1NQeeAB4uQViAkpjq",
15
+ });
16
+ console.log("Solana account:", account.address);
17
+
18
+ const DEST = "FDx9mfVqTvXUaSPQDELwDtGgMqxirmAFsEK2s4YsKfsc";
19
+
20
+ // --- Example 1: SOL transfer ---
21
+ const solResult = await account.transfer({
22
+ to: DEST,
23
+ amount: 1_000_000n,
24
+ cluster: "devnet",
25
+ });
26
+ console.log("SOL transfer signature:", solResult.signature);
27
+
28
+ // --- Example 2: USDC transfer by name ---
29
+ const usdcResult = await account.transfer({
30
+ to: DEST,
31
+ amount: 1_000_000n,
32
+ token: "usdc",
33
+ cluster: "devnet",
34
+ });
35
+ console.log("USDC transfer signature:", usdcResult.signature);
36
+
37
+ // --- Example 3: SPL transfer by mint address ---
38
+ const splResult = await account.transfer({
39
+ to: DEST,
40
+ amount: 2_000_000n,
41
+ token: "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU",
42
+ cluster: "devnet",
43
+ });
44
+ console.log("SPL transfer signature:", splResult.signature);
package/knip.json CHANGED
@@ -2,5 +2,14 @@
2
2
  "$schema": "https://unpkg.com/knip@latest/schema.json",
3
3
  "entry": ["src/index.ts!"],
4
4
  "project": ["src/**/*.ts!"],
5
- "ignore": ["example/**"]
5
+ "ignore": ["example/**"],
6
+ "ignoreDependencies": [
7
+ "@solana-program/compute-budget",
8
+ "@solana-program/system",
9
+ "@solana-program/token",
10
+ "@solana/kit",
11
+ "@solana/kora",
12
+ "@solana/transaction-confirmation",
13
+ "viem"
14
+ ]
6
15
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openfort/openfort-node",
3
- "version": "0.9.3",
3
+ "version": "0.10.0",
4
4
  "description": "Openfort Node SDK",
5
5
  "author": "Openfort",
6
6
  "repository": {
@@ -40,24 +40,29 @@
40
40
  },
41
41
  "dependencies": {
42
42
  "@openfort/shield-js": "^0.1.35",
43
- "@types/node": "^25.3.2",
44
- "@types/node-fetch": "^2.6.13",
45
43
  "axios": "^1.13.6",
46
44
  "axios-retry": "^4.5.0",
47
45
  "bs58": "^6.0.0",
48
46
  "jose": "^5.10.0",
49
47
  "node-fetch": "^2.7.0",
50
- "viem": "^2.46.3",
51
48
  "zod": "^3.25.76"
52
49
  },
53
50
  "simple-git-hooks": {
54
51
  "pre-commit": "pnpm check"
55
52
  },
56
53
  "devDependencies": {
54
+ "@types/node": "^25.3.2",
55
+ "@types/node-fetch": "^2.6.13",
57
56
  "@arethetypeswrong/cli": "^0.18.2",
58
57
  "@biomejs/biome": "^2.4.4",
59
58
  "@changesets/changelog-github": "^0.5.2",
60
59
  "@changesets/cli": "^2.29.8",
60
+ "@solana-program/compute-budget": "^0.14.0",
61
+ "@solana-program/system": "^0.12.0",
62
+ "@solana-program/token": "^0.12.0",
63
+ "@solana/kit": "^6.1.0",
64
+ "@solana/kora": "^0.1.3",
65
+ "@solana/transaction-confirmation": "^6.1.0",
61
66
  "@vitest/coverage-v8": "^3.2.4",
62
67
  "knip": "^5.85.0",
63
68
  "orval": "^8.5.1",
@@ -65,8 +70,41 @@
65
70
  "simple-git-hooks": "^2.13.1",
66
71
  "tsup": "^8.5.1",
67
72
  "typescript": "^5.9.3",
73
+ "viem": "^2.46.3",
68
74
  "vitest": "^3.2.4"
69
75
  },
76
+ "peerDependencies": {
77
+ "@solana-program/compute-budget": ">=0.7.0",
78
+ "@solana-program/system": ">=0.7.0",
79
+ "@solana-program/token": ">=0.7.0",
80
+ "@solana/kit": ">=6.0.0",
81
+ "@solana/kora": ">=0.1.0",
82
+ "@solana/transaction-confirmation": ">=6.0.0",
83
+ "viem": ">=2.0.0"
84
+ },
85
+ "peerDependenciesMeta": {
86
+ "@solana/kit": {
87
+ "optional": true
88
+ },
89
+ "@solana-program/compute-budget": {
90
+ "optional": true
91
+ },
92
+ "@solana-program/system": {
93
+ "optional": true
94
+ },
95
+ "@solana-program/token": {
96
+ "optional": true
97
+ },
98
+ "@solana/kora": {
99
+ "optional": true
100
+ },
101
+ "@solana/transaction-confirmation": {
102
+ "optional": true
103
+ },
104
+ "viem": {
105
+ "optional": true
106
+ }
107
+ },
70
108
  "scripts": {
71
109
  "prebuild": "node -p \"'export const VERSION = ' + JSON.stringify(require('./package.json').version) + ';\\nexport const PACKAGE = ' + JSON.stringify(require('./package.json').name) + ';'\" > src/version.ts",
72
110
  "build": "tsup",
package/tsconfig.json CHANGED
@@ -11,19 +11,18 @@
11
11
  "lib": ["es2022", "esnext.disposable", "dom"],
12
12
  "typeRoots": ["node_modules/@types", "./typings"],
13
13
  "downlevelIteration": true,
14
- "experimentalDecorators": true,
15
14
  "declaration": true,
16
15
  "strictNullChecks": true,
17
16
  "newLine": "LF",
18
17
  "noUnusedParameters": false,
19
18
  "noUnusedLocals": false,
20
- "emitDecoratorMetadata": true,
21
19
  "noImplicitThis": true,
22
20
  "noImplicitReturns": true,
23
21
  "noFallthroughCasesInSwitch": true,
24
22
  "strictBindCallApply": true,
25
23
  "esModuleInterop": true,
26
- "resolveJsonModule": true
24
+ "resolveJsonModule": true,
25
+ "skipLibCheck": true
27
26
  },
28
27
  "include": ["src/**/*"],
29
28
  "exclude": ["dist", "example"]
@@ -1,71 +0,0 @@
1
- // Usage: npx tsx policies/createAccountPolicy.ts
2
- //
3
- // Creates an account-scoped policy (as opposed to project-scoped).
4
- // Account policies apply only to a specific wallet account.
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
- walletSecret: process.env.OPENFORT_WALLET_SECRET,
15
- });
16
-
17
- // Create an EVM backend wallet to attach the policy to
18
- const account = await openfort.accounts.evm.backend.create();
19
- console.log("Created account:", account.id);
20
-
21
- // ---------------------------------------------------------------------------
22
- // Create an account-scoped policy
23
- // ---------------------------------------------------------------------------
24
-
25
- const body: CreatePolicyBody = {
26
- scope: "account",
27
- accountId: account.id,
28
- description: "Account-level allowlist for this specific wallet",
29
- enabled: true,
30
- priority: 10,
31
- rules: [
32
- {
33
- action: "accept",
34
- operation: "signEvmTransaction",
35
- criteria: [
36
- {
37
- type: "evmAddress",
38
- operator: "in",
39
- addresses: ["0x000000000000000000000000000000000000dEaD"],
40
- },
41
- {
42
- type: "ethValue",
43
- operator: "<=",
44
- ethValue: "500000000000000000", // 0.5 ETH
45
- },
46
- ],
47
- },
48
- {
49
- action: "accept",
50
- operation: "signEvmMessage",
51
- criteria: [
52
- {
53
- type: "evmMessage",
54
- operator: "match",
55
- pattern: "^Sign in to",
56
- },
57
- ],
58
- },
59
- ],
60
- };
61
-
62
- CreatePolicyBodySchema.parse(body);
63
-
64
- const policy = await openfort.policies.create(body);
65
-
66
- console.log("\nCreated account-scoped policy:");
67
- console.log(" ID:", policy.id);
68
- console.log(" Scope:", policy.scope);
69
- console.log(" Account:", policy.accountId);
70
- console.log(" Priority:", policy.priority);
71
- console.log(" Rules:", policy.rules.length);
@@ -1,149 +0,0 @@
1
- // Usage: npx tsx policies/createEvmPolicy.ts
2
- //
3
- // Creates policies that control EVM signing operations.
4
- // Demonstrates: ethValue limits, address allowlists, network restrictions,
5
- // and combined criteria.
6
-
7
- import Openfort, {
8
- CreatePolicyBodySchema,
9
- type CreatePolicyBody,
10
- } from "@openfort/openfort-node";
11
- import "dotenv/config";
12
-
13
- const openfort = new Openfort(process.env.OPENFORT_API_KEY!, {
14
- basePath: process.env.OPENFORT_BASE_URL,
15
- });
16
-
17
- // ---------------------------------------------------------------------------
18
- // 1. Reject high-value EVM transactions (> 1 ETH)
19
- // ---------------------------------------------------------------------------
20
-
21
- const highValueBody: CreatePolicyBody = {
22
- scope: "project",
23
- description: "Reject transactions above 1 ETH",
24
- rules: [
25
- {
26
- action: "reject",
27
- operation: "signEvmTransaction",
28
- criteria: [
29
- {
30
- type: "ethValue",
31
- operator: ">",
32
- ethValue: "1000000000000000000", // 1 ETH in wei
33
- },
34
- ],
35
- },
36
- ],
37
- };
38
-
39
- // Validate with Zod before sending
40
- CreatePolicyBodySchema.parse(highValueBody);
41
-
42
- const highValuePolicy = await openfort.policies.create(highValueBody);
43
- console.log("Created high-value rejection policy:");
44
- console.log(" ID:", highValuePolicy.id);
45
- console.log(" Scope:", highValuePolicy.scope);
46
- console.log(" Rules:", highValuePolicy.rules.length);
47
-
48
- // ---------------------------------------------------------------------------
49
- // 2. Address allowlist — only allow transactions to known addresses
50
- // ---------------------------------------------------------------------------
51
-
52
- const allowlistBody: CreatePolicyBody = {
53
- scope: "project",
54
- description: "Only allow transfers to treasury and vault",
55
- rules: [
56
- {
57
- action: "accept",
58
- operation: "sendEvmTransaction",
59
- criteria: [
60
- {
61
- type: "evmAddress",
62
- operator: "in",
63
- addresses: [
64
- "0x000000000000000000000000000000000000dEaD",
65
- "0x1234567890abcdef1234567890abcdef12345678",
66
- ],
67
- },
68
- {
69
- type: "evmNetwork",
70
- operator: "in",
71
- chainIds: [1, 137, 8453], // Ethereum, Polygon, Base
72
- },
73
- ],
74
- },
75
- ],
76
- };
77
-
78
- CreatePolicyBodySchema.parse(allowlistBody);
79
-
80
- const allowlistPolicy = await openfort.policies.create(allowlistBody);
81
- console.log("\nCreated address allowlist policy:");
82
- console.log(" ID:", allowlistPolicy.id);
83
-
84
- // ---------------------------------------------------------------------------
85
- // 3. Restrict EVM contract calls by ABI function
86
- // ---------------------------------------------------------------------------
87
-
88
- const dataBody: CreatePolicyBody = {
89
- scope: "project",
90
- description: "Only allow ERC-20 transfer calls",
91
- rules: [
92
- {
93
- action: "accept",
94
- operation: "signEvmTransaction",
95
- criteria: [
96
- {
97
- type: "evmData",
98
- operator: "==",
99
- abi: '[{"type":"function","name":"transfer","inputs":[{"name":"to","type":"address"},{"name":"amount","type":"uint256"}],"outputs":[{"type":"bool"}]}]',
100
- functionName: "transfer",
101
- },
102
- ],
103
- },
104
- ],
105
- };
106
-
107
- CreatePolicyBodySchema.parse(dataBody);
108
-
109
- const dataPolicy = await openfort.policies.create(dataBody);
110
- console.log("\nCreated ERC-20 transfer-only policy:");
111
- console.log(" ID:", dataPolicy.id);
112
-
113
- // ---------------------------------------------------------------------------
114
- // 4. Combined: value cap + address allowlist + network restriction
115
- // ---------------------------------------------------------------------------
116
-
117
- const combinedBody: CreatePolicyBody = {
118
- scope: "project",
119
- description: "Accept low-value sends to known addresses on mainnet only",
120
- rules: [
121
- {
122
- action: "accept",
123
- operation: "sendEvmTransaction",
124
- criteria: [
125
- {
126
- type: "ethValue",
127
- operator: "<=",
128
- ethValue: "500000000000000000", // 0.5 ETH
129
- },
130
- {
131
- type: "evmAddress",
132
- operator: "in",
133
- addresses: ["0x000000000000000000000000000000000000dEaD"],
134
- },
135
- {
136
- type: "evmNetwork",
137
- operator: "in",
138
- chainIds: [1], // Ethereum mainnet only
139
- },
140
- ],
141
- },
142
- ],
143
- };
144
-
145
- CreatePolicyBodySchema.parse(combinedBody);
146
-
147
- const combinedPolicy = await openfort.policies.create(combinedBody);
148
- console.log("\nCreated combined EVM policy:");
149
- console.log(" ID:", combinedPolicy.id);