Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build-test-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ on:
branches: ["*"]

env:
DEVNET_VERSION: "0.7.2"
DEVNET_VERSION: "0.8.1"
DEVNET_DIR: "/tmp/devnet-ci-storage"
DEVNET_PATH: "/tmp/devnet-ci-storage/starknet-devnet"
FORKED_DEVNET_PORT: 5051
Expand Down
46 changes: 45 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ npm i starknet-devnet

## Devnet compatibility

This library version is compatible with Devnet `v0.7.2`.
This library version is compatible with Devnet `v0.8.1`.

[Devnet's balance checking functionality](https://0xspaceshard.github.io/starknet-devnet/docs/balance#check-balance) is not provided in this library because it is simply replaceable using starknet.js, as witnessed by the [getAccountBalance](./test/util.ts#L61) function.

Expand Down Expand Up @@ -157,6 +157,50 @@ const block = await starknetProvider.getBlock("latest");

Assuming there is an L1 provider running (e.g. [anvil](https://github.com/foundry-rs/foundry/tree/master/crates/anvil)), use the `postman` property of `DevnetProvider` to achieve [L1-L2 communication](https://0xspaceshard.github.io/starknet-devnet/docs/postman). See [this example](https://github.com/0xSpaceShard/starknet-devnet-js/blob/master/test/l1-l2-postman.test.ts) for more info.

## Transaction Proofs

Use the `proofs` property of `DevnetProvider` to prove INVOKE v3 transactions. This is useful for testing proof-aware flows in your application. See the [Devnet proofs documentation](https://0xspaceshard.github.io/starknet-devnet/docs/proofs) for more details on proof modes.

**Note:** Before calling `proveTransaction`, Devnet requires at least 10 blocks to exist. Start Devnet with `--proof-mode devnet` to enable this feature.

```typescript
import { Devnet } from "starknet-devnet";
import * as starknet from "starknet";

const devnet = await Devnet.spawnInstalled({ args: ["--proof-mode", "devnet"] });

// ... ensure at least 10 blocks exist (e.g. via devnet.provider.createBlock()) ...

// Build an INVOKE v3 transaction payload
const invokeTx = {
type: "INVOKE" as const,
version: "0x3" as const,
sender_address: account.address,
calldata: ["0x1", "0x2"],
signature: ["0x...", "0x..."],
nonce: "0x0",
resource_bounds: {
l1_gas: { max_amount: "0x100", max_price_per_unit: "0x100" },
l1_data_gas: { max_amount: "0x100", max_price_per_unit: "0x100" },
l2_gas: { max_amount: "0x100", max_price_per_unit: "0x100" },
},
tip: "0x0",
paymaster_data: [],
account_deployment_data: [],
nonce_data_availability_mode: "L1" as const,
fee_data_availability_mode: "L1" as const,
};

// Prove the transaction
const proofResult = await devnet.provider.proofs.proveTransaction("latest", invokeTx);

console.log(proofResult.proof); // Base64-encoded mock proof
console.log(proofResult.proof_facts); // Array of 9 hex strings
console.log(proofResult.l2_to_l1_messages); // L2 to L1 messages from simulation
```

See [this example](https://github.com/0xSpaceShard/starknet-devnet-js/blob/master/test/proofs.test.ts) for a complete test with transaction building and signing.

## Configuration modification and retrieval

Devnet's configuration can be modified, other than [on startup (as already described)](#specify-devnet-arguments), via `setGasPrice`. It can be retrieved via `getConfig`.
Expand Down
8 changes: 2 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "starknet-devnet",
"version": "0.7.2",
"version": "0.8.1",
"description": "Starknet Devnet provider",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand Down
5 changes: 5 additions & 0 deletions src/devnet-provider.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import axios, { AxiosInstance } from "axios";
import { Postman } from "./postman";
import { Cheats } from "./cheats";
import { Proofs } from "./proofs";
import { RpcProvider } from "./rpc-provider";
import { BalanceUnit, BlockId, PredeployedAccount, toRpcBlockId } from "./types";
import { DEFAULT_DEVNET_URL, DEFAULT_HTTP_TIMEOUT } from "./constants";
Expand Down Expand Up @@ -52,6 +53,9 @@ export class DevnetProvider {
/** Contains methods for cheating, e.g. account impersonation. */
public readonly cheats: Cheats;

/** Contains methods for transaction proofs. */
public readonly proofs: Proofs;

public constructor(config?: DevnetProviderConfig) {
this.url = config?.url || DEFAULT_DEVNET_URL;
this.httpProvider = axios.create({
Expand All @@ -61,6 +65,7 @@ export class DevnetProvider {
this.rpcProvider = new RpcProvider(this.httpProvider, this.url);
this.postman = new Postman(this.rpcProvider);
this.cheats = new Cheats(this.rpcProvider);
this.proofs = new Proofs(this.rpcProvider);
}

/**
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from "./devnet";
export * from "./devnet-provider";
export * from "./types";
export * from "./proofs";
100 changes: 100 additions & 0 deletions src/proofs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import { L2ToL1Message } from "./postman";
import { RpcProvider } from "./rpc-provider";
import { BlockId, toRpcBlockId } from "./types";

/**
* Resource bounds for a transaction (gas/data gas).
* Compatible with starknet.js RPC.RESOURCE_BOUNDS type.
*/
export interface ResourceBounds {
max_amount: string;
max_price_per_unit: string;
}

/**
* Full resource bounds for INVOKE v3 transaction.
* Compatible with starknet.js RPC.RESOURCE_BOUNDS_MAPPING type.
*/
export interface ResourceBoundsMapping {
l1_gas: ResourceBounds;
l1_data_gas: ResourceBounds;
l2_gas: ResourceBounds;
}

export type DataAvailabilityMode = "L1" | "L2";

/**
* INVOKE v3 transaction payload.
* Compatible with starknet.js RPC.INVOKE_TXN_V3 type.
* https://0xspaceshard.github.io/starknet-devnet/docs/proofs
*/
export interface InvokeV3Transaction {
type: "INVOKE";
version: "0x3";
sender_address: string;
calldata: string[];
signature: string[];
nonce: string;
resource_bounds: ResourceBoundsMapping;
tip: string;
paymaster_data: string[];
account_deployment_data: string[];
nonce_data_availability_mode: DataAvailabilityMode;
fee_data_availability_mode: DataAvailabilityMode;
}

/**
* L2 to L1 message included in the proof response, ordered by emission.
*/
export interface ProofL2ToL1Message extends L2ToL1Message {
order: number;
}

/**
* Response from `starknet_proveTransaction`
* https://0xspaceshard.github.io/starknet-devnet/docs/proofs
*/
export interface ProveTransactionResponse {
/** Base64-encoded mock proof */
proof: string;
/** Array of 9 hex strings (includes messages_hash in devnet mode) */
proof_facts: string[];
/** L2 to L1 messages extracted by simulating the transaction */
l2_to_l1_messages: ProofL2ToL1Message[];
}

/**
* Transaction proofs handler for Devnet.
*
* This covers `starknet_proveTransaction`, a Devnet extension for proving/validating
* `INVOKE v3` transaction payloads. For configuration (proof modes), see:
* https://0xspaceshard.github.io/starknet-devnet/docs/proofs
*/
export class Proofs {
constructor(private rpcProvider: RpcProvider) {}

/**
* Prove an INVOKE v3 transaction payload.
*
* Returns a deterministic mock proof and proof facts in `devnet` proof mode (default).
* Returns an error in `none` mode (disabled) or `full` mode (not implemented).
*
* If the transaction simulation fails (e.g. execution reverts), an error is returned
* instead of a proof.
*
* https://0xspaceshard.github.io/starknet-devnet/docs/proofs
*
* @param blockId the block context for proving (e.g. "latest", block number, or block hash)
* @param transaction the INVOKE v3 transaction payload to prove
* @returns proof data including the proof, proof_facts, and l2_to_l1_messages
*/
public async proveTransaction(
blockId: BlockId,
transaction: InvokeV3Transaction,
): Promise<ProveTransactionResponse> {
return await this.rpcProvider.sendRequest("starknet_proveTransaction", {
block_id: toRpcBlockId(blockId),
transaction,
});
}
}
Loading
Loading