diff --git a/block_parser/das_action_create_sub_account.go b/block_parser/das_action_create_sub_account.go index 65072d0d..dc585f2c 100644 --- a/block_parser/das_action_create_sub_account.go +++ b/block_parser/das_action_create_sub_account.go @@ -62,7 +62,7 @@ func (b *BlockParser) DasActionCreateSubAccount(req FuncTransactionHandleReq) (r // add task and smt records if selfTask.TaskId != "" { // maybe rollback - if err := b.DbDao.UpdateToChainTask(selfTask.TaskId, req.BlockNumber); err != nil { + if err := b.DbDao.UpdateToChainTask(selfTask.TaskId, req.BlockNumber, 0); err != nil { resp.Err = fmt.Errorf("UpdateToChainTask err: %s", err.Error()) return } diff --git a/block_parser/das_action_edit_sub_account.go b/block_parser/das_action_edit_sub_account.go index 5c3ab019..1ed23143 100644 --- a/block_parser/das_action_edit_sub_account.go +++ b/block_parser/das_action_edit_sub_account.go @@ -41,7 +41,7 @@ func (b *BlockParser) DasActionEditSubAccount(req FuncTransactionHandleReq) (res // add task and smt records if selfTask.TaskId != "" { // maybe rollback - if err := b.DbDao.UpdateToChainTask(selfTask.TaskId, req.BlockNumber); err != nil { + if err := b.DbDao.UpdateToChainTask(selfTask.TaskId, req.BlockNumber, 0); err != nil { resp.Err = fmt.Errorf("UpdateToChainTask err: %s", err.Error()) return } diff --git a/block_parser/das_action_update_sub_account.go b/block_parser/das_action_update_sub_account.go index baeeac60..9512699d 100644 --- a/block_parser/das_action_update_sub_account.go +++ b/block_parser/das_action_update_sub_account.go @@ -10,6 +10,7 @@ import ( "github.com/dotbitHQ/das-lib/common" "github.com/dotbitHQ/das-lib/core" "github.com/dotbitHQ/das-lib/witness" + "github.com/shopspring/decimal" "gorm.io/gorm" ) @@ -40,9 +41,15 @@ func (b *BlockParser) DasActionUpdateSubAccount(req FuncTransactionHandleReq) (r parentAccountId = common.Bytes2Hex(v.Type.Args) } } + // get quote cell + quote, err := b.DasCore.GetTxQuote(req.Tx) + if err != nil { + resp.Err = fmt.Errorf("GetTxQuote err: %s", err.Error()) + return + } // get task , smt-record - taskInfo, smtRecordList, err := b.getTaskAndSmtRecordsNew(b.Slb, &req, parentAccountId, refOutpoint, outpoint) + taskInfo, smtRecordList, err := b.getTaskAndSmtRecordsNew(b.Slb, &req, parentAccountId, refOutpoint, outpoint, quote) if err != nil { resp.Err = fmt.Errorf("getTaskAndSmtRecordsNew err: %s", err.Error()) return @@ -57,7 +64,7 @@ func (b *BlockParser) DasActionUpdateSubAccount(req FuncTransactionHandleReq) (r // add task and smt records if selfTask.TaskId != "" { - if err := b.DbDao.UpdateToChainTask(selfTask.TaskId, req.BlockNumber); err != nil { + if err := b.DbDao.UpdateToChainTask(selfTask.TaskId, req.BlockNumber, quote); err != nil { resp.Err = fmt.Errorf("UpdateToChainTask err: %s", err.Error()) return } @@ -194,7 +201,7 @@ func (b *BlockParser) getOutpoint(req FuncTransactionHandleReq, dasContractName return refOutpoint, outpoint, nil } -func (b *BlockParser) getTaskAndSmtRecordsNew(slb *lb.LoadBalancing, req *FuncTransactionHandleReq, parentAccountId, refOutpoint, outpoint string) (*tables.TableTaskInfo, []tables.TableSmtRecordInfo, error) { +func (b *BlockParser) getTaskAndSmtRecordsNew(slb *lb.LoadBalancing, req *FuncTransactionHandleReq, parentAccountId, refOutpoint, outpoint string, quote uint64) (*tables.TableTaskInfo, []tables.TableSmtRecordInfo, error) { svrName := "" if slb != nil { s := slb.GetServer(parentAccountId) @@ -249,6 +256,7 @@ func (b *BlockParser) getTaskAndSmtRecordsNew(slb *lb.LoadBalancing, req *FuncTr SubAction: v.Action, MintSignId: "", ExpiredAt: v.SignExpiredAt, + Quote: decimal.NewFromInt(int64(quote)), } switch v.Action { case common.SubActionCreate: diff --git a/config/config.go b/config/config.go index 25e9ad5b..3bad9f20 100644 --- a/config/config.go +++ b/config/config.go @@ -140,3 +140,14 @@ func GetUnipayAddress(tokenId tables.TokenId) string { } return "" } + +func PriceToCKB(price, quote, years uint64) (total uint64) { + log.Info("PriceToCKB:", price, quote, years) + if price > quote { + total = price / quote * common.OneCkb * years + } else { + total = price * common.OneCkb / quote * years + } + log.Info("PriceToCKB:", price, quote, total) + return +} diff --git a/dao/t_smt_record_info.go b/dao/t_smt_record_info.go index f635ed9c..21d8e2c2 100644 --- a/dao/t_smt_record_info.go +++ b/dao/t_smt_record_info.go @@ -162,7 +162,19 @@ func (d *DbDao) FindSmtRecordInfoByActions(parentAccountId string, actions, subA func (d *DbDao) GetSmtRecordManualMintYears(parentAccountId string) (total uint64, err error) { err = d.db.Model(&tables.TableSmtRecordInfo{}).Select("IFNULL(sum(register_years+renew_years),0)"). - Where("parent_account_id=? and mint_type in (?) and sub_action in (?) and record_type=?", + Where("parent_account_id=? and mint_type in (?) and sub_action in (?) and record_type=? and quote=0", + parentAccountId, []tables.MintType{tables.MintTypeDefault, tables.MintTypeManual}, + []common.DasAction{common.SubActionCreate, common.SubActionRenew}, tables.RecordTypeChain).Scan(&total).Error + if err == gorm.ErrRecordNotFound { + err = nil + } + return +} + +func (d *DbDao) GetSmtRecordManualCKB(parentAccountId string) (total uint64, err error) { + err = d.db.Model(&tables.TableSmtRecordInfo{}). + Select("IFNULL(sum(round(990000/quote,0)*(register_years+renew_years)),0)"). + Where("parent_account_id=? and mint_type in (?) and sub_action in (?) and record_type=? and quote>0", parentAccountId, []tables.MintType{tables.MintTypeDefault, tables.MintTypeManual}, []common.DasAction{common.SubActionCreate, common.SubActionRenew}, tables.RecordTypeChain).Scan(&total).Error if err == gorm.ErrRecordNotFound { diff --git a/dao/t_sub_account_auto_mint_statement.go b/dao/t_sub_account_auto_mint_statement.go index 8c0413d6..996a3a97 100644 --- a/dao/t_sub_account_auto_mint_statement.go +++ b/dao/t_sub_account_auto_mint_statement.go @@ -33,6 +33,15 @@ func (d *DbDao) GetLatestSubAccountAutoMintStatementByType(providerId string, tx return } +func (d *DbDao) GetLatestSubAccountAutoMintStatementByType2(providerId, parentAccountId string, txType tables.SubAccountAutoMintTxType) (info tables.TableSubAccountAutoMintStatement, err error) { + err = d.parserDb.Where("service_provider_id=? and parent_account_id=? and tx_type=?", + providerId, parentAccountId, txType).Order("id desc").First(&info).Error + if err == gorm.ErrRecordNotFound { + err = nil + } + return +} + func (d *DbDao) FindSubAccountAutoMintStatements(providerId string, txType tables.SubAccountAutoMintTxType, blockNumber uint64) (list []*tables.TableSubAccountAutoMintStatement, err error) { err = d.parserDb.Where("service_provider_id=? and tx_type=? and block_number > ?", providerId, txType, blockNumber).Find(&list).Error if err == gorm.ErrRecordNotFound { @@ -40,3 +49,12 @@ func (d *DbDao) FindSubAccountAutoMintStatements(providerId string, txType table } return } + +func (d *DbDao) FindSubAccountAutoMintStatements2(providerId, parentAccountId string, txType tables.SubAccountAutoMintTxType, blockNumber uint64) (list []*tables.TableSubAccountAutoMintStatement, err error) { + err = d.parserDb.Where("service_provider_id=? and parent_account_id=? and tx_type=? and block_number > ?", + providerId, parentAccountId, txType, blockNumber).Find(&list).Error + if err == gorm.ErrRecordNotFound { + err = nil + } + return +} diff --git a/dao/t_task_info.go b/dao/t_task_info.go index c39389c4..e348fa56 100644 --- a/dao/t_task_info.go +++ b/dao/t_task_info.go @@ -179,7 +179,7 @@ func (d *DbDao) CreateChainTask(task *tables.TableTaskInfo, list []tables.TableS }) } -func (d *DbDao) UpdateToChainTask(taskId string, blockNumber uint64) error { +func (d *DbDao) UpdateToChainTask(taskId string, blockNumber, quote uint64) error { return d.db.Transaction(func(tx *gorm.DB) error { if err := tx.Model(tables.TableTaskInfo{}).Where("task_id=?", taskId). Updates(map[string]interface{}{ @@ -194,7 +194,8 @@ func (d *DbDao) UpdateToChainTask(taskId string, blockNumber uint64) error { Where("task_id=?", taskId). Updates(map[string]interface{}{ "record_type": tables.RecordTypeChain, - "RecordBN": blockNumber, + "record_bn": blockNumber, + "quote": quote, }).Error; err != nil { return err } diff --git a/example/api_internal_test.go b/example/api_internal_test.go index 5adfa7f8..f891a79d 100644 --- a/example/api_internal_test.go +++ b/example/api_internal_test.go @@ -31,7 +31,7 @@ func TestInternalSubAccountMint(t *testing.T) { Account: "10086.bit", SubAccountList: []handle.CreateSubAccount{ { - Account: "test1.10086.bit", + Account: "test12.10086.bit", RegisterYears: 1, ChainTypeAddress: core.ChainTypeAddress{ Type: "blockchain", @@ -43,7 +43,7 @@ func TestInternalSubAccountMint(t *testing.T) { }, }, { - Account: "test2.10086.bit", + Account: "test22.10086.bit", RegisterYears: 2, ChainTypeAddress: core.ChainTypeAddress{ Type: "blockchain", diff --git a/example/custom_script_test.go b/example/custom_script_test.go index f3cc61d2..e5031c34 100644 --- a/example/custom_script_test.go +++ b/example/custom_script_test.go @@ -10,6 +10,7 @@ import ( "github.com/dotbitHQ/das-lib/molecule" "github.com/dotbitHQ/das-lib/witness" "github.com/nervosnetwork/ckb-sdk-go/types" + "github.com/scorpiotzh/toolib" "testing" ) @@ -34,6 +35,7 @@ func TestCustomScript(t *testing.T) { 5: {1000000, 1000000}, }, } + fmt.Println(toolib.JsonString(&req)) var data handle.RespCustomScript if err := doReq(url, req, &data); err != nil { t.Fatal(err) @@ -128,3 +130,25 @@ func TestCustomScriptPrice(t *testing.T) { } } + +func TestPrice(t *testing.T) { + dc, err := getNewDasCoreTestnet2() + if err != nil { + t.Fatal(err) + } + qCell, err := dc.GetQuoteCell() + if err != nil { + t.Fatal(err) + } + fmt.Println(qCell.Quote()) + quote := uint64(12632) //0.012632 + yearlyPrice := uint64(12000) //uint64(990000) //0.99 + if yearlyPrice < quote { + fmt.Println("<", yearlyPrice*common.OneCkb/quote*1) + //fmt.Println(">", yearlyPrice/quote*common.OneCkb*1) + } else { + //fmt.Println("<", yearlyPrice*common.OneCkb/quote*1) + fmt.Println(">", yearlyPrice/quote*common.OneCkb*1) + } + +} diff --git a/go.mod b/go.mod index 369a2e5e..19e922b6 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module das_sub_account go 1.18 require ( - github.com/dotbitHQ/das-lib v1.1.1-0.20230915031854-7f69edfd6582 + github.com/dotbitHQ/das-lib v1.1.1-0.20231008024610-0511cd287954 github.com/fsnotify/fsnotify v1.5.4 github.com/getsentry/sentry-go v0.24.0 github.com/gin-gonic/gin v1.9.0 diff --git a/go.sum b/go.sum index 87528078..19cbba66 100644 --- a/go.sum +++ b/go.sum @@ -143,8 +143,8 @@ github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5O github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/dop251/goja v0.0.0-20211011172007-d99e4b8cbf48/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= -github.com/dotbitHQ/das-lib v1.1.1-0.20230915031854-7f69edfd6582 h1:QVovYJfsPq5qRKD0MkOh91+8p8lWdkEFmkh/+/S/c94= -github.com/dotbitHQ/das-lib v1.1.1-0.20230915031854-7f69edfd6582/go.mod h1:bWgGqfGuc9moidjzK7MpC0q80d694ucm0961MEMNiaI= +github.com/dotbitHQ/das-lib v1.1.1-0.20231008024610-0511cd287954 h1:WcuZsczQ6/tm8nSWehmhDiczq0IPV4ZqqfE6Jjyg7bE= +github.com/dotbitHQ/das-lib v1.1.1-0.20231008024610-0511cd287954/go.mod h1:bWgGqfGuc9moidjzK7MpC0q80d694ucm0961MEMNiaI= github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/elazarl/goproxy v0.0.0-20221015165544-a0805db90819 h1:RIB4cRk+lBqKK3Oy0r2gRX4ui7tuhiZq2SuTtTCi0/0= diff --git a/http_server/handle/auto_account_search.go b/http_server/handle/auto_account_search.go index a2e6e390..42241ebb 100644 --- a/http_server/handle/auto_account_search.go +++ b/http_server/handle/auto_account_search.go @@ -7,6 +7,7 @@ import ( "github.com/dotbitHQ/das-lib/common" "github.com/dotbitHQ/das-lib/core" api_code "github.com/dotbitHQ/das-lib/http_api" + "github.com/dotbitHQ/das-lib/molecule" "github.com/dotbitHQ/das-lib/witness" "github.com/gin-gonic/gin" "github.com/nervosnetwork/ckb-sdk-go/types" @@ -120,6 +121,22 @@ func (h *HttpHandle) doAutoAccountSearch(req *ReqAutoAccountSearch, apiResp *api } else if apiResp.ErrNo != api_code.ApiCodeSuccess { return nil } + // check min price 0.99$ + builder, err := h.DasCore.ConfigCellDataBuilderByTypeArgsList(common.ConfigCellTypeArgsSubAccount) + if err != nil { + apiResp.ApiRespErr(api_code.ApiCodeError500, "Failed to get config info") + return fmt.Errorf("ConfigCellDataBuilderByTypeArgsList err: %s", err.Error()) + } + newSubAccountPrice, _ := molecule.Bytes2GoU64(builder.ConfigCellSubAccount.NewSubAccountPrice().RawData()) + minPrice := decimal.NewFromInt(int64(newSubAccountPrice)).DivRound(decimal.NewFromInt(common.UsdRateBase), 2) + if req.ActionType == tables.ActionTypeRenew { + renewSubAccountPrice, _ := molecule.Bytes2GoU64(builder.ConfigCellSubAccount.RenewSubAccountPrice().RawData()) + minPrice = decimal.NewFromInt(int64(renewSubAccountPrice)).DivRound(decimal.NewFromInt(common.UsdRateBase), 2) + } + if minPrice.GreaterThan(resp.Price) { + apiResp.ApiRespErr(api_code.ApiCodePriceRulePriceNotBeLessThanMin, "Pricing below minimum") + return fmt.Errorf("price not be less than min: %s$", minPrice.String()) + } resp.PremiumPercentage = config.Cfg.Stripe.PremiumPercentage resp.PremiumBase = config.Cfg.Stripe.PremiumBase diff --git a/http_server/handle/auto_order_create.go b/http_server/handle/auto_order_create.go index f667c6de..898edb9f 100644 --- a/http_server/handle/auto_order_create.go +++ b/http_server/handle/auto_order_create.go @@ -8,6 +8,7 @@ import ( "github.com/dotbitHQ/das-lib/common" "github.com/dotbitHQ/das-lib/core" api_code "github.com/dotbitHQ/das-lib/http_api" + "github.com/dotbitHQ/das-lib/molecule" "github.com/gin-gonic/gin" "github.com/scorpiotzh/toolib" "github.com/shopspring/decimal" @@ -122,7 +123,6 @@ func (h *HttpHandle) doAutoOrderCreate(req *ReqAutoOrderCreate, apiResp *api_cod apiResp.ApiRespErr(api_code.ApiCodeBeyondMaxYears, "The main account is valid for less than one year") return nil } - // get rule price usdAmount, err := h.getRulePrice(parentAccount.Account, parentAccountId, req.SubAccount, apiResp) if err != nil { @@ -138,6 +138,23 @@ func (h *HttpHandle) doAutoOrderCreate(req *ReqAutoOrderCreate, apiResp *api_cod apiResp.ApiRespErr(api_code.ApiCodeTokenIdNotSupported, "payment method not supported") return nil } + // check min price 0.99$ + builder, err := h.DasCore.ConfigCellDataBuilderByTypeArgsList(common.ConfigCellTypeArgsSubAccount) + if err != nil { + apiResp.ApiRespErr(api_code.ApiCodeError500, "Failed to get config info") + return fmt.Errorf("ConfigCellDataBuilderByTypeArgsList err: %s", err.Error()) + } + newSubAccountPrice, _ := molecule.Bytes2GoU64(builder.ConfigCellSubAccount.NewSubAccountPrice().RawData()) + minPrice := decimal.NewFromInt(int64(newSubAccountPrice)).DivRound(decimal.NewFromInt(common.UsdRateBase), 2) + if req.ActionType == tables.ActionTypeRenew { + renewSubAccountPrice, _ := molecule.Bytes2GoU64(builder.ConfigCellSubAccount.RenewSubAccountPrice().RawData()) + minPrice = decimal.NewFromInt(int64(renewSubAccountPrice)).DivRound(decimal.NewFromInt(common.UsdRateBase), 2) + } + if minPrice.GreaterThan(usdAmount) { + apiResp.ApiRespErr(api_code.ApiCodePriceRulePriceNotBeLessThanMin, "Pricing below minimum") + return fmt.Errorf("price not be less than min: %s$", minPrice.String()) + } + log.Info("usdAmount:", usdAmount.String(), req.Years) usdAmount = usdAmount.Mul(decimal.NewFromInt(int64(req.Years))) //log.Info("usdAmount:", usdAmount.String(), req.Years) diff --git a/http_server/handle/config_info.go b/http_server/handle/config_info.go index c88fa30a..20976df6 100644 --- a/http_server/handle/config_info.go +++ b/http_server/handle/config_info.go @@ -22,9 +22,9 @@ type RespConfigInfo struct { PaymentMinPrice int64 `json:"payment_min_price"` ServiceFeeRatio string `json:"service_fee_ratio"` } `json:"auto_mint"` - MintCostsManually uint64 `json:"mint_costs_manually"` - RenewCostsManually uint64 `json:"renew_costs_manually"` - ManagementTimes uint64 `json:"management_times"` + MintCostsManually decimal.Decimal `json:"mint_costs_manually"` + RenewCostsManually decimal.Decimal `json:"renew_costs_manually"` + ManagementTimes uint64 `json:"management_times"` } func (h *HttpHandle) ConfigInfo(ctx *gin.Context) { @@ -57,13 +57,15 @@ func (h *HttpHandle) doConfigInfo(apiResp *api_code.ApiResp) error { } resp.SubAccountBasicCapacity, _ = molecule.Bytes2GoU64(builder.ConfigCellSubAccount.BasicCapacity().RawData()) resp.SubAccountPreparedFeeCapacity, _ = molecule.Bytes2GoU64(builder.ConfigCellSubAccount.PreparedFeeCapacity().RawData()) - resp.SubAccountNewSubAccountPrice, _ = molecule.Bytes2GoU64(builder.ConfigCellSubAccount.NewSubAccountPrice().RawData()) - resp.SubAccountRenewSubAccountPrice, _ = molecule.Bytes2GoU64(builder.ConfigCellSubAccount.RenewSubAccountPrice().RawData()) resp.SubAccountCommonFee, _ = molecule.Bytes2GoU64(builder.ConfigCellSubAccount.CommonFee().RawData()) - resp.MintCostsManually, _ = molecule.Bytes2GoU64(builder.ConfigCellSubAccount.NewSubAccountPrice().RawData()) - resp.RenewCostsManually, _ = molecule.Bytes2GoU64(builder.ConfigCellSubAccount.RenewSubAccountPrice().RawData()) resp.ManagementTimes = 10000 + mintPrice, _ := builder.NewSubAccountPrice() + renewPrice, _ := builder.RenewSubAccountPrice() + + resp.MintCostsManually = decimal.NewFromInt(int64(mintPrice)).DivRound(decimal.NewFromInt(common.UsdRateBase), 2) + resp.RenewCostsManually = decimal.NewFromInt(int64(renewPrice)).DivRound(decimal.NewFromInt(common.UsdRateBase), 2) + quoteCell, err := h.DasCore.GetQuoteCell() if err != nil { apiResp.ApiRespErr(api_code.ApiCodeError500, err.Error()) @@ -71,6 +73,8 @@ func (h *HttpHandle) doConfigInfo(apiResp *api_code.ApiResp) error { } quote := decimal.NewFromInt(int64(quoteCell.Quote())) resp.CkbQuote = quote.Div(decimal.NewFromInt(int64(common.OneCkb))).String() + resp.SubAccountNewSubAccountPrice = config.PriceToCKB(mintPrice, quoteCell.Quote(), 1) + resp.SubAccountRenewSubAccountPrice = config.PriceToCKB(renewPrice, quoteCell.Quote(), 1) resp.AutoMint.PaymentMinPrice = config.Cfg.Das.AutoMint.PaymentMinPrice resp.AutoMint.ServiceFeeRatio = fmt.Sprintf("%s%%", decimal.NewFromFloat(config.Cfg.Das.AutoMint.ServiceFeeRatio*100).String()) diff --git a/http_server/handle/price_rule_update.go b/http_server/handle/price_rule_update.go index fe32833e..ecb7c3ed 100644 --- a/http_server/handle/price_rule_update.go +++ b/http_server/handle/price_rule_update.go @@ -272,11 +272,11 @@ func (h *HttpHandle) rulesTxAssemble(params RulesTxAssembleParams) (*txbuilder.B return nil, nil, err } - token, err := h.DbDao.GetTokenById(tables.TokenIdCkb) - if err != nil { - params.ApiResp.ApiRespErr(api_code.ApiCodeError500, err.Error()) - return nil, nil, err - } + //token, err := h.DbDao.GetTokenById(tables.TokenIdCkb) + //if err != nil { + // params.ApiResp.ApiRespErr(api_code.ApiCodeError500, err.Error()) + // return nil, nil, err + //} builder, err := h.DasCore.ConfigCellDataBuilderByTypeArgsList(common.ConfigCellTypeArgsSubAccount) if err != nil { @@ -296,14 +296,16 @@ func (h *HttpHandle) rulesTxAssemble(params RulesTxAssembleParams) (*txbuilder.B } if math.Round(v.Price*10000)/10000 != v.Price { - err = errors.New("price most be two decimal places") + err = errors.New("price most be four decimal places") params.ApiResp.ApiRespErr(api_code.ApiCodePriceMostReserveTwoDecimal, err.Error()) return nil, nil, err } - price := decimal.NewFromInt(int64(newSubAccountPrice)).Mul(token.Price).Div(decimal.NewFromFloat(math.Pow10(int(token.Decimals)))) + // check min price 0.99$ + price := decimal.NewFromInt(int64(newSubAccountPrice)).DivRound(decimal.NewFromInt(common.UsdRateBase), 2) + //price := decimal.NewFromInt(int64(newSubAccountPrice)).Mul(token.Price).Div(decimal.NewFromFloat(math.Pow10(int(token.Decimals)))) if price.GreaterThan(decimal.NewFromFloat(v.Price)) { - err = fmt.Errorf("price not be less than min: %s$", price) + err = fmt.Errorf("price not be less than min: %s$", price.String()) params.ApiResp.ApiRespErr(api_code.ApiCodePriceRulePriceNotBeLessThanMin, err.Error()) return nil, nil, err } diff --git a/http_server/handle/service_provider_withdraw2.go b/http_server/handle/service_provider_withdraw2.go new file mode 100644 index 00000000..90a31cd6 --- /dev/null +++ b/http_server/handle/service_provider_withdraw2.go @@ -0,0 +1,229 @@ +package handle + +import ( + "das_sub_account/config" + "das_sub_account/internal" + "das_sub_account/tables" + "das_sub_account/txtool" + "fmt" + "github.com/dotbitHQ/das-lib/common" + "github.com/dotbitHQ/das-lib/core" + api_code "github.com/dotbitHQ/das-lib/http_api" + "github.com/dotbitHQ/das-lib/txbuilder" + "github.com/dotbitHQ/das-lib/witness" + "github.com/gin-gonic/gin" + "github.com/nervosnetwork/ckb-sdk-go/address" + "github.com/nervosnetwork/ckb-sdk-go/types" + "github.com/scorpiotzh/toolib" + "github.com/shopspring/decimal" + "net/http" + "time" +) + +type ReqServiceProviderWithdraw2 struct { + ServiceProviderAddress string `json:"service_provider_address" binding:"required"` + Account string `json:"account" binding:"required"` + Withdraw bool `json:"withdraw"` +} + +type RespServiceProviderWithdraw2 struct { + Hash string `json:"hash"` +} + +func (h *HttpHandle) ServiceProviderWithdraw2(ctx *gin.Context) { + var ( + funcName = "ServiceProviderWithdraw2" + clientIp, remoteAddrIP = GetClientIp(ctx) + req ReqServiceProviderWithdraw2 + apiResp api_code.ApiResp + err error + ) + + if err := ctx.ShouldBindJSON(&req); err != nil { + log.Error("ShouldBindJSON err: ", err.Error(), funcName, clientIp, remoteAddrIP) + apiResp.ApiRespErr(api_code.ApiCodeParamsInvalid, "params invalid") + ctx.JSON(http.StatusOK, apiResp) + return + } + log.Info("ApiReq:", funcName, clientIp, toolib.JsonString(req)) + + //time.Sleep(time.Minute * 3) + if err = h.doServiceProviderWithdraw2(&req, &apiResp); err != nil { + log.Error("doServiceProviderWithdraw2 err:", err.Error(), funcName, clientIp) + } + + ctx.JSON(http.StatusOK, apiResp) +} + +func (h *HttpHandle) doServiceProviderWithdraw2(req *ReqServiceProviderWithdraw2, apiResp *api_code.ApiResp) error { + var resp RespServiceProviderWithdraw2 + + if err := h.checkSystemUpgrade(apiResp); err != nil { + return fmt.Errorf("checkSystemUpgrade err: %s", err.Error()) + } + if ok := internal.IsLatestBlockNumber(config.Cfg.Server.ParserUrl); !ok { + apiResp.ApiRespErr(api_code.ApiCodeSyncBlockNumber, "sync block number") + return fmt.Errorf("sync block number") + } + + // + if hash, err := h.buildServiceProviderWithdraw2Tx(req); err != nil { + apiResp.ApiRespErr(api_code.ApiCodeError500, err.Error()) + return fmt.Errorf("buildServiceProviderWithdraw2Tx err: %s", err.Error()) + } else { + resp.Hash = hash + } + + apiResp.ApiRespOK(resp) + return nil +} + +func (h *HttpHandle) buildServiceProviderWithdraw2Tx(req *ReqServiceProviderWithdraw2) (string, error) { + spAddr, err := address.Parse(req.ServiceProviderAddress) + if err != nil { + return "", fmt.Errorf("address.Parse err: %s", err.Error()) + } + parentAccountId := common.Bytes2Hex(common.GetAccountIdByAccount(req.Account)) + providerId := common.Bytes2Hex(spAddr.Script.Args) + + latestExpenditure, err := h.DbDao.GetLatestSubAccountAutoMintStatementByType2(providerId, parentAccountId, tables.SubAccountAutoMintTxTypeExpenditure) + if err != nil { + return "", fmt.Errorf("GetLatestSubAccountAutoMintStatementByType2 err: %s", err.Error()) + } + + list, err := h.DbDao.FindSubAccountAutoMintStatements2(providerId, parentAccountId, tables.SubAccountAutoMintTxTypeIncome, latestExpenditure.BlockNumber) + if err != nil { + return "", fmt.Errorf("FindSubAccountAutoMintStatements err: %s", err.Error()) + } + if len(list) == 0 { + return "", nil + } + // testnet 2023-09-15 + minPrice := uint64(990000) + amount := decimal.Zero + for _, v := range list { + log.Info(v.ServiceProviderId, v.Quote, v.Years, v.Price) + if v.Quote.Cmp(decimal.Zero) == 0 || v.Years == 0 { + amount = amount.Add(v.Price) + continue + } + minCKB := decimal.NewFromInt(int64(config.PriceToCKB(minPrice, uint64(v.Quote.IntPart()), v.Years))) + backCKB := v.Price.Sub(minCKB) + if backCKB.Cmp(decimal.Zero) == 1 { + amount = amount.Add(backCKB) + } + } + log.Info("ServiceProviderWithdraw2:", req.ServiceProviderAddress, req.Account, amount.String()) + if amount.Cmp(decimal.NewFromInt(int64(common.MinCellOccupiedCkb))) < 1 { + return "", nil + } + if !req.Withdraw { + return "", nil + } + + // build tx ================== + + txParams := &txbuilder.BuildTransactionParams{} + // CellDeps + contractSubAccount, err := core.GetDasContractInfo(common.DASContractNameSubAccountCellType) + if err != nil { + return "", fmt.Errorf("GetDasContractInfo err: %s", err.Error()) + } + contractBalanceCell, err := core.GetDasContractInfo(common.DasContractNameBalanceCellType) + if err != nil { + return "", fmt.Errorf("GetDasContractInfo err: %s", err.Error()) + } + configCellSubAcc, err := core.GetDasConfigCellInfo(common.ConfigCellTypeArgsSubAccount) + if err != nil { + return "", fmt.Errorf("GetDasConfigCellInfo err: %s", err.Error()) + } + txParams.CellDeps = append(txParams.CellDeps, + contractSubAccount.ToCellDep(), + contractBalanceCell.ToCellDep(), + configCellSubAcc.ToCellDep(), + ) + + // inputs cell + subAccountCell, err := h.DasCore.GetSubAccountCell(parentAccountId) + if err != nil { + return "", fmt.Errorf("GetSubAccountCell err: %s", err.Error()) + } + txParams.Inputs = append(txParams.Inputs, &types.CellInput{ + PreviousOutput: subAccountCell.OutPoint, + }) + + change, liveBalanceCell, err := h.TxTool.GetBalanceCell(&txtool.ParamBalance{ + DasLock: h.TxTool.ServerScript, + NeedCapacity: common.OneCkb, + }) + if err != nil { + return "", fmt.Errorf("GetBalanceCell err: %s", err.Error()) + } + for _, v := range liveBalanceCell { + txParams.Inputs = append(txParams.Inputs, &types.CellInput{ + PreviousOutput: v.OutPoint, + }) + } + + // sub_account cell + txParams.Outputs = append(txParams.Outputs, &types.CellOutput{ + Capacity: subAccountCell.Output.Capacity - uint64(amount.IntPart()), + Lock: subAccountCell.Output.Lock, + Type: subAccountCell.Output.Type, + }) + subAccountCellDetail := witness.ConvertSubAccountCellOutputData(subAccountCell.OutputData) + subAccountCellDetail.DasProfit -= uint64(amount.IntPart()) + txParams.OutputsData = append(txParams.OutputsData, witness.BuildSubAccountCellOutputData(subAccountCellDetail)) + + // provider balance_cell + txParams.Outputs = append(txParams.Outputs, &types.CellOutput{ + Capacity: uint64(amount.IntPart()), + Lock: common.GetNormalLockScript(providerId), + }) + txParams.OutputsData = append(txParams.OutputsData, []byte{}) + + // change balance_cell + txParams.Outputs = append(txParams.Outputs, &types.CellOutput{ + Capacity: change + common.OneCkb, + Lock: h.ServerScript, + }) + txParams.OutputsData = append(txParams.OutputsData, []byte{}) + + actionWitness, err := witness.GenActionDataWitness(common.DasActionCollectSubAccountChannelProfit, nil) + if err != nil { + return "", fmt.Errorf("GenActionDataWitness err: %s", err.Error()) + } + txParams.Witnesses = append(txParams.Witnesses, actionWitness) + + // + txBuilder := txbuilder.NewDasTxBuilderFromBase(h.TxBuilderBase, nil) + if err := txBuilder.BuildTransaction(txParams); err != nil { + return "", fmt.Errorf("BuildTransaction err: %s", err.Error()) + } + sizeInBlock, _ := txBuilder.Transaction.SizeInBlock() + latestIndex := len(txBuilder.Transaction.Outputs) - 1 + changeCapacity := txBuilder.Transaction.Outputs[latestIndex].Capacity - sizeInBlock - 1000 + txBuilder.Transaction.Outputs[latestIndex].Capacity = changeCapacity + + hash, err := txBuilder.SendTransaction() + if err != nil { + return "", fmt.Errorf("SendTransaction err: %s", err.Error()) + } + + taskInfo := &tables.TableTaskInfo{ + TaskType: tables.TaskTypeChain, + ParentAccountId: parentAccountId, + Action: common.DasActionCollectSubAccountChannelProfit, + Outpoint: common.OutPoint2String(hash.Hex(), 0), + Timestamp: time.Now().UnixMilli(), + SmtStatus: tables.SmtStatusWriteComplete, + TxStatus: tables.TxStatusPending, + } + taskInfo.InitTaskId() + if err := h.DbDao.CreateTask(taskInfo); err != nil { + log.Error("CreateTask err: ", err.Error(), hash.Hex()) + return hash.Hex(), nil + } + + return hash.Hex(), nil +} diff --git a/http_server/handle/statistical_info.go b/http_server/handle/statistical_info.go index f15a8a75..defe912a 100644 --- a/http_server/handle/statistical_info.go +++ b/http_server/handle/statistical_info.go @@ -194,9 +194,14 @@ func (h *HttpHandle) doStatisticalInfo(req *ReqStatisticalInfo, apiResp *api_cod total, err := h.DbDao.GetSmtRecordManualMintYears(accountId) if err != nil { apiResp.ApiRespErr(api_code.ApiCodeDbError, "db error") - return err + return fmt.Errorf("GetSmtRecordManualMintYears err: %s", err.Error()) + } + total2, err := h.DbDao.GetSmtRecordManualCKB(accountId) + if err != nil { + apiResp.ApiRespErr(api_code.ApiCodeDbError, "db error") + return fmt.Errorf("GetSmtRecordManualCKB err: %s", err.Error()) } - resp.CkbSpending.Total = fmt.Sprintf("%d", total) + resp.CkbSpending.Total = fmt.Sprintf("%d", total+total2) return nil }) diff --git a/http_server/handle/sub_account_create_new.go b/http_server/handle/sub_account_create_new.go index a4e311c5..ba091c9c 100644 --- a/http_server/handle/sub_account_create_new.go +++ b/http_server/handle/sub_account_create_new.go @@ -145,10 +145,19 @@ func (h *HttpHandle) doSubAccountCreateNew(req *ReqSubAccountCreate, apiResp *ap } newSubAccountPrice, _ := molecule.Bytes2GoU64(configCellBuilder.ConfigCellSubAccount.NewSubAccountPrice().RawData()) totalCapacity := uint64(0) + totalRegisterYears := uint64(0) for _, v := range req.SubAccountList { - totalCapacity += v.RegisterYears + totalRegisterYears += v.RegisterYears } - totalCapacity = totalCapacity * newSubAccountPrice + + quoteCell, err := h.DasCore.GetQuoteCell() + if err != nil { + apiResp.ApiRespErr(api_code.ApiCodeError500, "failed to get quote cell") + return fmt.Errorf("GetQuoteCell err: %s", err.Error()) + } + totalCapacity = config.PriceToCKB(newSubAccountPrice, quoteCell.Quote(), totalRegisterYears) + //totalCapacity = totalRegisterYears * newSubAccountPrice + _, _, err = h.DasCore.GetBalanceCells(&core.ParamGetBalanceCells{ DasCache: nil, LockScript: balanceDasLock, diff --git a/http_server/handle/sub_account_renew.go b/http_server/handle/sub_account_renew.go index 5a91611e..8f405cf4 100644 --- a/http_server/handle/sub_account_renew.go +++ b/http_server/handle/sub_account_renew.go @@ -141,10 +141,17 @@ func (h *HttpHandle) doSubAccountRenew(req *ReqSubAccountRenew, apiResp *api_cod } totalCapacity := uint64(0) + totalRenewYears := uint64(0) for _, v := range req.SubAccountList { - totalCapacity += v.RenewYears + totalRenewYears += v.RenewYears } - totalCapacity = totalCapacity * renewSubAccountPrice + //totalCapacity = totalRenewYears * renewSubAccountPrice + quoteCell, err := h.DasCore.GetQuoteCell() + if err != nil { + apiResp.ApiRespErr(api_code.ApiCodeError500, "failed to get quote cell") + return fmt.Errorf("GetQuoteCell err: %s", err.Error()) + } + totalCapacity = config.PriceToCKB(renewSubAccountPrice, quoteCell.Quote(), totalRenewYears) _, _, err = h.DasCore.GetBalanceCells(&core.ParamGetBalanceCells{ DasCache: nil, diff --git a/http_server/router.go b/http_server/router.go index 8d650e8f..357644e6 100644 --- a/http_server/router.go +++ b/http_server/router.go @@ -54,9 +54,9 @@ func (h *HttpServer) initRouter() { v1.POST("/sub/account/edit", api_code.DoMonitorLog("account_edit"), h.H.SubAccountEditNew) // edit_sub_account v1.POST("/owner/profit", api_code.DoMonitorLog("owner_profit"), h.H.OwnerProfit) v1.POST("/profit/withdraw", api_code.DoMonitorLog("profit_withdraw"), h.H.ProfitWithdraw) - v1.POST("/custom/script/set", api_code.DoMonitorLog("custom_script"), h.H.CustomScript) - v1.POST("/custom/script/info", api_code.DoMonitorLog("custom_script_info"), h.H.CustomScriptInfo) - v1.POST("/custom/script/price", api_code.DoMonitorLog("mint_price"), cacheHandleShort, h.H.CustomScriptPrice) + //v1.POST("/custom/script/set", api_code.DoMonitorLog("custom_script"), h.H.CustomScript) + //v1.POST("/custom/script/info", api_code.DoMonitorLog("custom_script_info"), h.H.CustomScriptInfo) + //v1.POST("/custom/script/price", api_code.DoMonitorLog("mint_price"), cacheHandleShort, h.H.CustomScriptPrice) v1.POST("/transaction/send", api_code.DoMonitorLog("tx_send"), h.H.TransactionSendNew) v1.POST("/mint/config/update", api_code.DoMonitorLog("mint_config_update"), h.H.MintConfigUpdate) v1.POST("/config/auto_mint/update", api_code.DoMonitorLog("config_auto_mint_update"), h.H.ConfigAutoMintUpdate) @@ -79,12 +79,14 @@ func (h *HttpServer) initRouter() { internalV1.POST("/internal/smt/update", h.H.SmtUpdate) internalV1.POST("/internal/smt/syncTree", h.H.SmtSync) - internalV1.POST("/internal/sub/account/mint", h.H.InternalSubAccountMintNew) + //internalV1.POST("/internal/sub/account/mint", h.H.InternalSubAccountMintNew) internalV1.POST("/owner/payment/export", h.H.OwnerPaymentExport) internalV1.POST("/unipay/notice", h.H.UniPayNotice) internalV1.POST("/service/provider/withdraw", h.H.ServiceProviderWithdraw) + internalV1.POST("/service/provider/withdraw2", h.H.ServiceProviderWithdraw2) internalV1.POST("/internal/recycle/account", h.H.RecycleAccount) } + // curl -X POST http://127.0.0.1:8127/v1/service/provider/withdraw2 -d'{"service_provider_address":"","account":"","withdraw":false}' } func respHandle(c *gin.Context, res string, err error) { diff --git a/tables/sub_account_db.sql b/tables/sub_account_db.sql index 6560f755..d14242c3 100644 --- a/tables/sub_account_db.sql +++ b/tables/sub_account_db.sql @@ -1,5 +1,7 @@ -CREATE DATABASE `sub_account_db`; -USE `sub_account_db`; +CREATE + DATABASE `sub_account_db`; +USE + `sub_account_db`; -- t_block_parser_info CREATE TABLE `t_block_parser_info` @@ -94,4 +96,46 @@ CREATE TABLE `t_mint_sign_info` UNIQUE KEY `uk_mint_sign_id` (`mint_sign_id`) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 - COLLATE = utf8mb4_0900_ai_ci COMMENT ='mint sign info'; \ No newline at end of file + COLLATE = utf8mb4_0900_ai_ci COMMENT ='mint sign info'; + +-- t_coupon_set_info +CREATE TABLE `t_coupon_set_info` +( + `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '', + `cid` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '', + `account_id` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '', + `owner_aid` SMALLINT NOT NULL DEFAULT '0' COMMENT '', + `owner` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '', + `root` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '', + `name` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '', + `note` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '', + `price` DECIMAL(50, 10) NOT NULL DEFAULT '' COMMENT '', + `num` INT NOT NULL DEFAULT '0' COMMENT '', + `expired_at` BIGINT NOT NULL DEFAULT '0' COMMENT '', + `status` SMALLINT NOT NULL DEFAULT '0' COMMENT '', + `signature` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '', + `created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '', + `updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '', + PRIMARY KEY (`id`), + UNIQUE KEY `uk_cid` (`cid`), + KEY `k_account_id` (`account_id`), + KEY `k_owner` (`owner`) +) ENGINE = InnoDB + DEFAULT CHARSET = utf8mb4 + COLLATE = utf8mb4_0900_ai_ci COMMENT ='coupon set info'; + + +-- t_coupon_info +CREATE TABLE `t_coupon_info` +( + `id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '', + `cid` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '', + `code` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '', + `status` SMALLINT NOT NULL DEFAULT '0' COMMENT '', + `created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '', + `updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '', + PRIMARY KEY (`id`), + UNIQUE KEY `uk_cid` (`cid`) +) ENGINE = InnoDB + DEFAULT CHARSET = utf8mb4 + COLLATE = utf8mb4_0900_ai_ci COMMENT ='coupon info'; \ No newline at end of file diff --git a/tables/t_smt_record_info.go b/tables/t_smt_record_info.go index fc4ee2f1..741df9a0 100644 --- a/tables/t_smt_record_info.go +++ b/tables/t_smt_record_info.go @@ -8,6 +8,7 @@ import ( "github.com/dotbitHQ/das-lib/http_api/logger" "github.com/dotbitHQ/das-lib/molecule" "github.com/dotbitHQ/das-lib/witness" + "github.com/shopspring/decimal" "strings" "time" ) @@ -44,6 +45,7 @@ type TableSmtRecordInfo struct { SubAction common.SubAction `json:"sub_action" gorm:"column:sub_action; index:k_action; type:varchar(255) NOT NULL DEFAULT '' COMMENT '';"` MintSignId string `json:"mint_sign_id" gorm:"column:mint_sign_id; index:k_mint_sign_id; type:varchar(255) NOT NULL DEFAULT '' COMMENT '';"` ExpiredAt uint64 `json:"expired_at" gorm:"column:expired_at; type:bigint(20) NOT NULL DEFAULT '0' COMMENT '';"` + Quote decimal.Decimal `json:"quote" gorm:"column:quote; type:decimal(50,10) NOT NULL DEFAULT '0' COMMENT 'quote';"` CreatedAt time.Time `json:"created_at" gorm:"column:created_at;type:timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT ''"` UpdatedAt time.Time `json:"updated_at" gorm:"column:updated_at;type:timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT ''"` } diff --git a/tables/t_sub_account_auto_mint_statement.go b/tables/t_sub_account_auto_mint_statement.go index a97a962a..3c9c585c 100644 --- a/tables/t_sub_account_auto_mint_statement.go +++ b/tables/t_sub_account_auto_mint_statement.go @@ -1,6 +1,7 @@ package tables import ( + "github.com/dotbitHQ/das-lib/common" "github.com/shopspring/decimal" "time" ) @@ -20,8 +21,11 @@ type TableSubAccountAutoMintStatement struct { ParentAccountId string `json:"parent_account_id" gorm:"column:parent_account_id; type:varchar(255) NOT NULL DEFAULT '' COMMENT '';"` ServiceProviderId string `json:"service_provider_id" gorm:"column:service_provider_id; index:idx_service_provider_id; type:varchar(255) NOT NULL DEFAULT '' COMMENT '';"` Price decimal.Decimal `json:"price" gorm:"column:price; type:decimal(60,2) NOT NULL DEFAULT '0' COMMENT '';"` + Quote decimal.Decimal `json:"quote" gorm:"column:quote; type:decimal(50,10) NOT NULL DEFAULT '0' COMMENT '';"` + Years uint64 `json:"years" gorm:"column:years; type:int(11) NOT NULL DEFAULT '0' COMMENT'';"` BlockTimestamp uint64 `json:"block_timestamp" gorm:"column:block_timestamp; type:bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT '';"` TxType SubAccountAutoMintTxType `json:"tx_type" gorm:"column:tx_type; type:int(11) NOT NULL DEFAULT '0' COMMENT '1: income, 2: expenditure';"` + SubAction common.SubAction `json:"sub_action" gorm:"column:sub_action; type:varchar(255) NOT NULL DEFAULT '' COMMENT '';"` CreatedAt time.Time `json:"created_at" gorm:"column:created_at;type:timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT ''"` UpdatedAt time.Time `json:"updated_at" gorm:"column:updated_at;type:timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT ''"` } diff --git a/txtool/txtool.go b/txtool/txtool.go index aa83b681..3cd28f06 100644 --- a/txtool/txtool.go +++ b/txtool/txtool.go @@ -43,7 +43,7 @@ type ParamBuildTxs struct { } type ResultBuildTxs struct { - IsCustomScript bool + //IsCustomScript bool DasTxBuilderList []*txbuilder.DasTxBuilder } @@ -59,7 +59,7 @@ func (s *SubAccountTxTool) BuildTxsForUpdateSubAccount(p *ParamBuildTxs) (*Resul subAccountOutpoint := p.SubAccountLiveCell.OutPoint // account - res.IsCustomScript = s.isCustomScript(p.SubAccountLiveCell.OutputData) + //res.IsCustomScript = s.isCustomScript(p.SubAccountLiveCell.OutputData) subAccountCellOutput := p.SubAccountLiveCell.Output subAccountOutputsData := p.SubAccountLiveCell.OutputData // build txs @@ -72,49 +72,49 @@ func (s *SubAccountTxTool) BuildTxsForUpdateSubAccount(p *ParamBuildTxs) (*Resul case common.DasActionUpdateSubAccount: var resUpdate *ResultBuildUpdateSubAccountTx var err error - if res.IsCustomScript { - resUpdate, err = s.BuildUpdateSubAccountTxForCustomScript(&ParamBuildUpdateSubAccountTx{ - TaskInfo: &p.TaskList[i], - Account: p.Account, - AccountOutPoint: accountOutPoint, - SubAccountOutpoint: subAccountOutpoint, - SmtRecordInfoList: records, - Tree: p.Tree, - BaseInfo: p.BaseInfo, - SubAccountBuilderMap: p.SubAccountBuilderMap, - NewSubAccountPrice: newSubAccountPrice, - RenewSubAccountPrice: renewSubAccountPrice, - BalanceDasLock: p.BalanceDasLock, - BalanceDasType: p.BalanceDasType, - CommonFee: commonFee, - SubAccountCellOutput: subAccountCellOutput, - SubAccountOutputsData: subAccountOutputsData, - }) - if err != nil { - return nil, fmt.Errorf("BuildUpdateSubAccountTxForCustomScript err: %s", err.Error()) - } - } else { - resUpdate, err = s.BuildUpdateSubAccountTx(&ParamBuildUpdateSubAccountTx{ - TaskInfo: &p.TaskList[i], - Account: p.Account, - AccountOutPoint: accountOutPoint, - SubAccountOutpoint: subAccountOutpoint, - SmtRecordInfoList: records, - Tree: p.Tree, - BaseInfo: p.BaseInfo, - SubAccountBuilderMap: p.SubAccountBuilderMap, - NewSubAccountPrice: newSubAccountPrice, - RenewSubAccountPrice: renewSubAccountPrice, - BalanceDasLock: p.BalanceDasLock, - BalanceDasType: p.BalanceDasType, - CommonFee: commonFee, - SubAccountCellOutput: subAccountCellOutput, - SubAccountOutputsData: subAccountOutputsData, - }) - if err != nil { - return nil, fmt.Errorf("BuildUpdateSubAccountTx err: %s", err.Error()) - } + //if res.IsCustomScript { + // resUpdate, err = s.BuildUpdateSubAccountTxForCustomScript(&ParamBuildUpdateSubAccountTx{ + // TaskInfo: &p.TaskList[i], + // Account: p.Account, + // AccountOutPoint: accountOutPoint, + // SubAccountOutpoint: subAccountOutpoint, + // SmtRecordInfoList: records, + // Tree: p.Tree, + // BaseInfo: p.BaseInfo, + // SubAccountBuilderMap: p.SubAccountBuilderMap, + // NewSubAccountPrice: newSubAccountPrice, + // RenewSubAccountPrice: renewSubAccountPrice, + // BalanceDasLock: p.BalanceDasLock, + // BalanceDasType: p.BalanceDasType, + // CommonFee: commonFee, + // SubAccountCellOutput: subAccountCellOutput, + // SubAccountOutputsData: subAccountOutputsData, + // }) + // if err != nil { + // return nil, fmt.Errorf("BuildUpdateSubAccountTxForCustomScript err: %s", err.Error()) + // } + //} else { + resUpdate, err = s.BuildUpdateSubAccountTx(&ParamBuildUpdateSubAccountTx{ + TaskInfo: &p.TaskList[i], + Account: p.Account, + AccountOutPoint: accountOutPoint, + SubAccountOutpoint: subAccountOutpoint, + SmtRecordInfoList: records, + Tree: p.Tree, + BaseInfo: p.BaseInfo, + SubAccountBuilderMap: p.SubAccountBuilderMap, + NewSubAccountPrice: newSubAccountPrice, + RenewSubAccountPrice: renewSubAccountPrice, + BalanceDasLock: p.BalanceDasLock, + BalanceDasType: p.BalanceDasType, + CommonFee: commonFee, + SubAccountCellOutput: subAccountCellOutput, + SubAccountOutputsData: subAccountOutputsData, + }) + if err != nil { + return nil, fmt.Errorf("BuildUpdateSubAccountTx err: %s", err.Error()) } + // } res.DasTxBuilderList = append(res.DasTxBuilderList, resUpdate.DasTxBuilder) default: return nil, fmt.Errorf("not exist action [%s]", task.Action) diff --git a/txtool/update_sub_account.go b/txtool/update_sub_account.go index 42ffb4f6..3ffed2e4 100644 --- a/txtool/update_sub_account.go +++ b/txtool/update_sub_account.go @@ -1,7 +1,7 @@ package txtool import ( - "bytes" + "das_sub_account/config" "das_sub_account/tables" "encoding/json" "errors" @@ -113,6 +113,7 @@ func (s *SubAccountTxTool) BuildUpdateSubAccountTx(p *ParamBuildUpdateSubAccount renewTotalYears := uint64(0) autoTotalCapacity := uint64(0) subAccountPriceMap := make(map[string]uint64) + quote := p.BaseInfo.QuoteCell.Quote() for _, v := range p.SmtRecordInfoList { if v.SubAction != common.SubActionCreate && v.SubAction != common.SubActionRenew { @@ -151,8 +152,6 @@ func (s *SubAccountTxTool) BuildUpdateSubAccountTx(p *ParamBuildUpdateSubAccount if !hit { return nil, fmt.Errorf("%s not hit any price rule", v.Account) } - - quote := p.BaseInfo.QuoteCell.Quote() yearlyPrice := uint64(subAccountRule.Rules[idx].Price) subAccountPrice := uint64(0) years := uint64(0) @@ -175,7 +174,10 @@ func (s *SubAccountTxTool) BuildUpdateSubAccountTx(p *ParamBuildUpdateSubAccount var err error var manualChange uint64 manualBalanceLiveCells := make([]*indexer.LiveCell, 0) - manualCapacity := p.NewSubAccountPrice*registerTotalYears + p.RenewSubAccountPrice*renewTotalYears + + // min price 0.99$ + manualCapacity := config.PriceToCKB(p.NewSubAccountPrice, quote, registerTotalYears) + config.PriceToCKB(p.RenewSubAccountPrice, quote, renewTotalYears) + //manualCapacity := p.NewSubAccountPrice*registerTotalYears + p.RenewSubAccountPrice*renewTotalYears if manualCapacity > 0 { needCapacity := manualCapacity if autoTotalCapacity == 0 { @@ -432,10 +434,10 @@ func (s *SubAccountTxTool) BuildUpdateSubAccountTx(p *ParamBuildUpdateSubAccount OutPoint: p.AccountOutPoint, DepType: types.DepTypeCode, }, + p.BaseInfo.QuoteCell.ToCellDep(), p.BaseInfo.ContractDas.ToCellDep(), p.BaseInfo.ContractAcc.ToCellDep(), p.BaseInfo.ContractSubAcc.ToCellDep(), - p.BaseInfo.QuoteCell.ToCellDep(), p.BaseInfo.HeightCell.ToCellDep(), p.BaseInfo.TimeCell.ToCellDep(), p.BaseInfo.ConfigCellAcc.ToCellDep(), @@ -859,14 +861,14 @@ func (s *SubAccountTxTool) BuildUpdateSubAccountTxForCustomScript(p *ParamBuildU return &res, nil } -func (s *SubAccountTxTool) isCustomScript(data []byte) bool { - subDataDetail := witness.ConvertSubAccountCellOutputData(data) - customScriptArgs := make([]byte, 32) - if len(subDataDetail.CustomScriptArgs) == 0 || bytes.Compare(subDataDetail.CustomScriptArgs, customScriptArgs) == 0 { - return false - } - return true -} +//func (s *SubAccountTxTool) isCustomScript(data []byte) bool { +// subDataDetail := witness.ConvertSubAccountCellOutputData(data) +// customScriptArgs := make([]byte, 32) +// if len(subDataDetail.CustomScriptArgs) == 0 || bytes.Compare(subDataDetail.CustomScriptArgs, customScriptArgs) == 0 { +// return false +// } +// return true +//} func (s *SubAccountTxTool) getSubAccountCell(parentAccountId string) (*indexer.LiveCell, error) { baseInfo, err := s.GetBaseInfo()