Spaces:
Runtime error
Runtime error
File size: 5,031 Bytes
711e9c6 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
---
sidebar_position: 9
---
# How to Publish a Contract to NPM
## What is a Smart Contract Library?
A smart contract library can provide methods which can be reused in many contracts. Developers can use existing libraries to reduce the cost of developing their own contracts.
A smart contract library is different from a smart contract in these ways:
* A smart contract library can not have any public/entry `@method`s, which means a library can not be deployed or called directly through a tx. They can only be called within a smart contract or another library.
* A smart contract library can not have any stateful properties, i.e. `@prop(true)` properties. But a property declared as `@prop()` is fine.
## Write a Smart Contract Library
Using `sCrypt` we can create a smart contract library class like this:
```ts
class MyLib extends SmartContractLib {
@prop()
readonly buf: ByteString;
constructor(buf: ByteString) {
super(...arguments);
this.buf = buf;
}
@method()
append(content: ByteString) {
this.buf += content;
}
@method()
static add(x: bigint, y: bigint): bigint {
return x + y;
}
}
```
A smart contract library can be declared as a class that extends `SmartContractLib`. It may also have `@prop`s and `@method`s like smart contracts which have the same rules [introduced before](./how-to-write-a-contract). A smart contract library can be used within `@method`s like this:
```ts
class MyContract extends SmartContract {
@method()
public unlock(x: ByteString) {
let myLib = new MyLib(hexToByteString('0123'));
myLib.append(x);
assert(MyLib.add(1n, 2n) === 3n, 'incorrect sum');
}
}
```
## Test a Smart Contract Library
You can test your smart contract library as a normal class, for example, writing some unit tests:
```ts
describe('Test SmartContractLib `MyLib`', () => {
it('should pass unit test successfully.', () => {
expect(MyLib.add(1n, 2n)).to.eq(3n)
})
})
```
Also you can write a smart contract using the library, then have some tests for the contract, like:
```ts
class TestLib extends SmartContract {
@method
public unlock(x: bigint) {
assert(MyLib.add(1n, 2n) == x, 'incorrect sum')
}
}
describe('Test SmartContractLib `Lib`', () => {
before(async() => {
await TestLib.compile()
})
it('should pass integration test successfully.', () => {
let testLib = new TestLib()
let result = testLib.verify(self => self.unlock(3n))
expect(result.success, result.error).to.be.true
}
})
```
## Create and Publish a Library Project Using sCrypt CLI
The following command will create a demo scryptTS library along with tests and scaffolding:
```sh
scrypt project --lib <your-lib-name>
```
Note the `lib` option is turned on.
You can publish the library on [NPM](https://www.npmjs.com/) by running the following command in the project's root directory:
```sh
npm publish
```
This will build the project and publish it on NPM. After the library is published, users can simply import it in any other project just like regular NPM packages.
:::note
Named imports are not supported yet. You should only import like the following.
:::
```ts
import { MyLib } from “my_package”
```
### Advanced
For the import system working properly, you should always publish the auto-generated sCrypt contracts (including `scrypt.index.json` file) along with the javascript outputs. The structure of the package could be like this:
```
node_modules
|__ my_package
|__ dist
|__ myLib.js
|__ myLib.d.ts
|__ artifacts
|__ myLib.scrypt
|__ scrypt.index.json
…
```
The `scrypt.index.json` file will be generated at TypeScript compile time in the same directory of your `tsconfig.json` which should be placed in the root folder. It shall not be moved or modified manually. The folder for auto-generated `.scrypt` files (`artifacts` in the upper file tree) can be changed by configuring the `outDir` option in `tsconfig.json`, like:
```json
"compilerOptions": {
"plugins": [
{
"transform": "scrypt-ts/dist/transformation/transformer",
"transformProgram": "true",
"outDir": "my_scrypts_dir"
}
]
}
```
You should always publish the auto-generated sCrypt files along with the package. If you are familiar with sCrypt development and want to apply some improvements to the auto-generated files, for example using an inline asm function to replace an ordinary function to reduce the final script size, you could just modify the auto-generated file as you wish before publishing it. Take a look at how [scrytp-ts-lib](https://github.com/sCrypt-Inc/scrypt-ts-lib/tree/master/optimizations) does it.
:::note
You should modify the auto-generated files with caution and make sure that the modification passes the tests.
:::
## Related Tools
### `scrypt-ts-lib`
It’s a collection of smart contract libraries provided by us. You can find some useful tools [here](https://github.com/sCrypt-Inc/scrypt-ts-lib). Also you are welcome to contribute.
|