Skip to content
Draft
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
4 changes: 4 additions & 0 deletions website/docs/releases/release-notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ title: Release Notes
- :hammer_and_wrench: Improve libauth template generation.
- :bug: Fix bug where `SignatureTemplate` would not accept private key hex strings as a signer.

---

https://x.com/CashScriptBCH/status/1973692336782876974

## v0.11.5

#### CashScript SDK
Expand Down
37 changes: 34 additions & 3 deletions website/docs/sdk/electrum-network-provider.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,17 @@
title: Electrum Network Provider
---

The CashScript SDK needs to connect to the BCH network to perform certain operations, like retrieving the contract's balance, or sending transactions. By default the network provider is an `ElectrumNetworkProvider`.
The CashScript SDK needs to connect to the BCH network to perform certain operations, like retrieving the contract's balance, or sending transactions. The recommended network provider is the `ElectrumNetworkProvider`.

## ElectrumNetworkProvider
## Creating an ElectrumNetworkProvider

The ElectrumNetworkProvider uses [@electrum-cash/network][electrum-cash] to connect to the BCH network. Both `network` and `options` parameters are optional, and they default to mainnet with the `bch.imaginary.cash` electrum server.
The ElectrumNetworkProvider uses [@electrum-cash/network][electrum-cash] library to connect to the configured electrum server. The connection uses a single, trusted electrum server so it does no have any fallback logic and does not validate SPV proofs for chain inclusion.

By default the `ElectrumNetworkProvider` creates a short-lived connection only when requests are pending. To configure this see the section on '[Manual Connection Management](#manual-connection-management)'.

### Constructor

Both `network` and `options` parameters are optional, and they default to `mainnet` with the `bch.imaginary.cash` electrum server.

```ts
new ElectrumNetworkProvider(network?: Network, options?: Options)
Expand Down Expand Up @@ -44,6 +50,9 @@ const hostname = 'chipnet.bch.ninja';
const provider = new ElectrumNetworkProvider('chipnet', { hostname });
```

## ElectrumNetworkProvider Methods


### getUtxos()
```ts
async provider.getUtxos(address: string): Promise<Utxo[]>;
Expand Down Expand Up @@ -143,5 +152,27 @@ provider.disconnect(): Promise<boolean>;

Disconnects from the electrum client, returns `true` if the client was connected, `false` if it was already disconnected.

## Using electrum-cash functionality

To use more of the electrum-specific functionality which is not exposed in the `ElectrumNetworkProvider` you can simply call the methods on the electrum Client itself.

### Custom Electrum Client

When initializing an `ElectrumNetworkProvider` you have the option in the constructor to provide a custom electrum client. This way you can use one and the same indexer server for blockchain information but use it through two different interfaces. This allows you to access all underlying functionality of the [@electrum-cash/network][electrum-cash] library like address and blockHeight subscriptions.

If intending to use electrum-cash subscriptions, make sure to set `manualConnectionManagement` to true, so the `ElectrumNetworkProvider` does not disconnect after each request.

#### example

```ts
import { ElectrumClient } from '@electrum-cash/network';
import { ElectrumNetworkProvider } from 'cashscript';

const electrum = new ElectrumClient('CashScript Application', '1.4.1', 'chipnet.bch.ninja');
const provider = new ElectrumNetworkProvider(Network.CHIPNET, {
electrum, manualConnectionManagement: true
});
await electrum.connect();
```

[electrum-cash]: https://www.npmjs.com/package/@electrum-cash/network
22 changes: 11 additions & 11 deletions website/docs/sdk/instantiation.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,6 @@ title: Contract Instantiation

Before interacting with a smart contract on the BCH network, the CashScript SDK needs to instantiate a `Contract` object. This is done by providing the contract's information and constructor arguments. After this instantiation, the CashScript SDK can interact with the BCH contract.

:::info
CashScript offers a TypeScript SDK, which can also be used easily in vanilla JavaScript codebases.
Because of the separation of the compiler and the SDK, CashScript contracts can be integrated into other languages in the future.
:::

## Creating a Contract
The `Contract` class is used to represent a CashScript contract in a JavaScript object. These objects can be used to retrieve information such as the contract's address and balance. Contract objects can be used to interact with the contract by generating an `Unlocker` by calling the contract's unlocker functions.

Expand All @@ -17,16 +12,20 @@ The `Contract` class is used to represent a CashScript contract in a JavaScript
new Contract(
artifact: Artifact,
constructorArgs: ConstructorArgument[],
options? : {
options : {
provider: NetworkProvider,
addressType: 'p2sh20' | 'p2sh32',
addressType?: 'p2sh20' | 'p2sh32',
}
)
```

A CashScript contract can be instantiated by providing an `Artifact` object, a list of constructor arguments, and optionally an options object configuring `NetworkProvider` and `addressType`.

An `Artifact` object is the result of compiling a CashScript contract. Compilation can be done using the standalone [`cashc` CLI](/docs/compiler) or programmatically with the `cashc` NPM package (see [CashScript Compiler](/docs/compiler#javascript-compilation)). If compilation is done using the `cashc` CLI with the <span style={{ display: 'inline-block' }}>`--format ts`</span> option, you will get explicit types and type checking for the constructor arguments and function arguments.
An `Artifact` object is the result of compiling a CashScript contract. Compilation can be done using the standalone [`cashc` CLI](/docs/compiler) or programmatically with the `cashc` NPM package (see [CashScript Compiler](/docs/compiler#javascript-compilation)).

:::tip
If compilation is done using the `cashc` CLI with the <span style={{ display: 'inline-block' }}>`--format ts`</span> option to output TypeScript Artifacts, you will get explicit types and type checking for the constructor arguments and function arguments of the `Contract` class.
:::

The `NetworkProvider` option is used to manage network operations for the CashScript contract. By default, a mainnet `ElectrumNetworkProvider` is used, but the network providers can be configured. See the docs on [NetworkProvider](/docs/sdk/network-provider).

Expand Down Expand Up @@ -170,6 +169,10 @@ contract.unlock.<functionName>(...args: FunctionArgument[]): Unlocker
Once a smart contract has been instantiated, you can invoke a contract function on a smart contract UTXO to use the '[Transaction Builder](/docs/sdk/transaction-builder)' by calling the function name under the `unlock` member field of a contract object.
To call these functions successfully, the provided parameters must match the function signature defined in the CashScript code.

:::tip
When using a TypeScript contract Artifact, you will get explicit types and type checking for the function name and arguments.
:::

These contract functions return an incomplete `transactionBuilder` object, which needs to be completed by providing outputs of the transaction. For more information see the [transaction-builder](/docs/sdk/transaction-builder) page.

```ts
Expand All @@ -180,6 +183,3 @@ const contractUtxos = await contract.getUtxos();
transactionBuilder.addInput(contractUtxos[0], contract.unlock.spend());
```

:::tip
If the contract artifact is generated using the `cashc` CLI with the `--format ts` option, you will get explicit types and type checking for the function name and arguments.
:::
12 changes: 11 additions & 1 deletion website/docs/sdk/network-provider.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: Network Provider
---

The CashScript SDK needs to connect to the BCH network to perform certain operations, like retrieving the contract's balance, or sending transactions. By default the network provider is an `ElectrumNetworkProvider`, however for local development it is recommended to use a `MockNetworkProvider`.
The CashScript SDK needs to connect to the BCH network to perform certain operations, like retrieving the contract's balance, or sending transactions. The recommended network provider to use blockchain network functionality is the `ElectrumNetworkProvider`, however for local development it is recommended to use a `MockNetworkProvider`.

:::tip
CashScript NetworkProviders have a standardized interface, this allows different network providers to be used by the SDK and makes it easy to swap out dependencies.
Expand Down Expand Up @@ -90,3 +90,13 @@ const txId = await provider.sendRawTransaction(txHex)
A big strength of the NetworkProvider setup is that it allows you to implement custom providers. So if you want to use a new or different BCH indexer for network information, it is simple to add support for it by creating your own `NetworkProvider` adapter by implementing the [NetworkProvider interface](https://github.com/CashScript/cashscript/blob/master/packages/cashscript/src/network/NetworkProvider.ts).

You can create a PR to add your custom `NetworkProvider` to the CashScript codebase to share this functionality with others. It is required to have basic automated tests for any new `NetworkProvider`.

## Provider-Specific functionality

Beyond the standardized `NetworkProvider` interface each provider can have its own provider-specific functionality. This can either be done by extending the `NetworkProvider` interface or by providing a more full-featured networking client to create the `NetworkProvider`.

## Limitations

If you look at the [Transaction Lifecycle](guides/lifecycle.md) guide then you'll see there are blockchain edge cases like chain re-organisations or double spends. Ideally the `NetworkProvider` interface would be able to provide more detailed `Utxo` chain information like whether the UTXO is unconfirmed or confirmed, the number of confirmations and the block-hash of the block which included the transaction creating the UTXO.

Currently however the `NetworkProvider` interface does not include the details needed to understand whether blockchain state is confirmed, pending or ended up getting reversed. This means that in the case something does end up being reversed your application might not correctly be in sync with the actual network state.
13 changes: 11 additions & 2 deletions website/docs/sdk/other-network-providers.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,25 @@ The CashScript SDK needs to connect to the BCH network to perform certain operat

## MockNetworkProvider
```ts
new MockNetworkProvider(options?: { updateUtxoSet: boolean })
new MockNetworkProvider(options?: MockNetworkProviderOptions)
```

The `MockNetworkProvider` is a special network provider that allows you to evaluate transactions locally without interacting with the Bitcoin Cash network. This is useful when writing automated tests for your contracts, or when debugging your contract locally.

The `MockNetworkProvider` has extra methods to enable this local emulation such as `.addUtxo()` and `.setBlockHeight()`.
You can read more about the `MockNetworkProvider` and automated tests on the [testing setup](/docs/sdk/testing-setup) page.

```ts
interface MockNetworkProviderOptions {
updateUtxoSet?: boolean;
vmTarget?: VmTarget;
}
```

The `updateUtxoSet` option is used to determine whether the UTXO set should be updated after a transaction is sent. If `updateUtxoSet` is `true` (default), the UTXO set will be updated to reflect the new state of the mock network. If `updateUtxoSet` is `false`, the UTXO set will not be updated.

The `vmTarget` option defaults to the current VM of `BCH_2025_05`, but this can be changed to test your contract against different BCH virtual machine targets.

#### Example
```ts
const provider = new MockNetworkProvider();
Expand Down Expand Up @@ -63,7 +72,7 @@ new BitcoinRpcNetworkProvider(network: Network, url: string, options?: any)
The `BitcoinRpcNetworkProvider` uses a direct connection to a BCH node. Note that a regular node does not have indexing, so any address of interest (e.g. the contract address) need to be registered by the node *before* sending any funds to those addresses. Because of this it is recommended to use a different network provider unless you have a specific reason to use the RPC provider.

:::caution
The `BitcoinRpcNetworkProvider` does not currently support CashTokens. If you want to use CashTokens, please use the `ElectrumNetworkProvider` instead.
The `BitcoinRpcNetworkProvider` does not currently support CashTokens. If you want to use CashTokens, use the `ElectrumNetworkProvider` instead.
:::

#### Example
Expand Down
1 change: 1 addition & 0 deletions website/docs/sdk/transaction-builder.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ interface TransactionBuilderOptions {
provider: NetworkProvider;
maximumFeeSatoshis?: bigint;
maximumFeeSatsPerByte?: number;
allowImplicitFungibleTokenBurn?: boolean;
}
```

Expand Down
81 changes: 81 additions & 0 deletions website/docs/sdk/typescript-sdk.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
---
title: TypeScript SDK
---

CashScript offers a TypeScript SDK, which makes it easy to build smart contract transactions, both in browser or on the server. By offering full type-safety, developers can be confident in the quality and reliability of their applications. The SDK can also be used easily in vanilla JavaScript codebases, although the benefits of the type-safety will be lost.

:::info
Because of the separation of the compiler and the SDK, CashScript contracts can be integrated into other programming languages in the future.
:::

## SDK Classes

The CashScript SDK consists of 4 classes, together they form one cohesive structure to build BCH smart contract applications.
The documentation also follows the structure of these 4 classes:

- the `Contract` class
- the `TransactionBuilder` class
- the `NetworkProvider` class
- the `SignatureTemplate` class

## SDK usage

The usage of the 4 classes in your code is as follows: before using the SDK you create one or multiple contract artifacts compiled by `cashc`. Then to start using the SDK, you instantiate a `NetworkProvider`, which you then provide to instantiate a `Contract` from an `Artifact`. Once you have a `Contract` instance, you can use it in the `TransactionBuilder`. During transaction building you might need to generate a signature, in which case you would instantiate a `SignatureTemplate`.

For an more complete example of the SDK flow, refer to the [SDK Example](./examples.md).

#### example

```ts
import { Contract, ElectrumNetworkProvider, TransactionBuilder, SignatureTemplate } from 'cashscript';
import { P2pkhArtifact } from './artifact';
import { contractArguments, aliceWif } from './somewhere';

const provider = new ElectrumNetworkProvider('chipnet');

const contract = new Contract(P2pkhArtifact, contractArguments, { provider });

const aliceSignatureTemplate = new SignatureTemplate(aliceWif);
const unlocker = contract.unlock.transfer(aliceSignatureTemplate)

const transactionBuilder = new TransactionBuilder({ provider });

// then use the transactionBuilder to actually spend a UTXO with the contract unlocker
```

## Full TypeScript Integration

The constructor of the `Contract` class takes in an `Artifact`, this is the output of the `cashc` compiler and can be configured to either output a JSON or TS file. To have the best TypeScript integration, we recommend generating the artifact in the `.ts` format and importing it into your TypeScript project from that `.ts` file. The type benefits are explained in more details in the documentation for the [Contract](./instantiation#constructor) class.

## Advanced: non-CashScript Contracts

You can also use the CashScript SDK without relying on the CashScript contract language and compiler. This way you can still leverage the a lot of the tooling while having full control over the raw BCH script so this can be hand-written or hand-optimized.

There's two ways to go about this, either you create a custom `Artifact` so you can still use the `Contract` class or you create a custom `Unlocker` to use in the transaction building directly.

### Custom Artifacts

You can create an Artifact for a fully hand-written contract so it becomes possible to use the contract with the nice features of the CashScript SDK! An example of this is [Cauldron_Swap_Test](https://github.com/mr-zwets/Cauldron_Swap_Test) which uses `Artifact bytecode` not produced by `cashc` at all but still uses the CashScript SDK.

### Custom Unlockers

In the [addInput() method](./transaction-builder#addInput()) on the TransactionBuilder you can provide a custom `Unlocker`

```ts
transactionBuilder.addInput(utxo: Utxo, unlocker: Unlocker, options?: InputOptions): this
```

the `Unlocker` interface is the following:

```ts
interface Unlocker {
generateLockingBytecode: () => Uint8Array;
generateUnlockingBytecode: (options: GenerateUnlockingBytecodeOptions) => Uint8Array;
}

interface GenerateUnlockingBytecodeOptions {
transaction: Transaction;
sourceOutputs: LibauthOutput[];
inputIndex: number;
}
```
1 change: 1 addition & 0 deletions website/sidebars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ const sidebars: SidebarsConfig = {
type: 'category',
label: 'TypeScript SDK',
items: [
'sdk/typescript-sdk',
'sdk/instantiation',
'sdk/transaction-builder',
{
Expand Down