Skip to main content
This section will help you get started with running a verified transaction using the Newton network. For this example we will use an existing policy that checks whether the transaction is being sent to a sanctioned address. If it is not sanctioned, the transaction is permitted. Here the policy and the policy client is already deployed to Newton and Ethereum Sepolia respectively. We will submit a task to the Newton protocol, then a transaction to Ethereum mainnet execute the compliant transaction. See here if you want to write your own policy.

Set up

In order to run verified transactions, you must first set up a policy and policy client. For the purposes of the quickstart, these two have already been written and deployed. See below for details on how they work

Verify intent

Now that a policy is deployed and ready we can submit a transaction against it. But first a proof needs to be generated. To do that, we will submit a task to the Newton protocol which will return the proof. Before proceeding, ensure that you install the newton-protocol-sdk
npm install @magicnewton/newton-protocol-sdk
Note the public address of your PRIVATE_KEY needs to be allowlisted by the Newton team before proceeding with this step.
import { privateKeyToAccount } from "viem/accounts";
import {
  createWalletClient,
  createPublicClient,
  publicActions,
  webSocket,
} from "viem";
import { sepolia } from "viem/chains";
import {
  newtonWalletClientActions,
  newtonPublicClientActions,
} from "@magicnewton/newton-protocol-sdk";

const signer = privateKeyToAccount(PRIVATE_KEY);

export const walletClient = createWalletClient({
  chain: sepolia,
  transport: webSocket(webSocketUrl),
  account: signer,
})
  .extend(publicActions)
  .extend(newtonWalletClientActions());

const publicClient = createPublicClient({
  chain: sepolia,
  transport: webSocket(webSocketUrl),
}).extend(
  newtonPublicClientActions({
    policyContractAddress: POLICY_CLIENT_ADDRESS,
  })
);

function stringToHexBytes(str: string) {
  const encoder = new TextEncoder();
  const bytes = encoder.encode(str);
  return Array.from(bytes)
    .map((byte) => byte.toString(16).padStart(2, "0"))
    .join("");
}

const wasmArgs = stringToHexBytes(toAddress);

const intentCode = `{
  "policyClient": "${POLICY_CLIENT_ADDRESS}",
  "intent": {
      "from": "${connectedAddress}",
      "to": "${toAddress}",
      "value": "0x1",
      "data": "0x",
      "chainId": 11155111,
      "functionSignature": "0x"
  },
  "timeout": 60,
  "wasmArgs": "${wasmArgs}"
}`;

const pendingTask = await walletClient.submitEvaluationRequest(
  JSON.parse(intentCode)
);

const response: TaskResponseResult = await publicClient.waitForTaskResponded({
  taskId: pendingTask.result.taskId,
  timeoutMs: 20_000,
});

console.log("evaluation result: ", response.taskResponse.evaluationResult);
console.log("attestation: ", response.attestation);

Execute intent

At this point we have a proof that be used execute the transaction. The following code submits a transaction with the proof using viem.
import { createPublicClient, custom, walletActions } from "viem";

const browserWalletClient = createWalletClient({
  chain: sepolia,
  transport: custom(window.ethereum),
}).extend(walletActions);

console.log("Submitting transaction with attestation:", attestation);

// Submit the transaction
const hash = await browserWalletClient.writeContract({
  address: POLICY_CLIENT_ADDRESS as `0x${string}`,
  abi: POLICY_CLIENT_ABI,
  functionName: "sanctionProtectedTransfer",
  args: [attestation],
  account: connectedAddress as `0x${string}`,
});

console.log("Transaction submitted:", hash);
The transaction should go through. We have demonstrated how a transaction can be validated against offchain data in a policy and enforced by the Newton protocol.