Releases: warp-contracts/warp
Custom SmartWeave extension plugin
This release enables creating custom SmartWeave extension plugins. It is required for these plugins to implement WarpPlugin interface and set the plugin to a type starting with smartweave-extension-
.
Plugin's process
method is then called during contract execution and required is set as the property of SmartWeave.extensions
object (available globally in the contract).
An example of such plugin implementation:
import { WarpPlugin, WarpPluginType } from 'warp-contracts';
import { custom } from 'custom-library';
class CustomExtension implements WarpPlugin<any, void> {
process(input: any): void {
input.custom = custom;
}
type(): WarpPluginType {
return 'smartweave-extension-custom';
}
}
How to use the plugin during state execution?
const warp = WarpFactory.forMainnet().use(new CustomExtension());
What's Changed
- feat: custom plugin config by @asiaziola in #307
Full Changelog: v1.2.40...v1.2.41
Fetch options plugin
Following release introduces new Warp plugin which allows to update fetch options for the endpoints and therefore allows custom http configuration.
In order to change fetch options one needs to create an implementation of WarpPlugin interface. process
method will receive following properties:
interface FetchRequest {
input: RequestInfo | URL;
init: Partial<RequestInit>;
}
...and it should return updated fetch options (by returning updated init object). An example of such implementation in src/tools/fetch-options-plugin.ts.
In order to use this plugin, it needs to be attached while creating Warp instance, e.g.:
const warp = WarpFactory.forMainnet().use(new FetchOptionsPlugin());
What's Changed
- feat: fetch options plugin by @asiaziola in #255
Full Changelog: v1.2.39...v1.2.40
AtomicNFT - register contract
This released introduces an option to register a contract, that was first deployed via Bundlr.
Used mostly for registering AtomicNFTs - #277.
What's Changed
- feat: register contract by @asiaziola in #299
Full Changelog: 1.2.38...v1.2.39
Contracts' Cache
This release fixes #261.
The contracts cache has been divided into contract metadata cache and contract source cache (since many different contracts share the exact same source with the same source tx id).
What's Changed
- split cached contract definitions to avoid duplicates by @janekolszak in #304
Full Changelog: 1.2.37...1.2.38
1.2.37
The release changes the behaviour of the unsafeClient
evaluation option.
If it is set to skip
- the root contract (if it using the unsafe client) will still throw.
What's Changed
- fix: root contract with unsafeClient should throw even with unsafeCli… by @ppedziwiatr in #303
Full Changelog: 1.2.36...1.2.37
1.2.36
This releases adds all typed arrays to the types exposed to the VM2.
More details: patriksimek/vm2#484 (comment)
What's Changed
New Contributors
Full Changelog: 1.2.35...1.2.36
unsafeClient evaluation option change, Contract Manifest
Unsafe client evaluation option
Before this release, evaluationOptions.allowUnsafeClient
was a boolean value - the SDK either allowed for reading the state of an unsafe contract (i.e. such contract that is using SmartWeave.allowUnsafeClient
in its source code; evaluation of such contract is non-deterministic) or threw an exception if allowUnsafeClient
was set to false
.
This however was an issue in case the contract was interacting with a foreign contract that was using unsafeClient - and at the same time didn't want to allow for unsafeClient to be used. Any interaction with an unsafe contract was causing an exception to be thrown and evaluation to stop.
To mitigate this issue, the allowUnsafeClient
has been renamed to unsafeClient
and can now accept one of three values:
throw
- the default, same asfalse
before this release - will cause the evaluation to stop and throw an exception when a contract withunsafeClient
will be detected.allow
- same astrue
before this release - allows for evaluation of unsafe contractskip
- skips the evaluation of an unsafe contract - a new option, added in this release. It allows to skip evaluation of a foreign contract that is using unsafe client; in such case the validity of the parent contract interaction will be set to false and the error message will contain error like[SkipUnsafeError] Using unsafeClient is not allowed by default
.
NOTE: contract's evolves are also being tracked - e.g. if contract evolves from safe to unsafe - its evaluation will be skipped from that point.
NOTE: if contract evolves back to safe code (from unsafe code) - it still will be skipped. The reason is that we're unable to determine the state of the contract when it returns to the safe version.
Contract manifest
This release adds a new feature - a contract manifest. Contract manifest is a set of evaluation options that are required by the contract to properly execute.
In order to deploy a contract with a manifest, pass the manifest options in the contractData
parameter of the warp.deploy
method, e.g.:
const {contractTxId, srcTxId} = await warp.deploy({
wallet,
initState: initialState,
src: jsContractSrc,
evaluationManifest: {
evaluationOptions: {
unsafeClient: 'skip',
internalWrites: true
}
}
});
In such case - the contract deployment transaction will contain a new tag - Contract-Manifest
.
Example - oG4vBpf7IqmadALEM9XmguLTfRlztxDcX8lWdUfiHIM.
If the client's evaluation options are not compatible with the contract's manifest options - an error will be thrown, e.g.:
Error: Option {unsafeClient} differs. EvaluationOptions: [throw], manifest: [skip]. Use contract.setEvaluationOptions({unsafeClient: skip) to evaluate contract state.
Option {internalWrites} differs. EvaluationOptions: [false], manifest: [true]. Use contract.setEvaluationOptions({internalWrites: true) to evaluate contract state.
Interactions between contracts with different manifests
In case of an interaction between two contracts that both define a manifest - the idea is that evaluation of the foreign contract should not be processed with "less secure" evaluation options than those set for the main/root contract (i.e. the one that is being read by the User).
Currently, one exception to this rule are the internal writes.
Consider the examples below:
Example 1:
- The root contract blocks internal writes
- The foreign contract allows for internal writes
=> the internal writes should be allowed during evaluation of the foreign contract
Example 2:
- The root contract has the 'unsafeClient' set to 'skip'
- The foreign contract has the 'unsafeClient' to 'allow'
=> the 'unsafeClient' should be set to 'skip' for foreign contract
Example 3:
- The root contract has the 'vm2' set to 'true'
- The foreign contract has the 'vm2' set to 'false'
=> the 'vm2' for the foreign contract should be set to 'true'
Example 4:
- The root contract has the 'maxCallDepth' set to 3
- The foreign contract has the 'maxCallDepth' set to 5
=> the 'maxCallDepth' for the foreign contract should be set to '3'
NOTE: call depth is always verified from the perspective of the root contract!
Example 5:
- The root contract has the 'maxInteractionEvaluationTimeSeconds' set to 10
- The foreign contract has the 'maxInteractionEvaluationTimeSeconds' set to 60
=> the 'maxInteractionEvaluationTimeSeconds' for the foreign contract should be set to '10'
On the other hand - if the root contract has less secure options than the foreign contract -
the more secure options of the foreign contract should be respected.
Example:
- Contract "A" with 'unsafeClient' = 'allow' (and unsafeClient used in its source) is performing
write operation on Contract "B" that has 'unsafeClient' set to 'skip'.
i.e. Contract A calls SmartWeave.contracts.write on Contract B.
In this case the more secure setting of the Contract B should be reflected - and write itself
should be blocked (i.e. it should not be even created during the A.writeInteraction
- when a dry-run
is being performed, and we're evaluating a list of internal writes for a newly created interaction).
All rules are defined in https://github.com/warp-contracts/warp/blob/main/src/contract/EvaluationOptionsEvaluator.ts#L21
What's Changed
- feat: skip unsafe contracts calls by @ppedziwiatr in #259
Full Changelog: v1.2.33...1.2.35
Save contract source through Bundlr
This release adds an option to save contract source through Bundlr using Warp Gateway and introduces some significant API changes.
- Saving source through Bundlr
This release splits contract source saving process to two parts - creating source and saving source.
createSourceTx
- creates and signs contract source transaction, returns signed contract source transaction
createSourceTx(sourceData: SourceData, wallet: ArWallet | SignatureType): Promise<Transaction>;
usage:
const srcTx = await warp.createSourceTx({ src: contractSrc }, wallet);
saveSourceTx
- saves source transaction created usingcreateSourceTx
method; by default source transaction is sent to Warp Gateway where it is uploaded to Bundlr, if in local environment or bundle is disabled usingdisableBundling
method - source transaction is sent directly to Arweave, returns source transaction id
saveSourceTx(sourceTx: Transaction, disableBundling?: boolean): Promise<string>;
usage:
const srcTxId = await warp.saveSourceTx(srcTx);
Above methods are useful particularly when one contract needs to evolve its current contract source:
const srcTx = await warp.createSourceTx({ src: newJsContractSrc }, wallet);
const newSrcTxId = await warp.saveSourceTx(srcTx);
await contract.evolve(newSrcTxId);
...it is also useful when one contract source should be later used by multiple contracts.
- API changes
createContract
field inWarp
instance is now deprecated and will be changed into private field soon. AllCreateContract
methods are now accessible directly fromWarp
instance, they can be used like so:
const { contractTxId } = await warp.deploy({
wallet,
initState: JSON.stringify(initialState),
src: contractSrc
});
List of CreateContract
methods now available from Warp
instance:
async deploy(contractData: ContractData, disableBundling?: boolean): Promise<ContractDeploy>;
async deployFromSourceTx(contractData: FromSrcTxContractData, disableBundling?: boolean): Promise<ContractDeploy>;
async deployBundled(rawDataItem: Buffer): Promise<ContractDeploy>;
async createSourceTx(sourceData: SourceData, wallet: ArWallet | SignatureType): Promise<Transaction>
async saveSourceTx(srcTx: Transaction, disableBundling?: boolean): Promise<string>
What's Changed
- feat: save source through bundlr by @asiaziola in #283
Full Changelog: 1.2.31...v1.2.32
Cache enhancements
This release adds new methods to the SortKeyCache
interface:
prune
- allows to remove old cache entries - https://github.com/warp-contracts/warp/blob/main/src/cache/SortKeyCache.ts#L65delete
- allows to remove all cached values for a given contract - https://github.com/warp-contracts/warp/blob/main/src/cache/SortKeyCache.ts#L35
What's Changed
- Implement prune method by @janekolszak in #268
- Delete method by @janekolszak in #281
- Lazy initialization of the LevelDB cache by @janekolszak in #282
New Contributors
- @janekolszak made their first contribution in #268
Full Changelog: v1.2.30...1.2.31
'Buffer' defined for the contract function executed in browser environment
- adds
Buffer, atob, btoa
to the browser version of contract function so it can be defined inside the contract when state is evaluated in the browser - removes polyfills from the web bundle (introduced in
v1.2.29
) - upgrades
arweave-js
version to1.11.8
(which fixes issues with tx signature verification) - changes
smartweave-nlp-extension
plugin's name tosmartweave-nlp-extension
andsmartweave-ethers-extension
tosmartweave-extension-ethers
What's Changed
- feat: buffer fight by @asiaziola in #279
Full Changelog: v1.2.29...v1.2.30