Skip to content

Commit

Permalink
Merge pull request #164 from nervina-labs/develop
Browse files Browse the repository at this point in the history
Release v0.11.0
  • Loading branch information
duanyytop authored May 19, 2023
2 parents 4c0fa4b + 5c4f7aa commit 0d10e62
Show file tree
Hide file tree
Showing 9 changed files with 132 additions and 6 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ name: CI

on:
pull_request: # trigger on pull requests
branches:
- develop
push:
branches: # array of glob patterns matching against refs/heads. Optional; defaults to all
- master # triggers on pushes that contain changes in master
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "cota-aggregator"
version = "0.10.9"
version = "0.11.0"
edition = "2018"

[dependencies]
Expand Down
47 changes: 46 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ https://cota.nervina.dev/aggregator
- [get_mint_cota_nft](#get_mint_cota_nft)
- [is_claimed](#is_claimed)
- [get_cota_nft_sender](#get_cota_nft_sender)
- [get_cota_nft_owner](#get_cota_nft_owner)
- [get_define_info](#get_define_info)
- [get_issuer_info](#get_issuer_info)
- [get_issuer_info_by_cota_id](#get_issuer_info_by_cota_id)
Expand Down Expand Up @@ -939,7 +940,7 @@ claimed - true for claimed and false fot unclaimed

### get_cota_nft_sender

Get the sender lock hash of the CoTA NFT
Get the sender lock hash and address of the CoTA NFT

#### Parameters

Expand Down Expand Up @@ -985,6 +986,50 @@ sender_address - The sender ckb address of the NFT
}
```

### get_cota_nft_owner

Get the owner address of the CoTA NFT

#### Parameters

```
cota_id - CoTA NFT Class Unique ID
token_index - The index of the NFT Class (increment from zero)
```

```shell
echo '{
"id":2,
"jsonrpc":"2.0",
"method":"get_cota_nft_owner",
"params":{
"cota_id":"0x2dd97617e685c0cd44b87cba7e8756ea67a721cd",
"token_index":"0x00000000"
}
}' \
| tr -d '\n' \
| curl -H 'content-type: application/json' -d @- \
http://localhost:3030
```

#### Response

```
block_number - The latest block number of cota-syncer
owner_address - The owner ckb address of the NFT
```

```json
{
"jsonrpc": "2.0",
"result": {
"block_number": 4397997,
"owner_address": "ckt1qzda0cr08m85hc8jlnfp3zer7xulejywt49kt2rr0vthywaa50xwsq2mvqpq923wn8tpkxalc0d095xv0wzfsqqzkfvyx"
},
"id": 2
}
```

### get_define_info

Get define CoTA NFT Class information(name, description, image, total, issued, configure etc.) by the cota_id
Expand Down
21 changes: 18 additions & 3 deletions src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ use crate::models::common::{
};
use crate::models::issuer::get_issuer_info_by_lock_hash;
use crate::models::joyid::get_joyid_info_by_lock_hash;
use crate::models::withdrawal::nft::get_cota_info_by_cota_id_token_index;
use crate::models::withdrawal::nft::{
get_cota_info_by_cota_id_token_index, get_receiver_lock_by_cota_id_and_token_index,
};
use crate::request::claim::{ClaimReq, ClaimUpdateReq, IsClaimedReq};
use crate::request::define::{DefineInfoReq, DefineReq};
use crate::request::extension::{ExtSocialReq, ExtSubkeysReq};
Expand All @@ -31,7 +33,7 @@ use crate::request::social::SocialUnlockReq;
use crate::request::subkey::SubKeyUnlockReq;
use crate::request::transfer::{TransferReq, TransferUpdateReq};
use crate::request::update::UpdateReq;
use crate::request::withdrawal::{SenderLockReq, WithdrawalReq};
use crate::request::withdrawal::{OwnerLockReq, SenderLockReq, WithdrawalReq};
use crate::request::witness::WitnessReq;
use crate::response::claim::{parse_claimed_response, parse_claimed_smt, parse_claimed_update_smt};
use crate::response::define::{parse_define_info, parse_define_smt};
Expand All @@ -47,7 +49,7 @@ use crate::response::transaction::{parse_cota_transactions, parse_history_transa
use crate::response::transfer::{parse_transfer_smt, parse_transfer_update_smt};
use crate::response::update::parse_update_smt;
use crate::response::withdrawal::{
parse_sender_response, parse_withdrawal_response, parse_withdrawal_smt,
parse_owner_response, parse_sender_response, parse_withdrawal_response, parse_withdrawal_smt,
};
use crate::response::witness::cota::parse_cota_witness;
use crate::utils::error;
Expand Down Expand Up @@ -235,6 +237,19 @@ pub async fn get_sender_account(params: Params) -> Result<Value, Error> {
parse_sender_response(sender_account, block_number).map_err(rpc_err)
}

pub async fn get_owner_account(params: Params) -> Result<Value, Error> {
info!("Get owner account request: {:?}", params);
let map: Map<String, Value> = Params::parse(params)?;
let OwnerLockReq {
cota_id,
token_index,
} = OwnerLockReq::from_map(&map).map_err(rpc_err)?;
let owner_lock =
get_receiver_lock_by_cota_id_and_token_index(cota_id, token_index).map_err(rpc_err)?;
let block_number = tip_number()?;
parse_owner_response(owner_lock, block_number).map_err(rpc_err)
}

pub async fn get_define_info(params: Params) -> Result<Value, Error> {
info!("Get define info request: {:?}", params);
let map: Map<String, Value> = Params::parse(params)?;
Expand Down
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ fn main() {
io.add_method("get_mint_cota_nft", fetch_mint_rpc);
io.add_method("is_claimed", is_claimed_rpc);
io.add_method("get_cota_nft_sender", get_sender_account);
io.add_method("get_cota_nft_owner", get_owner_account);
io.add_method("get_define_info", get_define_info);
io.add_method("get_issuer_info", get_issuer_info);
io.add_method("get_cota_nft_info", get_cota_nft_info);
Expand Down
37 changes: 37 additions & 0 deletions src/models/withdrawal/nft.rs
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,43 @@ pub fn get_sender_lock_by_script_id(
}
}

pub fn get_receiver_lock_by_cota_id_and_token_index(
cota_id_: [u8; 20],
token_index_: [u8; 4],
) -> Result<Vec<u8>, Error> {
let start_time = Local::now().timestamp_millis();
let cota_id_hex = hex::encode(cota_id_);
let token_index_u32 = u32::from_be_bytes(token_index_);
let cota_id_crc_u32 = generate_crc(cota_id_hex.as_bytes());
let receiver_lock_ids: Vec<i64> = withdraw_cota_nft_kv_pairs
.select(receiver_lock_script_id)
.filter(cota_id_crc.eq(cota_id_crc_u32))
.filter(token_index.eq(token_index_u32))
.filter(cota_id.eq(cota_id_hex))
.order(updated_at.desc())
.limit(1)
.load::<i64>(&get_conn())
.map_err(|e| {
error!("Query withdraw error: {}", e.to_string());
Error::DatabaseQueryError(e.to_string())
})?;
diff_time(
start_time,
"SQL get_receiver_lock_by_cota_id_and_token_index",
);
if let Some(receiver_lock_id) = receiver_lock_ids.first().cloned() {
let lock_opt = get_script_map_by_ids(vec![receiver_lock_id])?
.get(&receiver_lock_id)
.cloned();
match lock_opt {
Some(lock) => Ok(lock),
None => Ok(vec![]),
}
} else {
Ok(vec![])
}
}

fn parse_withdraw_db(withdrawals: Vec<WithdrawCotaNft>) -> DBResult<WithdrawDb> {
let block_height = get_syncer_tip_block_number()?;
if withdrawals.is_empty() {
Expand Down
15 changes: 15 additions & 0 deletions src/request/withdrawal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,18 @@ impl SenderLockReq {
})
}
}

#[derive(Clone, Eq, PartialEq)]
pub struct OwnerLockReq {
pub cota_id: [u8; 20],
pub token_index: [u8; 4],
}

impl OwnerLockReq {
pub fn from_map(map: &Map<String, Value>) -> Result<Self, Error> {
Ok(OwnerLockReq {
cota_id: map.get_hex_bytes_filed::<20>("cota_id")?,
token_index: map.get_hex_bytes_filed::<4>("token_index")?,
})
}
}
11 changes: 11 additions & 0 deletions src/response/withdrawal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,14 @@ pub fn parse_sender_response(
map.insert_u64("block_number", block_number);
Ok(Value::Object(map))
}

pub fn parse_owner_response(owner_lock: Vec<u8>, block_number: u64) -> Result<Value, Error> {
let mut map = Map::new();
if owner_lock.is_empty() {
map.insert_null("owner_address");
} else {
map.insert_str("owner_address", address_from_script(&owner_lock)?);
}
map.insert_u64("block_number", block_number);
Ok(Value::Object(map))
}

0 comments on commit 0d10e62

Please sign in to comment.