-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #17 from nervina-labs/develop
Release v0.1.0
- Loading branch information
Showing
33 changed files
with
1,103 additions
and
149 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
#!/bin/sh | ||
. "$(dirname "$0")/_/husky.sh" | ||
|
||
yarn lint | ||
yarn lint | ||
yarn check |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,22 @@ | ||
# cota-sdk-js | ||
# cota-sdk-js | ||
|
||
[![License](https://img.shields.io/badge/license-MIT-green)](https://github.com/nervina-labs/cota-sdk-js/blob/develop/LICENSE) | ||
[![CI](https://github.com/nervina-labs/cota-sdk-js/actions/workflows/build.yml/badge.svg?branch=develop)](https://github.com/nervina-labs/cota-sdk-js/actions) | ||
[![NPM](https://img.shields.io/npm/v/@nervina-labs/cota-sdk/latest.svg)](https://www.npmjs.com/package/@nervina-labs/cota-sdk) | ||
|
||
JavaScript SDK for [CoTA](https://talk.nervos.org/t/rfc-cota-a-compact-token-aggregator-standard-for-extremely-low-cost-nfts-and-fts/6338). | ||
|
||
## Feature | ||
|
||
- Provide methods for [cota-aggregator](https://github.com/nervina-labs/cota-aggregator) and [cota-registry-aggregator](https://github.com/nervina-labs/cota-registry-aggregator) RPC APIs | ||
- Provide methods to generate CoTA operating transactions | ||
|
||
## Examples | ||
|
||
- [aggregator example](https://github.com/nervina-labs/cota-sdk-js/blob/develop/example/aggregator.ts): Fetch CoTA NFT data and [SMT](https://github.com/nervosnetwork/sparse-merkle-tree) data from Aggregator server | ||
- [registry example](https://github.com/nervina-labs/cota-sdk-js/blob/develop/example/define.ts): Generate defining CoTA cells transaction | ||
- [mint example](https://github.com/nervina-labs/cota-sdk-js/blob/develop/example/mint.ts): Generate minting CoTA NFT transaction | ||
- [claim example](https://github.com/nervina-labs/cota-sdk-js/blob/develop/example/claim.ts): Generate claiming CoTA NFT transaction | ||
- [withdraw example](https://github.com/nervina-labs/cota-sdk-js/blob/develop/example/withdraw.ts): Generate withdrawing CoTA NFT transaction | ||
- [transfer example](https://github.com/nervina-labs/cota-sdk-js/blob/develop/example/transfer.ts): Generate transferring CoTA NFT transaction | ||
- [update example](https://github.com/nervina-labs/cota-sdk-js/blob/develop/example/update.ts): Generate updating CoTA NFT information transaction |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,22 @@ | ||
const { Aggregator } = require("../lib/aggregator") | ||
const { Aggregator } = require('../lib/aggregator') | ||
|
||
const run = async () => { | ||
const aggregator = new Aggregator({registryUrl: "http://localhost:3050", cotaUrl: "http://localhost:3030"}) | ||
const aggregator = new Aggregator({ registryUrl: 'http://localhost:3050', cotaUrl: 'http://localhost:3030' }) | ||
const holds = await aggregator.getHoldCotaNft({ | ||
lockScript: "0x490000001000000030000000310000009bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce80114000000dc70f33de86fdf381b4fc5bf092bb23d02774801", | ||
lockScript: | ||
'0x490000001000000030000000310000009bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce80114000000dc70f33de86fdf381b4fc5bf092bb23d02774801', | ||
page: 0, | ||
pageSize: 10 | ||
pageSize: 10, | ||
}) | ||
console.log(JSON.stringify(holds)) | ||
|
||
const lock_hash = await aggregator.getCotaNftSender({ | ||
lockScript: "0x490000001000000030000000310000009bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce80114000000dc70f33de86fdf381b4fc5bf092bb23d02774801", | ||
cotaId: "0xb22585a8053af3fed0fd39127f5b1487ce08b756", | ||
tokenIndex: "0x00000000" | ||
const senderLockHash = await aggregator.getCotaNftSender({ | ||
lockScript: | ||
'0x490000001000000030000000310000009bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce80114000000dc70f33de86fdf381b4fc5bf092bb23d02774801', | ||
cotaId: '0xb22585a8053af3fed0fd39127f5b1487ce08b756', | ||
tokenIndex: '0x00000000', | ||
}) | ||
console.log(JSON.stringify(lock_hash)) | ||
console.log(JSON.stringify(senderLockHash)) | ||
} | ||
|
||
run() | ||
run() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,22 @@ | ||
import { Aggregator } from "../src/aggregator" | ||
import { Aggregator } from '../src/aggregator' | ||
|
||
const run = async () => { | ||
const aggregator = new Aggregator({registryUrl: "http://localhost:3050", cotaUrl: "http://localhost:3030"}) | ||
const aggregator = new Aggregator({ registryUrl: 'http://localhost:3050', cotaUrl: 'http://localhost:3030' }) | ||
const holds = await aggregator.getHoldCotaNft({ | ||
lockScript: "0x490000001000000030000000310000009bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce80114000000dc70f33de86fdf381b4fc5bf092bb23d02774801", | ||
lockScript: | ||
'0x490000001000000030000000310000009bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce80114000000dc70f33de86fdf381b4fc5bf092bb23d02774801', | ||
page: 0, | ||
pageSize: 10 | ||
pageSize: 10, | ||
}) | ||
console.log(JSON.stringify(holds)) | ||
|
||
const senderLockHash = await aggregator.getCotaNftSender({ | ||
lockScript: | ||
'0x490000001000000030000000310000009bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce80114000000dc70f33de86fdf381b4fc5bf092bb23d02774801', | ||
cotaId: '0xb22585a8053af3fed0fd39127f5b1487ce08b756', | ||
tokenIndex: '0x00000000', | ||
}) | ||
console.log(JSON.stringify(senderLockHash)) | ||
} | ||
|
||
run() | ||
run() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import { addressToScript } from '@nervosnetwork/ckb-sdk-utils' | ||
import { Collector } from '../src/collector' | ||
import { Aggregator } from '../src/aggregator' | ||
import { generateClaimCotaTx } from '../src/service/cota' | ||
import { Claim, Service } from '../src' | ||
import CKB from '@nervosnetwork/ckb-sdk-core' | ||
|
||
const TEST_ADDRESS = 'ckt1qyq0scej4vn0uka238m63azcel7cmcme7f2sxj5ska' | ||
const RECEIVER_PRIVATE_KEY = '0xcf56c11ce3fbec627e5118acd215838d1f9c5048039792d42143f933cde76311' | ||
const RECEIVER_ADDRESS = 'ckt1qyqdcu8n8h5xlhecrd8ut0cf9wer6qnhfqqsnz3lw9' | ||
|
||
const secp256k1CellDep = async (ckb: CKB): Promise<CKBComponents.CellDep> => { | ||
const secp256k1Dep = (await ckb.loadDeps()).secp256k1Dep | ||
return { outPoint: secp256k1Dep.outPoint, depType: 'depGroup' } | ||
} | ||
|
||
const run = async () => { | ||
const service: Service = { | ||
collector: new Collector({ ckbNodeUrl: 'http://localhost:8114', ckbIndexerUrl: 'http://localhost:8116' }), | ||
aggregator: new Aggregator({ registryUrl: 'http://localhost:3050', cotaUrl: 'http://localhost:3030' }), | ||
} | ||
const ckb = service.collector.getCkb() | ||
const claimLock = addressToScript(RECEIVER_ADDRESS) | ||
const withdrawLock = addressToScript(TEST_ADDRESS) | ||
|
||
const claims: Claim[] = [ | ||
{ | ||
cotaId: '0x1deb31f603652bf59ff5027b522e1d81c288b72f', | ||
tokenIndex: '0x00000000', | ||
}, | ||
] | ||
let rawTx = await generateClaimCotaTx(service, claimLock, withdrawLock, claims) | ||
|
||
const secp256k1Dep = await secp256k1CellDep(ckb) | ||
rawTx.cellDeps.push(secp256k1Dep) | ||
|
||
const signedTx = ckb.signTransaction(RECEIVER_PRIVATE_KEY)(rawTx) | ||
console.log(JSON.stringify(signedTx)) | ||
let txHash = await ckb.rpc.sendTransaction(signedTx, 'passthrough') | ||
console.info(`Claim cota nft tx has been sent with tx hash ${txHash}`) | ||
} | ||
|
||
run() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import { addressToScript, serializeWitnessArgs } from '@nervosnetwork/ckb-sdk-utils' | ||
import { Collector } from '../src/collector' | ||
import { Aggregator } from '../src/aggregator' | ||
import { generateDefineCotaTx } from '../src/service/cota' | ||
import { Service } from '../src' | ||
import { toSnakeCase } from '../src/utils' | ||
|
||
const TEST_ADDRESS = 'ckt1qpth5hjexr3wehtzqpm97dzzucgemjv7sl05wnez7y72hqvuszeyyqvz2vhrf3xz0jr8dcmxlv059kmpx4tt5vcluapd4' | ||
|
||
const run = async () => { | ||
const service: Service = { | ||
collector: new Collector({ ckbNodeUrl: 'http://localhost:8114', ckbIndexerUrl: 'http://localhost:8116' }), | ||
aggregator: new Aggregator({ registryUrl: 'http://localhost:3050', cotaUrl: 'http://localhost:3030' }), | ||
} | ||
const ckb = service.collector.getCkb() | ||
const defineLock = addressToScript(TEST_ADDRESS) | ||
let {rawTx, cotaId} = await generateDefineCotaTx(service, defineLock, 100, "0x00") | ||
console.log(`cotaId: ${cotaId}`) | ||
const flashsingerDep: CKBComponents.CellDep = { | ||
outPoint: { | ||
txHash: "0xb66776ff3244033fcd15312ae8b17d384c11bebbb923fce3bd896d89f4744d48", | ||
index: "0x0", | ||
}, | ||
depType: "depGroup" | ||
} | ||
rawTx.cellDeps.push(flashsingerDep) | ||
rawTx.witnesses = rawTx.witnesses.map(witness => witness !== '0x' ? serializeWitnessArgs(witness) : '0x') | ||
|
||
let signedTx = rawTx | ||
rawTx = toSnakeCase(rawTx) | ||
console.log(JSON.stringify(rawTx)) | ||
|
||
// TODO: Add witnesses signed by flashsigner | ||
signedTx.witnesses = ["flashsigner-signed-witness"] | ||
|
||
console.log(JSON.stringify(signedTx)) | ||
let txHash = await ckb.rpc.sendTransaction(signedTx, 'passthrough') | ||
console.info(`Define cota nft tx has been sent with tx hash ${txHash}`) | ||
} | ||
|
||
run() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { addressToScript } from '@nervosnetwork/ckb-sdk-utils' | ||
import { Collector } from '../src/collector' | ||
import { Aggregator } from '../src/aggregator' | ||
import { generateDefineCotaTx } from '../src/service/cota' | ||
import { Service } from '../src' | ||
import CKB from '@nervosnetwork/ckb-sdk-core' | ||
|
||
const TEST_PRIVATE_KEY = '0xc5bd09c9b954559c70a77d68bde95369e2ce910556ddc20f739080cde3b62ef2' | ||
const TEST_ADDRESS = 'ckt1qyq0scej4vn0uka238m63azcel7cmcme7f2sxj5ska' | ||
|
||
const secp256k1CellDep = async (ckb: CKB): Promise<CKBComponents.CellDep> => { | ||
const secp256k1Dep = (await ckb.loadDeps()).secp256k1Dep | ||
return { outPoint: secp256k1Dep.outPoint, depType: 'depGroup' } | ||
} | ||
|
||
const run = async () => { | ||
const service: Service = { | ||
collector: new Collector({ ckbNodeUrl: 'http://localhost:8114', ckbIndexerUrl: 'http://localhost:8116' }), | ||
aggregator: new Aggregator({ registryUrl: 'http://localhost:3050', cotaUrl: 'http://localhost:3030' }), | ||
} | ||
const ckb = service.collector.getCkb() | ||
const defineLock = addressToScript(TEST_ADDRESS) | ||
let {rawTx, cotaId} = await generateDefineCotaTx(service, defineLock, 100, "0x00") | ||
console.log(`cotaId: ${cotaId}`) | ||
const secp256k1Dep = await secp256k1CellDep(ckb) | ||
rawTx.cellDeps.push(secp256k1Dep) | ||
|
||
const signedTx = ckb.signTransaction(TEST_PRIVATE_KEY)(rawTx) | ||
console.log(JSON.stringify(signedTx)) | ||
let txHash = await ckb.rpc.sendTransaction(signedTx, 'passthrough') | ||
console.info(`Define cota nft tx has been sent with tx hash ${txHash}`) | ||
} | ||
|
||
run() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import { addressToScript, serializeScript } from '@nervosnetwork/ckb-sdk-utils' | ||
import { Collector } from '../src/collector' | ||
import { Aggregator } from '../src/aggregator' | ||
import { generateMintCotaTx } from '../src/service/cota' | ||
import { MintCotaInfo, Service } from '../src' | ||
import CKB from '@nervosnetwork/ckb-sdk-core' | ||
|
||
const TEST_PRIVATE_KEY = '0xc5bd09c9b954559c70a77d68bde95369e2ce910556ddc20f739080cde3b62ef2' | ||
const TEST_ADDRESS = 'ckt1qyq0scej4vn0uka238m63azcel7cmcme7f2sxj5ska' | ||
const RECEIVER_ADDRESS = 'ckt1qyqdcu8n8h5xlhecrd8ut0cf9wer6qnhfqqsnz3lw9' | ||
|
||
const secp256k1CellDep = async (ckb: CKB): Promise<CKBComponents.CellDep> => { | ||
const secp256k1Dep = (await ckb.loadDeps()).secp256k1Dep | ||
return { outPoint: secp256k1Dep.outPoint, depType: 'depGroup' } | ||
} | ||
|
||
const run = async () => { | ||
const service: Service = { | ||
collector: new Collector({ ckbNodeUrl: 'http://localhost:8114', ckbIndexerUrl: 'http://localhost:8116' }), | ||
aggregator: new Aggregator({ registryUrl: 'http://localhost:3050', cotaUrl: 'http://localhost:3030' }), | ||
} | ||
const ckb = service.collector.getCkb() | ||
const mintLock = addressToScript(TEST_ADDRESS) | ||
|
||
const mintCotaInfo: MintCotaInfo = { | ||
cotaId: "0x1deb31f603652bf59ff5027b522e1d81c288b72f", | ||
withdrawals: [ | ||
{ | ||
tokenIndex: '0x00000000', | ||
state: '0x00', | ||
characteristic: '0xa505050505050505050505050505050505050505', | ||
toLockScript: serializeScript(addressToScript(RECEIVER_ADDRESS)), | ||
}, | ||
{ | ||
tokenIndex: '0x00000001', | ||
state: '0x00', | ||
characteristic: '0xa505050505050505050505050505050505050505', | ||
toLockScript: serializeScript(addressToScript(RECEIVER_ADDRESS)), | ||
}, | ||
] | ||
} | ||
let rawTx = await generateMintCotaTx(service, mintLock, mintCotaInfo) | ||
|
||
const secp256k1Dep = await secp256k1CellDep(ckb) | ||
rawTx.cellDeps.push(secp256k1Dep) | ||
|
||
const signedTx = ckb.signTransaction(TEST_PRIVATE_KEY)(rawTx) | ||
console.log(JSON.stringify(signedTx)) | ||
let txHash = await ckb.rpc.sendTransaction(signedTx, 'passthrough') | ||
console.info(`Mint cota nft tx has been sent with tx hash ${txHash}`) | ||
} | ||
|
||
run() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
const { | ||
addressToScript, | ||
rawTransactionToHash, | ||
scriptToHash, | ||
serializeWitnessArgs, | ||
} = require('@nervosnetwork/ckb-sdk-utils') | ||
const { Collector } = require('../lib/collector') | ||
const { Aggregator } = require('../lib/aggregator') | ||
const { TestnetDeployment } = require('../lib/constants') | ||
const { generateRegisterCotaTx } = require('../lib/service/registry') | ||
const signWitnesses = require('@nervosnetwork/ckb-sdk-core/lib/signWitnesses') | ||
|
||
const TEST_PRIVATE_KEY = '0xc5bd09c9b954559c70a77d68bde95369e2ce910556ddc20f739080cde3b62ef2' | ||
const TEST_ADDRESS = 'ckt1qyq0scej4vn0uka238m63azcel7cmcme7f2sxj5ska' | ||
|
||
const secp256k1CellDep = async ckb => { | ||
const secp256k1Dep = (await ckb.loadDeps()).secp256k1Dep | ||
return { outPoint: secp256k1Dep.outPoint, depType: 'depGroup' } | ||
} | ||
|
||
const run = async () => { | ||
const service = { | ||
collector: new Collector({ ckbNodeUrl: 'http://localhost:8114', ckbIndexerUrl: 'http://localhost:8116' }), | ||
aggregator: new Aggregator({ registryUrl: 'http://localhost:3050', cotaUrl: 'http://localhost:3030' }), | ||
} | ||
const ckb = service.collector.getCkb() | ||
const provideCKBLock = addressToScript(TEST_ADDRESS) | ||
const unregisteredCotaLock = addressToScript(TEST_ADDRESS) | ||
let rawTx = await generateRegisterCotaTx(service, [unregisteredCotaLock], provideCKBLock) | ||
const secp256k1Dep = await secp256k1CellDep(ckb) | ||
rawTx.cellDeps.push(secp256k1Dep) | ||
|
||
const registryLock = TestnetDeployment.AlwaysSuccessLockScript | ||
|
||
let keyMap = new Map() | ||
keyMap.set(scriptToHash(registryLock), '') | ||
keyMap.set(scriptToHash(provideCKBLock), TEST_PRIVATE_KEY) | ||
|
||
const cells = rawTx.inputs.map((input, index) => ({ | ||
outPoint: input.previousOutput, | ||
lock: index === 0 ? registryLock : provideCKBLock, | ||
})) | ||
|
||
const transactionHash = rawTransactionToHash(rawTx) | ||
|
||
const signedWitnesses = signWitnesses(keyMap)({ | ||
transactionHash, | ||
witnesses: rawTx.witnesses, | ||
inputCells: cells, | ||
skipMissingKeys: true, | ||
}) | ||
const signedTx = { | ||
...rawTx, | ||
witnesses: signedWitnesses.map(witness => (typeof witness === 'string' ? witness : serializeWitnessArgs(witness))), | ||
} | ||
console.log(JSON.stringify(signedTx)) | ||
let txHash = await ckb.rpc.sendTransaction(signedTx, 'passthrough') | ||
console.log(`Register cota cell tx has been sent with tx hash ${txHash}`) | ||
} | ||
|
||
run() |
Oops, something went wrong.