mirror of
https://github.com/planetmint/planetmint-go.git
synced 2025-10-14 00:59:21 +00:00
chore: replace elementsd-connector with shamir-coordinator-client (#422)
* chore: replace elementsd-connector with shamir-coordinator-client --------- Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com>
This commit is contained in:
parent
d2def2b453
commit
3ffd9f96ef
@ -50,11 +50,21 @@ func ReIssueAsset(ctx context.Context, asset string, amount string) (txID string
|
|||||||
return res.TxID, nil
|
return res.TxID, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func IssueNFTAsset(ctx context.Context, name string, machineAddress string, domain string) (assetID string, contract string, hexTx string, err error) {
|
||||||
|
client := lazyLoadShamirCoordinatorClient()
|
||||||
|
res, err := client.IssueMachineNFT(ctx, name, machineAddress, domain)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return res.Asset, res.Contract, res.HexTX, nil
|
||||||
|
}
|
||||||
|
|
||||||
type IShamirCoordinatorClient interface {
|
type IShamirCoordinatorClient interface {
|
||||||
GetMnemonics(ctx context.Context) (res MnemonicsResponse, err error)
|
GetMnemonics(ctx context.Context) (res MnemonicsResponse, err error)
|
||||||
PostMnemonics(ctx context.Context, secret string) (err error)
|
PostMnemonics(ctx context.Context, secret string) (err error)
|
||||||
SendTokens(ctx context.Context, recipient string, amount string, asset string) (res SendTokensResponse, err error)
|
SendTokens(ctx context.Context, recipient string, amount string, asset string) (res SendTokensResponse, err error)
|
||||||
ReIssueAsset(ctx context.Context, asset string, amount string) (res ReIssueResponse, err error)
|
ReIssueAsset(ctx context.Context, asset string, amount string) (res ReIssueResponse, err error)
|
||||||
|
IssueMachineNFT(ctx context.Context, name string, machineAddress string, domain string) (res IssueMachineNFTResponse, err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type SendTokensRequest struct {
|
type SendTokensRequest struct {
|
||||||
@ -81,6 +91,18 @@ type MnemonicsResponse struct {
|
|||||||
Seed string `binding:"required" json:"seed"`
|
Seed string `binding:"required" json:"seed"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type IssueMachineNFTRequest struct {
|
||||||
|
Name string `binding:"required" json:"name"`
|
||||||
|
MachineAddress string `binding:"required" json:"machine-address"`
|
||||||
|
Domain string `binding:"required" json:"domain"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type IssueMachineNFTResponse struct {
|
||||||
|
Asset string `binding:"required" json:"asset"`
|
||||||
|
Contract string `binding:"required" json:"contract"`
|
||||||
|
HexTX string `binding:"required" json:"hex-tx"`
|
||||||
|
}
|
||||||
|
|
||||||
type ShamirCoordinatorClient struct {
|
type ShamirCoordinatorClient struct {
|
||||||
baseURL string
|
baseURL string
|
||||||
client *http.Client
|
client *http.Client
|
||||||
@ -125,6 +147,16 @@ func (scc *ShamirCoordinatorClient) ReIssueAsset(ctx context.Context, asset stri
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (scc *ShamirCoordinatorClient) IssueMachineNFT(ctx context.Context, name string, machineAddress string, domain string) (res IssueMachineNFTResponse, err error) {
|
||||||
|
requestBody := IssueMachineNFTRequest{
|
||||||
|
Name: name,
|
||||||
|
MachineAddress: machineAddress,
|
||||||
|
Domain: domain,
|
||||||
|
}
|
||||||
|
err = scc.doRequest(ctx, http.MethodPost, scc.baseURL+"/issue-machine-nft", &requestBody, &res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func (scc *ShamirCoordinatorClient) doRequest(ctx context.Context, method, url string, body interface{}, response interface{}) (err error) {
|
func (scc *ShamirCoordinatorClient) doRequest(ctx context.Context, method, url string, body interface{}, response interface{}) (err error) {
|
||||||
var bodyReader io.Reader
|
var bodyReader io.Reader
|
||||||
if body != nil {
|
if body != nil {
|
||||||
|
@ -50,6 +50,21 @@ func (mr *MockIShamirCoordinatorClientMockRecorder) GetMnemonics(ctx interface{}
|
|||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMnemonics", reflect.TypeOf((*MockIShamirCoordinatorClient)(nil).GetMnemonics), ctx)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMnemonics", reflect.TypeOf((*MockIShamirCoordinatorClient)(nil).GetMnemonics), ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IssueMachineNFT mocks base method.
|
||||||
|
func (m *MockIShamirCoordinatorClient) IssueMachineNFT(ctx context.Context, name, machineAddress, domain string) (clients.IssueMachineNFTResponse, error) {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "IssueMachineNFT", ctx, name, machineAddress, domain)
|
||||||
|
ret0, _ := ret[0].(clients.IssueMachineNFTResponse)
|
||||||
|
ret1, _ := ret[1].(error)
|
||||||
|
return ret0, ret1
|
||||||
|
}
|
||||||
|
|
||||||
|
// IssueMachineNFT indicates an expected call of IssueMachineNFT.
|
||||||
|
func (mr *MockIShamirCoordinatorClientMockRecorder) IssueMachineNFT(ctx, name, machineAddress, domain interface{}) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IssueMachineNFT", reflect.TypeOf((*MockIShamirCoordinatorClient)(nil).IssueMachineNFT), ctx, name, machineAddress, domain)
|
||||||
|
}
|
||||||
|
|
||||||
// PostMnemonics mocks base method.
|
// PostMnemonics mocks base method.
|
||||||
func (m *MockIShamirCoordinatorClient) PostMnemonics(ctx context.Context, secret string) error {
|
func (m *MockIShamirCoordinatorClient) PostMnemonics(ctx context.Context, secret string) error {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
|
@ -62,6 +62,11 @@ func Load(t *testing.T, configs ...Config) *Network {
|
|||||||
shamirMock.EXPECT().ReIssueAsset(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes().Return(clients.ReIssueResponse{
|
shamirMock.EXPECT().ReIssueAsset(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes().Return(clients.ReIssueResponse{
|
||||||
TxID: "7add40beb27df701e02ee85089c5bc0021bc813823fedb5f1dcb5debda7f3da9",
|
TxID: "7add40beb27df701e02ee85089c5bc0021bc813823fedb5f1dcb5debda7f3da9",
|
||||||
}, nil)
|
}, nil)
|
||||||
|
shamirMock.EXPECT().IssueMachineNFT(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes().Return(clients.IssueMachineNFTResponse{
|
||||||
|
HexTX: "0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
Contract: `{"entity":{"domain":"testnet-assets.rddl.io"}, "issuer_pubkey":"02", "machine_addr":"addr","name":"machine","precicion":8,"version":1}`,
|
||||||
|
Asset: "0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
}, nil)
|
||||||
clients.ShamirCoordinatorServiceClient = shamirMock
|
clients.ShamirCoordinatorServiceClient = shamirMock
|
||||||
|
|
||||||
// enable application logger in tests
|
// enable application logger in tests
|
||||||
|
@ -1,112 +0,0 @@
|
|||||||
package util
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/sha256"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/planetmint/planetmint-go/config"
|
|
||||||
"github.com/planetmint/planetmint-go/x/machine/types"
|
|
||||||
elements "github.com/rddl-network/elements-rpc"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
// this mutex has to protect all signing and crafting of transactions and their inputs
|
|
||||||
// so that UTXOs are not spend twice by accident
|
|
||||||
elementsSyncAccess sync.Mutex
|
|
||||||
)
|
|
||||||
|
|
||||||
func IssueNFTAsset(name string, machineAddress string, domain string) (assetID string, contract string, hexTx string, err error) {
|
|
||||||
conf := config.GetConfig()
|
|
||||||
url := conf.GetRPCURL()
|
|
||||||
|
|
||||||
address, err := elements.GetNewAddress(url, []string{``})
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
addressInfo, err := elements.GetAddressInfo(url, []string{`"` + address + `"`})
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
elementsSyncAccess.Lock()
|
|
||||||
defer elementsSyncAccess.Unlock()
|
|
||||||
hex, err := elements.CreateRawTransaction(url, []string{`[]`, `[{"data":"00"}]`})
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
fundRawTransactionResult, err := elements.FundRawTransaction(url, []string{`"` + hex + `"`, `{"feeRate":0.00001000}`})
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
c := types.Contract{
|
|
||||||
Entity: types.Entity{
|
|
||||||
Domain: domain,
|
|
||||||
},
|
|
||||||
IssuerPubkey: addressInfo.Pubkey,
|
|
||||||
MachineAddr: machineAddress,
|
|
||||||
Name: name,
|
|
||||||
Precision: 0,
|
|
||||||
Version: 0,
|
|
||||||
}
|
|
||||||
contractBytes, err := json.Marshal(c)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// e.g. {"entity":{"domain":"testnet-assets.rddl.io"}, "issuer_pubkey":"02...}
|
|
||||||
contract = string(contractBytes)
|
|
||||||
|
|
||||||
h := sha256.New()
|
|
||||||
_, err = h.Write(contractBytes)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// e.g. 7ca8bb403ee5dccddef7b89b163048cf39439553f0402351217a4a03d2224df8
|
|
||||||
hash := h.Sum(nil)
|
|
||||||
|
|
||||||
// Reverse hash, e.g. f84d22d2034a7a21512340f053954339cf4830169bb8f7decddce53e40bba87c
|
|
||||||
for i, j := 0, len(hash)-1; i < j; i, j = i+1, j-1 {
|
|
||||||
hash[i], hash[j] = hash[j], hash[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
rawIssueAssetResults, err := elements.RawIssueAsset(url, []string{`"` + fundRawTransactionResult.Hex + `"`,
|
|
||||||
`[{"asset_amount":0.00000001, "asset_address":"` + address + `", "blind":false, "contract_hash":"` + fmt.Sprintf("%+x", hash) + `"}]`,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
rawIssueAssetResult := rawIssueAssetResults[len(rawIssueAssetResults)-1]
|
|
||||||
hex, err = elements.BlindRawTransaction(url, []string{`"` + rawIssueAssetResult.Hex + `"`, `true`, `[]`, `false`})
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
assetID = rawIssueAssetResult.Asset
|
|
||||||
|
|
||||||
signRawTransactionWithWalletResult, err := elements.SignRawTransactionWithWallet(url, []string{`"` + hex + `"`})
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
testMempoolAcceptResults, err := elements.TestMempoolAccept(url, []string{`["` + signRawTransactionWithWalletResult.Hex + `"]`})
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
testMempoolAcceptResult := testMempoolAcceptResults[len(testMempoolAcceptResults)-1]
|
|
||||||
if !testMempoolAcceptResult.Allowed {
|
|
||||||
err = fmt.Errorf("not accepted by mempool: %+v %+v", testMempoolAcceptResult, signRawTransactionWithWalletResult)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
hex, err = elements.SendRawTransaction(url, []string{`"` + signRawTransactionWithWalletResult.Hex + `"`})
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
return assetID, contract, hex, err
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
package util_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"math/rand"
|
|
||||||
"strconv"
|
|
||||||
"sync"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/planetmint/planetmint-go/testutil/moduleobject"
|
|
||||||
"github.com/planetmint/planetmint-go/testutil/sample"
|
|
||||||
"github.com/planetmint/planetmint-go/util"
|
|
||||||
"github.com/planetmint/planetmint-go/x/machine/types"
|
|
||||||
elements "github.com/rddl-network/elements-rpc"
|
|
||||||
elementsmocks "github.com/rddl-network/elements-rpc/utils/mocks"
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestIssueNFTAsset(t *testing.T) {
|
|
||||||
elements.Client = &elementsmocks.MockClient{}
|
|
||||||
|
|
||||||
params := types.DefaultParams()
|
|
||||||
var wg sync.WaitGroup
|
|
||||||
|
|
||||||
for i := 0; i < 1; i++ {
|
|
||||||
wg.Add(1)
|
|
||||||
go func() {
|
|
||||||
randomInt := rand.Int()
|
|
||||||
sk, pk := sample.KeyPair(randomInt)
|
|
||||||
machine := moduleobject.MachineRandom(pk, pk, sk, "address "+strconv.Itoa(randomInt), randomInt)
|
|
||||||
|
|
||||||
_, _, _, err := util.IssueNFTAsset(machine.Name, machine.Address, params.AssetRegistryDomain)
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
wg.Done()
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
wg.Wait()
|
|
||||||
}
|
|
@ -12,6 +12,7 @@ import (
|
|||||||
|
|
||||||
errorsmod "cosmossdk.io/errors"
|
errorsmod "cosmossdk.io/errors"
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
"github.com/planetmint/planetmint-go/clients"
|
||||||
"github.com/planetmint/planetmint-go/x/machine/types"
|
"github.com/planetmint/planetmint-go/x/machine/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -32,7 +33,7 @@ func IssueMachineNFT(goCtx context.Context, machine *types.Machine, scheme strin
|
|||||||
// asset registration is in order to have the contact published
|
// asset registration is in order to have the contact published
|
||||||
var notarizedAsset types.LiquidAsset
|
var notarizedAsset types.LiquidAsset
|
||||||
notarizedAsset.Registered = true
|
notarizedAsset.Registered = true
|
||||||
assetID, contract, hex, err := IssueNFTAsset(machine.Name, machine.Address, domain)
|
assetID, contract, hex, err := clients.IssueNFTAsset(goCtx, machine.Name, machine.Address, domain)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
GetAppLogger().Error(ctx, err.Error())
|
GetAppLogger().Error(ctx, err.Error())
|
||||||
return err
|
return err
|
||||||
|
@ -9,7 +9,10 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
"github.com/golang/mock/gomock"
|
||||||
|
"github.com/planetmint/planetmint-go/clients"
|
||||||
"github.com/planetmint/planetmint-go/testutil/keeper"
|
"github.com/planetmint/planetmint-go/testutil/keeper"
|
||||||
|
clientmocks "github.com/planetmint/planetmint-go/testutil/mocks"
|
||||||
"github.com/planetmint/planetmint-go/testutil/moduleobject"
|
"github.com/planetmint/planetmint-go/testutil/moduleobject"
|
||||||
"github.com/planetmint/planetmint-go/testutil/sample"
|
"github.com/planetmint/planetmint-go/testutil/sample"
|
||||||
"github.com/planetmint/planetmint-go/util"
|
"github.com/planetmint/planetmint-go/util"
|
||||||
@ -47,7 +50,15 @@ func TestRegisterNFT(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestMachineNFTIssuance(t *testing.T) {
|
func TestMachineNFTIssuance(t *testing.T) {
|
||||||
|
ctrl := gomock.NewController(t)
|
||||||
elements.Client = &elementsmocks.MockClient{}
|
elements.Client = &elementsmocks.MockClient{}
|
||||||
|
shamirMock := clientmocks.NewMockIShamirCoordinatorClient(ctrl)
|
||||||
|
shamirMock.EXPECT().IssueMachineNFT(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes().Return(clients.IssueMachineNFTResponse{
|
||||||
|
HexTX: "0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
Contract: `{"entity":{"domain":"testnet-assets.rddl.io"}, "issuer_pubkey":"02", "machine_addr":"addr","name":"machine","precicion":8,"version":1}`,
|
||||||
|
Asset: "0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
}, nil)
|
||||||
|
clients.ShamirCoordinatorServiceClient = shamirMock
|
||||||
util.RegisterAssetServiceHTTPClient = &mocks.MockClient{}
|
util.RegisterAssetServiceHTTPClient = &mocks.MockClient{}
|
||||||
_, ctx := keeper.MachineKeeper(t)
|
_, ctx := keeper.MachineKeeper(t)
|
||||||
params := types.DefaultParams()
|
params := types.DefaultParams()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user