# Shield3 Syndicate Integration Demo ## Summary In the Syndicate dashboard demo project users are able to relay transactions via the Syndicate API to call `mint` on a demo contract. In this demo we'll show how we can define this restriction, and further restrictions within the Shield3 RPC. ![syndicate_flowchart_2 copy](https://hackmd.io/_uploads/SyMwaT5Qa.png) ### Syndicate Configuration On the Syndicate UI the project is configured as shown here: ![Screenshot 2023-11-08 at 12.49.36](https://hackmd.io/_uploads/SJ-aU9976.png) *Allowed Functions* restricts the API to send `mint` requests to the specified contact on the Mumbai testnet. The payload to send the `mint` request via the syndicate API is: ``` { "projectId": "e2903e3c-a044-47d1-835c-4fa4f49ed5a6", "contractAddress": "0xbEc332E1eb3EE582B36F979BF803F98591BB9E24", "chainId": 80001, "functionSignature": "mint(address account)", "args": { "account": "0x9E7d7C833c1D719E1dcFd06B3172065E7F6B600B" } } ``` ### Shield3 Policy On Shield3 the contract restriction can be defined with a policy as follows. **NOTE** this shows the inner workings of the policy engine, the dashboard provides a simple editor to set these parameters without needing to learn the policy language. ```jsonld= @name("Mint Method") @message("Allow mint on specific contract on Mumbai") @action("Notify") permit( principal, action == Action::"0x6a627842", resource == Address::"0xbec332e1eb3ee582b36f979bf803f98591bb9e24" ) when { context.transaction.network == Network::"0x013881" }; ``` `permit | forbid` defines the only conditions that the RPC should broadcast the transaction. Policies can be configured to either allow **everything** except specific conditions, or allow **nothing** except specific conditions. `action` Can be blank, `Notify` or `MFA`. This instructs the RPC what to do in the event that the transaction is allowed. Alerts and MFA requests are sent via webhooks. `principal` defines which senders this policy applies to. Principal by itself means that it applies to all senders. `action` defines which transaction types this policy applies to. In this case the function signature of `mint` is used. `resource` defines which contracts this policy applies to. In this case it is restricted to the mint contract address. `when` defines additional context. In this case it is restricting the policy to transactions on the Mumbai network. ## Allow/ Deny lists This policy can be further extended to allow customers to restrict transactions to specific lists of recipients. ```jsonld= @name("Mint Method Restricted Recipient") @message("Allow mint on specific contract on Mumbai unless blocked") @action("Notify") permit( principal, action == Action::"0x6a627842", resource == Address::"0xbec332e1eb3ee582b36f979bf803f98591bb9e24" ) when { context.transaction.network == Network::"0x013881" } unless { context.args.arg_0 has groups && context.args.arg_0.groups.contains(Group::"blocked") }; ``` This policy includes an `unless` case which checks if the recipient of the mint is on a deny list. These lists are configurable via the Shield3 API or dashboard. ## Example Requests Shield3 provides both `broadcast` and `simulate` capabilities to test the policy decision for a transaction. **A `broadcast` call follows the JSON RPC specification for all Ethereum nodes and no additional configuration is required except using the Shield3 RPC URL**. `Simulate` uses a custom RPC method. The api request looks like this for a valid mint request (function data is serialized using standard eth libs) ```json= { "jsonrpc": "2.0", "method": "eth_simulateTransaction", "params": [ "0xf8505a85e8d4a510008307a12094bec332e1eb3ee582b36f979bf803f98591bb9e24840f71b3fba46a6278420000000000000000000000000000000000000000000000000000000000000001830138818080", "0x01B2f8877f3e8F366eF4D4F48230949123733897" ], "id": 42 } ``` When we call the `simulate` method with the above policy enabled on the account we get this response. ```json= { "jsonrpc": "2.0", "result": { "transaction": { "id": "3595d30c-84e3-4ea9-9bb3-fa8fff6b238c", "team_id": "b9027b9d-9a3c-4dd9-807d-b0aa5c307ea0", "network": "0x013881", "tx_status": "Simulated", "decoded_type": "contract_with_data", "workflow_results": { "policyResults": [ { "name": "Syndicate Demo - Mint Method", "result": { "errors": [], "reasons": [ { "invoked": true, "policy_id": "policy0", "annotations": { "name": "Mint Method", "action": "Notify", "message": "Allow mint on specific contract on Mumbai" } } ], "decision": "Allow" }, "policyId": "52fc621e-067f-476b-b493-97a261d34181", "policySource": "Team" } ], "routingDecision": "Notify" }, "created_at": "2023-11-09 01:17:17.59499", "updated_at": "2023-11-09 01:17:17.797489" }, "decision": "Notify" }, "id": 42 } ``` With an invalid request (such as a different contract method or a blocked recipient) we get this response ```json= { "jsonrpc": "2.0", "result": { "transaction": { "id": "75b43ec1-4065-40c8-9b4e-962e3a22141c", "team_id": "b9027b9d-9a3c-4dd9-807d-b0aa5c307ea0", "network": "0x013881", "tx_status": "Simulated", "decoded_type": "contract_with_data", "workflow_results": { "policyResults": [ { "name": "Syndicate Demo - Mint Method", "result": { "errors": [], "reasons": [ { "invoked": false, "policy_id": "policy0", "annotations": { "name": "Mint Method", "action": "Notify", "message": "Allow mint on specific contract on Mumbai" } } ], "decision": "Deny" }, "policyId": "52fc621e-067f-476b-b493-97a261d34181", "policySource": "Team" } ], "routingDecision": "Block" }, "created_at": "2023-11-09 01:33:52.252141", "updated_at": "2023-11-09 01:33:52.458323" }, "decision": "Block" }, "id": 43 } ``` # Integration Guide ## 1. Generate Shield3 RPC ### Generating a Shield3 API Key and RPC URL The policy above has been enabled on an account with this RPC URL, you can also log in [here.]( https://www.shield3.com/auth/sign-in) `https://rpc.shield3.com/v3/0x013881/rpc?apiKey=9yOMT21nl259vFr82C3BT1BvMvGrK4eK7zOWFIX3` 1. On the dashboard page, under "Shield3 RPC", click "View API Keys" ![](https://hackmd.io/_uploads/HydDHDtG6.png) 2. Click "Create new API Key" ![](https://hackmd.io/_uploads/SyX2IDKGp.png) 3. Name your key ![](https://hackmd.io/_uploads/By8aLvFMp.png) 4. After creating your key, in options, click view key ![](https://hackmd.io/_uploads/HkjGDwKGa.png) 5. Now you have your API key and RPC URL ![](https://hackmd.io/_uploads/H1FUDDKfa.png) ### 3. Configure Policies Now, we want to enable our policies in the Shield3 dashboard. First, make your way to [the policies dashboard](https://www.shield3.com/dashboard/command-center/policies). Now, you should be seeing series of policies. Simply press the drop-down icon on your desired policies, then select "enable". Custom policies can also be uploaded via API, or send us a message with a policy you'd like and we'll make it happen! ### 4. Configure Webhook Configuring your webhook is also quite straight-forward. In this integration, the webhook will be used for MFA and any notifications arising from policy execution. Navigate to [the webhooks page](https://www.shield3.com/dashboard/command-center/webhooks). Next, press "create new webhook", then enter a name, description, and the URL to hit when the webhook is fired.