Skip to content

Commit

Permalink
doc: further updating docs
Browse files Browse the repository at this point in the history
  • Loading branch information
Alive24 committed Jan 6, 2025
1 parent 0023bc7 commit f4559fe
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 100 deletions.
109 changes: 36 additions & 73 deletions packages/udt/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,90 +52,59 @@
<h2> Quick Start </h2>

- At the moment, `UDT` and `UDTPausable` from `@ckb-ccc/udt` are fully supported through SSRI. In the future, there will be built in TypeScript generation directly based on the Rust contract on compilation.
- To instantialize a `UDT` contract compliant with SSRI, you need to set up the SSRI server first, and also specify the OutPoint of the contract code. You can also directly instantialize a `UDTPausable` in the same way.
- To instantiate a `UDT` contract compliant with SSRI, you can provide the SSRI server url and also specify the OutPoint of the contract code. Alternatively, You can also instantiate a `UDT` contract in legacy mode that is compatible with xUDT by providing a `ccc.Script` which retrieves name, symbol, and decimals via `ckb-udt-indexer` (To be released).
- You can also instantiate a `UDTPausable` contract or other contracts (To be released) that extends from `UDT`.

```ts
import { udt } from "@ckb-ccc/udt";

const { signer } = useApp();
const contractOutPointTx: ccc.Hex = "0x4e2e832e0b1e7b5994681b621b00c1e65f577ee4b440ef95fa07db9bb3d50269";
const contractOutPointIndex = 0;
const SSRIServerURL:string = "http://localhost:9090"

const testSSRIServer = new ssri.Server(signer.client, SSRIServerURL);
const testOutPoint = {
txHash: contractOutPointTx,
index: parseInt(contractOutPointIndex)
};

const udtContract = new udt.UDT(testSSRIServer, testOutPoint);
const udtPausableContract = new udt.UDTPausable(testSSRIServer, testOutPoint);
```
Alternatively, you can instantiate an `UDT` contract even if it's an `xUDT` contract by using `udt.UDT.fallbackToXudt` as constructor. However, this only works for `UDT` contract.
```ts
import { udt } from "@ckb-ccc/udt";
import { ccc } from "@ckb-ccc/ccc";

const { signer } = useApp();
const xudtTypeScript = await ccc.Script.fromKnownScript(
signer.client,
ccc.KnownScript.XUdt,
"0xf8f94a13dfe1b87c10312fb9678ab5276eefbe1e0b2c62b4841b1f393494eff2",
);

// Or you can instantiate your own Type Script if it is compatible with sUDT or xUDT behaviors.
const fallbackScript = {
codeHash: xudtTypeScript.codeHash,
hashType: xudtTypeScript.hashType as ccc.HashType,
args: xudtTypeScript.args
} as ccc.Script;

const fallbackName: string = "SEAL for testing UDT";
const fallbackSymbol: string = "SEAL";
const fallbackDecimals: string = "6"

// TODO: When ckb-udt-indexer becomes available, providing fallbackScript would automatically retrieve name, symbol, and decimals.
const xudtFallbackContract = udt.UDT.fallbackToXudt(
signer.client,
fallbackScript,
fallbackName,
fallbackSymbol,
BigInt(fallbackDecimals),
)
const udtSSRI = new UDT(client,
{
ssriServerURL: "https://localhost:9090",
codeOutPoint: {
txHash: '0x4e2e832e0b1e7b5994681b621b00c1e65f577ee4b440ef95fa07db9bb3d50269',
index: 0
}
}
);

const udtLegacyXudt = new UDT(
client,
await ccc.Script.fromKnownScript(
signer.client,
ccc.KnownScript.XUdt,
"0xf8f94a13dfe1b87c10312fb9678ab5276eefbe1e0b2c62b4841b1f393494eff2"
)
);

const udtPausable = new UDTPausable(client, {
ssriServerURL: "https://localhost:9090",
codeOutPoint: {
txHash: '0x4e2e832e0b1e7b5994681b621b00c1e65f577ee4b440ef95fa07db9bb3d50269',
index: 0
}
});
```

You can directly call the methods in the contract:

```ts
const udtSymbol = await udtContract.symbol();
const pauseList = await udtPausableContract.enumeratePaused();

const udtSymbol = await udtSSRI.symbol();
const userAddress = await signer.getRecommendedAddress();
const balanceOfUser = await xudtFallbackContract.balanceOf(userAddress);
```
const balanceOfUser = await udtLegacyXudt.balanceOf(userAddress);

Some of the methods can return a `ccc.Transaction`, but you might need to call with the correct `ssri.CallParams,` based on the method's documentation:

```ts
/**
* Transfers UDT to specified addresses.
* @param {ccc.Transaction | undefined} [tx] - Transfer on the basis of an existing transaction to achieve combined actions. If not provided, a new transaction will be created.
* @param {ccc.Script} toLockArray - The array of lock scripts for the recipients.
* @param {number[]} toAmountArray - The array of amounts to be transferred.
* @param {ssri.CallParams} [params] - The parameters for the call.
* @returns {Promise<{ tx: Transaction }>} The transaction result.
* @tag Script - This method requires a script level call. The script is the target Type Script for the UDT.
* @tag Mutation - This method represents a mutation of the onchain state and will return a transaction to be sent.
* @tag Fallback - Supports xUDT fallback behavior when initialized with fallbackToXudt.
*/
async transfer(
tx: ccc.Transaction | undefined,
toLockArray: ccc.Script[],
toAmountArray: number[],
params?: ssri.CallParams,
): Promise<ccc.Transaction>
const pauseList = await udtPausable.enumeratePaused();
```

for example, you can call `transfer` with the following params:
Some of the methods can return a `ccc.Transaction`. For example, you can call `transfer` with the following params:

```ts
const receiver = await signer.getRecommendedAddress();
// The sender script for change
Expand All @@ -157,13 +126,7 @@ const codeCellDep : CellDepLike = {
depType: 'code',
}

const transferTx = await udtContract.transfer([receiverLock], [100], { script:
{
code_hash: usdiScript.codeHash,
hash_type: usdiScript.hashType,
args: usdiScript.args,
} as ssri.Script
})
const transferTx = await udtContract.transfer([receiverLock], [100], usdiScript)

await transferTx.completeInputsByUdt(signer, usdiScript)
const balanceDiff =
Expand All @@ -184,4 +147,4 @@ await transferTx.completeFeeBy(signer)
const transferTxHash = await signer.sendTransaction(transferTx)
```

Read the tutorial at [How to interact with an SSRI-compliant contract on chain](https://github.com/Alive24/ckb_ssri_sdk/wiki/How-to-interact-with-an-SSRI-compliant-contract-on-chain) for more details.
Read the tutorial at [How to interact with an SSRI-compliant contract on chain](https://github.com/Alive24/ckb_ssri_sdk/wiki/How-to-interact-with-an-SSRI-compliant-contract-on-chain) for more details.
3 changes: 1 addition & 2 deletions packages/udt/src/udt/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ const testOutPoint: OutPointLike = {

const testUDTContract = new UDT(
testClient,
"http://localhost:9090",
testOutPoint
{ssriServerURL: "http://localhost:9090", codeOutPoint: testOutPoint}
)

describe("UDT Test", () => {
Expand Down
44 changes: 21 additions & 23 deletions packages/udt/src/udt/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,27 +37,23 @@ export class UDT extends ssri.Contract {
* By default it is a SSRI-compliant UDT. By providing `xudtType`, it is compatible with the legacy xUDT.
*
* @param {ccc.Client} client - The CCC client instance used for blockchain interactions.
* @param {string} ssriServerURL - The URL of the SSRI server.
* @param {ccc.OutPointLike} codeOutPoint - The code out point defining the UDT contract's location.
* @param {ccc.Script} xudtType - The type script of the legacy xUDT. Take precedence over `ssriServerURL` and `codeOutPoint`.
* @param {{ssriServerURL: string, codeOutPoint: ccc.OutPointLike} | {xudtType: ccc.Script}} params - Either a SSRI server URL and code out point, or a legacy xUDT type script to instantiate a legacy xUDT contract.
* @param {string} params.ssriServerURL - The URL of the SSRI server.
* @param {ccc.OutPointLike} params.codeOutPoint - The code out point defining the UDT contract's location.
* @param {ccc.Script} params.xudtType - The type script of the legacy xUDT.
* @example
* ```typescript
* const udtSSRI = new UDT(client, "https://localhost:9090", { txHash: '0x...', index: 0 });
* const udtLegacyXudt = new UDT(client, undefined, undefined, xudtType);
* const udtSSRI = new UDT(client, { ssriServerURL: "https://localhost:9090", codeOutPoint: { txHash: '0x...', index: 0 } });
* const udtLegacyXudt = new UDT(client, { xudtType: xudtType });
* ```
*/
constructor(
client: ccc.Client,
ssriServerURL?: string,
codeOutPoint?: ccc.OutPointLike,
xudtType?: ccc.Script,
params: {ssriServerURL: string, codeOutPoint: ccc.OutPointLike} | {xudtType: ccc.Script},
) {
const ssriServer = new ssri.Server(client, ssriServerURL ?? "https://localhost:9090");
super(ssriServer, codeOutPoint ?? {
txHash: "0x",
index: 0,
} as ccc.OutPointLike);
if (xudtType) {
const ssriServer = 'xudtType' in params ? undefined : new ssri.Server(client, params.ssriServerURL);
super(ssriServer!, 'xudtType' in params ? { txHash: "0x00", index: 0 } : params.codeOutPoint);
if ('xudtType' in params) {
// TODO: Obtain the name, symbol, decimals, and icon from ckb-udt-indexer
throw new Error("ckb-udt-indexer is not implemented yet");
// legacyModeUDTContract.legacyModeConfigs = {
Expand All @@ -68,13 +64,13 @@ export class UDT extends ssri.Contract {
// icon,
// };
} else {
if (!codeOutPoint || !ssriServerURL) {
if (!('codeOutPoint' in params) || !('ssriServerURL' in params)) {
throw new Error(
"codeOutPoint and ssriServerURL are required unless in legacy mode",
);
}
const ssriServer = new ssri.Server(client, ssriServerURL);
super(ssriServer, codeOutPoint);
const ssriServer = new ssri.Server(client, params.ssriServerURL);
super(ssriServer, params.codeOutPoint);
this.client = client;
}
}
Expand Down Expand Up @@ -117,7 +113,7 @@ export class UDT extends ssri.Contract {
/**
* Retrieves the decimals of the UDT.
* @returns {Promise<ccc.Num>} The decimals of the UDT.
* @tag Legacy - Supports xUDT legacy.
* @tag Legacy - Supports xUDT legacy behavior.
*/
async decimals(): Promise<ccc.Num> {
let rawResult: ccc.Hex;
Expand Down Expand Up @@ -214,14 +210,16 @@ export class UDT extends ssri.Contract {
* depType: 'code',
* }
*
* const transferTx = await udtContract.transfer([receiverLock], [100], { script:
* const transferTx = await udtContract.transfer(
* [receiverLock],
* [100],
* {
* code_hash: usdiScript.codeHash,
* hash_type: usdiScript.hashType,
* args: usdiScript.args,
* } as ssri.Script
* })
*
* }
* )
*
* await transferTx.completeInputsByUdt(signer, usdiScript)
* const balanceDiff =
* (await transferTx.getInputsUdtBalance(signer.client, usdiScript)) -
Expand Down Expand Up @@ -388,7 +386,7 @@ export class UDT extends ssri.Contract {
/**
* Retrieves the icon of the UDT encoded in base64.
* @returns {Promise<ccc.Bytes>} The icon of the UDT.
* @tag Legacy - Supports xUDT legacy behavior when initialized with legacyToXudt.
* @tag Legacy - Supports xUDT legacy behavior.
*/
async icon(): Promise<ccc.Bytes> {
let rawResult: ccc.Hex;
Expand Down
26 changes: 24 additions & 2 deletions packages/udt/src/udtPausable/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,30 @@ import { udtPausableDataCodec, u832VecCodec } from "./advanced.js";
* @public
*/
export class UDTPausable extends UDT {
cache: Map<string, unknown> = new Map();

/**
* Unlike `UDT`, `UDTPausable` contract cannot be instantiated in legacy mode.
*/
legacyModeConfigs: undefined;
/**
* Constructs a new Pausable UDT (User Defined Token) contract instance.
* Unlike `UDT`, `UDTPausable` contract cannot be instantiated in legacy mode.
*
* @param {ccc.Client} client - The CCC client instance used for blockchain interactions.
* @param {{ssriServerURL: string, codeOutPoint: ccc.OutPointLike}} params - Configuration parameters
* @param {string} params.ssriServerURL - The URL of the SSRI server.
* @param {ccc.OutPointLike} params.codeOutPoint - The code out point defining the UDT contract's location.
* @example
* ```typescript
* const udtPausable = new UDTPausable(client, "https://localhost:9090", { txHash: '0x...', index: 0 });
* ```
*/
constructor(
client: ccc.Client,
params: {ssriServerURL: string, codeOutPoint: ccc.OutPointLike},
) {
super(client, params);
this.client = client;
}

/**
* Pauses the UDT for the specified lock hashes. Pausing/Unpause without lock hashes should take effect on the global level. Note that this method is only available if the pausable UDT uses external pause list.
Expand Down

0 comments on commit f4559fe

Please sign in to comment.