mirror of
https://github.com/aljazceru/ark.git
synced 2026-01-17 18:54:20 +01:00
New boarding protocol (#279)
* [domain] add reverse boarding inputs in Payment struct * [tx-builder] support reverse boarding script * [wallet] add GetTransaction * [api-spec][application] add reverse boarding support in covenantless * [config] add reverse boarding config * [api-spec] add ReverseBoardingAddress RPC * [domain][application] support empty forfeits txs in EndFinalization events * [tx-builder] optional connector output in round tx * [btc-embedded] fix getTx and taproot finalizer * whitelist ReverseBoardingAddress RPC * [test] add reverse boarding integration test * [client] support reverse boarding * [sdk] support reverse boarding * [e2e] add sleep time after faucet * [test] run using bitcoin-core RPC * [tx-builder] fix GetSweepInput * [application][tx-builder] support reverse onboarding in covenant * [cli] support reverse onboarding in covenant CLI * [test] rework integration tests * [sdk] remove onchain wallet, replace by onboarding address * remove old onboarding protocols * [sdk] Fix RegisterPayment * [e2e] add more funds to covenant ASP * [e2e] add sleeping time * several fixes * descriptor boarding * remove boarding delay from info * [sdk] implement descriptor boarding * go mod tidy * fixes and revert error msgs * move descriptor pkg to common * add replace in go.mod * [sdk] fix unit tests * rename DescriptorInput --> BoardingInput * genrest in SDK * remove boarding input from domain * remove all "reverse boarding" * rename "onboarding" ==> "boarding" * remove outdate payment unit test * use tmpfs docker volument for compose testing files * several fixes
This commit is contained in:
@@ -15,7 +15,6 @@ type ArkClient interface {
|
||||
Unlock(ctx context.Context, password string) error
|
||||
Lock(ctx context.Context, password string) error
|
||||
Balance(ctx context.Context, computeExpiryDetails bool) (*Balance, error)
|
||||
Onboard(ctx context.Context, amount uint64) (string, error)
|
||||
Receive(ctx context.Context) (string, string, error)
|
||||
SendOnChain(ctx context.Context, receivers []Receiver) (string, error)
|
||||
SendOffChain(
|
||||
@@ -26,7 +25,7 @@ type ArkClient interface {
|
||||
ctx context.Context, addr string, amount uint64, withExpiryCoinselect bool,
|
||||
) (string, error)
|
||||
SendAsync(ctx context.Context, withExpiryCoinselect bool, receivers []Receiver) (string, error)
|
||||
ClaimAsync(ctx context.Context) (string, error)
|
||||
Claim(ctx context.Context) (string, error)
|
||||
ListVtxos(ctx context.Context) ([]client.Vtxo, []client.Vtxo, error)
|
||||
}
|
||||
|
||||
|
||||
@@ -92,14 +92,15 @@ func (a *arkClient) InitWithWallet(
|
||||
}
|
||||
|
||||
storeData := store.StoreData{
|
||||
AspUrl: args.AspUrl,
|
||||
AspPubkey: aspPubkey,
|
||||
WalletType: args.Wallet.GetType(),
|
||||
ClientType: args.ClientType,
|
||||
Network: network,
|
||||
RoundLifetime: info.RoundLifetime,
|
||||
UnilateralExitDelay: info.UnilateralExitDelay,
|
||||
MinRelayFee: uint64(info.MinRelayFee),
|
||||
AspUrl: args.AspUrl,
|
||||
AspPubkey: aspPubkey,
|
||||
WalletType: args.Wallet.GetType(),
|
||||
ClientType: args.ClientType,
|
||||
Network: network,
|
||||
RoundLifetime: info.RoundLifetime,
|
||||
UnilateralExitDelay: info.UnilateralExitDelay,
|
||||
MinRelayFee: uint64(info.MinRelayFee),
|
||||
BoardingDescriptorTemplate: info.BoardingDescriptorTemplate,
|
||||
}
|
||||
if err := a.store.AddData(ctx, storeData); err != nil {
|
||||
return err
|
||||
@@ -155,14 +156,15 @@ func (a *arkClient) Init(
|
||||
}
|
||||
|
||||
storeData := store.StoreData{
|
||||
AspUrl: args.AspUrl,
|
||||
AspPubkey: aspPubkey,
|
||||
WalletType: args.WalletType,
|
||||
ClientType: args.ClientType,
|
||||
Network: network,
|
||||
RoundLifetime: info.RoundLifetime,
|
||||
UnilateralExitDelay: info.UnilateralExitDelay,
|
||||
MinRelayFee: uint64(info.MinRelayFee),
|
||||
AspUrl: args.AspUrl,
|
||||
AspPubkey: aspPubkey,
|
||||
WalletType: args.WalletType,
|
||||
ClientType: args.ClientType,
|
||||
Network: network,
|
||||
RoundLifetime: info.RoundLifetime,
|
||||
UnilateralExitDelay: info.UnilateralExitDelay,
|
||||
MinRelayFee: uint64(info.MinRelayFee),
|
||||
BoardingDescriptorTemplate: info.BoardingDescriptorTemplate,
|
||||
}
|
||||
walletSvc, err := getWallet(a.store, &storeData, supportedWallets)
|
||||
if err != nil {
|
||||
@@ -201,12 +203,12 @@ func (a *arkClient) IsLocked(ctx context.Context) bool {
|
||||
}
|
||||
|
||||
func (a *arkClient) Receive(ctx context.Context) (string, string, error) {
|
||||
offchainAddr, onchainAddr, err := a.wallet.NewAddress(ctx, false)
|
||||
offchainAddr, boardingAddr, err := a.wallet.NewAddress(ctx, false)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
return offchainAddr, onchainAddr, nil
|
||||
return offchainAddr, boardingAddr, nil
|
||||
}
|
||||
|
||||
func (a *arkClient) ListVtxos(
|
||||
@@ -232,14 +234,11 @@ func (a *arkClient) ListVtxos(
|
||||
func (a *arkClient) ping(
|
||||
ctx context.Context, paymentID string,
|
||||
) func() {
|
||||
_, err := a.client.Ping(ctx, paymentID)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
ticker := time.NewTicker(5 * time.Second)
|
||||
|
||||
go func(t *time.Ticker) {
|
||||
// nolint
|
||||
a.client.Ping(ctx, paymentID)
|
||||
for range t.C {
|
||||
// nolint
|
||||
a.client.Ping(ctx, paymentID)
|
||||
|
||||
@@ -23,11 +23,8 @@ type ASPClient interface {
|
||||
ListVtxos(ctx context.Context, addr string) ([]Vtxo, []Vtxo, error)
|
||||
GetRound(ctx context.Context, txID string) (*Round, error)
|
||||
GetRoundByID(ctx context.Context, roundID string) (*Round, error)
|
||||
Onboard(
|
||||
ctx context.Context, tx, userPubkey string, congestionTree tree.CongestionTree,
|
||||
) error
|
||||
RegisterPayment(
|
||||
ctx context.Context, inputs []VtxoKey, ephemeralPublicKey string,
|
||||
ctx context.Context, inputs []Input, ephemeralKey string,
|
||||
) (string, error)
|
||||
ClaimPayment(
|
||||
ctx context.Context, paymentID string, outputs []Output,
|
||||
@@ -37,7 +34,7 @@ type ASPClient interface {
|
||||
) (<-chan RoundEventChannel, error)
|
||||
Ping(ctx context.Context, paymentID string) (RoundEvent, error)
|
||||
FinalizePayment(
|
||||
ctx context.Context, signedForfeitTxs []string,
|
||||
ctx context.Context, signedForfeitTxs []string, signedRoundTx string,
|
||||
) error
|
||||
CreatePayment(
|
||||
ctx context.Context, inputs []VtxoKey, outputs []Output,
|
||||
@@ -45,6 +42,7 @@ type ASPClient interface {
|
||||
CompletePayment(
|
||||
ctx context.Context, signedRedeemTx string, signedUnconditionalForfeitTxs []string,
|
||||
) error
|
||||
GetBoardingAddress(ctx context.Context, userPubkey string) (string, error)
|
||||
SendTreeNonces(
|
||||
ctx context.Context, roundID, cosignerPubkey string, nonces bitcointree.TreeNonces,
|
||||
) error
|
||||
@@ -55,12 +53,13 @@ type ASPClient interface {
|
||||
}
|
||||
|
||||
type Info struct {
|
||||
Pubkey string
|
||||
RoundLifetime int64
|
||||
UnilateralExitDelay int64
|
||||
RoundInterval int64
|
||||
Network string
|
||||
MinRelayFee int64
|
||||
Pubkey string
|
||||
RoundLifetime int64
|
||||
UnilateralExitDelay int64
|
||||
RoundInterval int64
|
||||
Network string
|
||||
MinRelayFee int64
|
||||
BoardingDescriptorTemplate string
|
||||
}
|
||||
|
||||
type RoundEventChannel struct {
|
||||
@@ -68,11 +67,38 @@ type RoundEventChannel struct {
|
||||
Err error
|
||||
}
|
||||
|
||||
type Input interface {
|
||||
GetTxID() string
|
||||
GetVOut() uint32
|
||||
GetDescriptor() string
|
||||
}
|
||||
|
||||
type VtxoKey struct {
|
||||
Txid string
|
||||
VOut uint32
|
||||
}
|
||||
|
||||
func (k VtxoKey) GetTxID() string {
|
||||
return k.Txid
|
||||
}
|
||||
|
||||
func (k VtxoKey) GetVOut() uint32 {
|
||||
return k.VOut
|
||||
}
|
||||
|
||||
func (k VtxoKey) GetDescriptor() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
type BoardingInput struct {
|
||||
VtxoKey
|
||||
Descriptor string
|
||||
}
|
||||
|
||||
func (k BoardingInput) GetDescriptor() string {
|
||||
return k.Descriptor
|
||||
}
|
||||
|
||||
type Vtxo struct {
|
||||
VtxoKey
|
||||
Amount uint64
|
||||
|
||||
@@ -97,12 +97,13 @@ func (a *grpcClient) GetInfo(ctx context.Context) (*client.Info, error) {
|
||||
return nil, err
|
||||
}
|
||||
return &client.Info{
|
||||
Pubkey: resp.GetPubkey(),
|
||||
RoundLifetime: resp.GetRoundLifetime(),
|
||||
UnilateralExitDelay: resp.GetUnilateralExitDelay(),
|
||||
RoundInterval: resp.GetRoundInterval(),
|
||||
Network: resp.GetNetwork(),
|
||||
MinRelayFee: resp.GetMinRelayFee(),
|
||||
Pubkey: resp.GetPubkey(),
|
||||
RoundLifetime: resp.GetRoundLifetime(),
|
||||
UnilateralExitDelay: resp.GetUnilateralExitDelay(),
|
||||
RoundInterval: resp.GetRoundInterval(),
|
||||
Network: resp.GetNetwork(),
|
||||
MinRelayFee: resp.GetMinRelayFee(),
|
||||
BoardingDescriptorTemplate: resp.GetBoardingDescriptorTemplate(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -143,20 +144,8 @@ func (a *grpcClient) GetRound(
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (a *grpcClient) Onboard(
|
||||
ctx context.Context, tx, userPubkey string, congestionTree tree.CongestionTree,
|
||||
) error {
|
||||
req := &arkv1.OnboardRequest{
|
||||
BoardingTx: tx,
|
||||
UserPubkey: userPubkey,
|
||||
CongestionTree: treeToProto(congestionTree).parse(),
|
||||
}
|
||||
_, err := a.svc.Onboard(ctx, req)
|
||||
return err
|
||||
}
|
||||
|
||||
func (a *grpcClient) RegisterPayment(
|
||||
ctx context.Context, inputs []client.VtxoKey, ephemeralPublicKey string,
|
||||
ctx context.Context, inputs []client.Input, ephemeralPublicKey string,
|
||||
) (string, error) {
|
||||
req := &arkv1.RegisterPaymentRequest{
|
||||
Inputs: ins(inputs).toProto(),
|
||||
@@ -198,11 +187,16 @@ func (a *grpcClient) Ping(
|
||||
}
|
||||
|
||||
func (a *grpcClient) FinalizePayment(
|
||||
ctx context.Context, signedForfeitTxs []string,
|
||||
ctx context.Context, signedForfeitTxs []string, signedRoundTx string,
|
||||
) error {
|
||||
req := &arkv1.FinalizePaymentRequest{
|
||||
SignedForfeitTxs: signedForfeitTxs,
|
||||
}
|
||||
|
||||
if len(signedRoundTx) > 0 {
|
||||
req.SignedRoundTx = &signedRoundTx
|
||||
}
|
||||
|
||||
_, err := a.svc.FinalizePayment(ctx, req)
|
||||
return err
|
||||
}
|
||||
@@ -210,8 +204,13 @@ func (a *grpcClient) FinalizePayment(
|
||||
func (a *grpcClient) CreatePayment(
|
||||
ctx context.Context, inputs []client.VtxoKey, outputs []client.Output,
|
||||
) (string, []string, error) {
|
||||
insCast := make([]client.Input, 0, len(inputs))
|
||||
for _, in := range inputs {
|
||||
insCast = append(insCast, in)
|
||||
}
|
||||
|
||||
req := &arkv1.CreatePaymentRequest{
|
||||
Inputs: ins(inputs).toProto(),
|
||||
Inputs: ins(insCast).toProto(),
|
||||
Outputs: outs(outputs).toProto(),
|
||||
}
|
||||
resp, err := a.svc.CreatePayment(ctx, req)
|
||||
@@ -260,6 +259,19 @@ func (a *grpcClient) GetRoundByID(
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (a *grpcClient) GetBoardingAddress(
|
||||
ctx context.Context, userPubkey string,
|
||||
) (string, error) {
|
||||
req := &arkv1.GetBoardingAddressRequest{
|
||||
Pubkey: userPubkey,
|
||||
}
|
||||
resp, err := a.svc.GetBoardingAddress(ctx, req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return resp.GetAddress(), nil
|
||||
}
|
||||
|
||||
func (a *grpcClient) SendTreeNonces(
|
||||
ctx context.Context, roundID, cosignerPubkey string, nonces bitcointree.TreeNonces,
|
||||
) error {
|
||||
@@ -418,8 +430,8 @@ func (v vtxo) toVtxo() client.Vtxo {
|
||||
}
|
||||
return client.Vtxo{
|
||||
VtxoKey: client.VtxoKey{
|
||||
Txid: v.GetOutpoint().GetTxid(),
|
||||
VOut: v.GetOutpoint().GetVout(),
|
||||
Txid: v.GetOutpoint().GetVtxoInput().GetTxid(),
|
||||
VOut: v.GetOutpoint().GetVtxoInput().GetVout(),
|
||||
},
|
||||
Amount: v.GetReceiver().GetAmount(),
|
||||
RoundTxid: v.GetPoolTxid(),
|
||||
@@ -441,21 +453,35 @@ func (v vtxos) toVtxos() []client.Vtxo {
|
||||
return list
|
||||
}
|
||||
|
||||
type input client.VtxoKey
|
||||
func toProtoInput(i client.Input) *arkv1.Input {
|
||||
if len(i.GetDescriptor()) > 0 {
|
||||
return &arkv1.Input{
|
||||
Input: &arkv1.Input_BoardingInput{
|
||||
BoardingInput: &arkv1.BoardingInput{
|
||||
Txid: i.GetTxID(),
|
||||
Vout: i.GetVOut(),
|
||||
Descriptor_: i.GetDescriptor(),
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (i input) toProto() *arkv1.Input {
|
||||
return &arkv1.Input{
|
||||
Txid: i.Txid,
|
||||
Vout: i.VOut,
|
||||
Input: &arkv1.Input_VtxoInput{
|
||||
VtxoInput: &arkv1.VtxoInput{
|
||||
Txid: i.GetTxID(),
|
||||
Vout: i.GetVOut(),
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type ins []client.VtxoKey
|
||||
type ins []client.Input
|
||||
|
||||
func (i ins) toProto() []*arkv1.Input {
|
||||
list := make([]*arkv1.Input, 0, len(i))
|
||||
for _, ii := range i {
|
||||
list = append(list, input(ii).toProto())
|
||||
list = append(list, toProtoInput(ii))
|
||||
}
|
||||
return list
|
||||
}
|
||||
@@ -496,27 +522,3 @@ func (t treeFromProto) parse() tree.CongestionTree {
|
||||
|
||||
return levels
|
||||
}
|
||||
|
||||
type treeToProto tree.CongestionTree
|
||||
|
||||
func (t treeToProto) parse() *arkv1.Tree {
|
||||
levels := make([]*arkv1.TreeLevel, 0, len(t))
|
||||
for _, level := range t {
|
||||
levelProto := &arkv1.TreeLevel{
|
||||
Nodes: make([]*arkv1.Node, 0, len(level)),
|
||||
}
|
||||
|
||||
for _, node := range level {
|
||||
levelProto.Nodes = append(levelProto.Nodes, &arkv1.Node{
|
||||
Txid: node.Txid,
|
||||
Tx: node.Tx,
|
||||
ParentTxid: node.ParentTxid,
|
||||
})
|
||||
}
|
||||
|
||||
levels = append(levels, levelProto)
|
||||
}
|
||||
return &arkv1.Tree{
|
||||
Levels: levels,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,12 +114,13 @@ func (a *restClient) GetInfo(
|
||||
}
|
||||
|
||||
return &client.Info{
|
||||
Pubkey: resp.Payload.Pubkey,
|
||||
RoundLifetime: int64(roundLifetime),
|
||||
UnilateralExitDelay: int64(unilateralExitDelay),
|
||||
RoundInterval: int64(roundInterval),
|
||||
Network: resp.Payload.Network,
|
||||
MinRelayFee: int64(minRelayFee),
|
||||
Pubkey: resp.Payload.Pubkey,
|
||||
RoundLifetime: int64(roundLifetime),
|
||||
UnilateralExitDelay: int64(unilateralExitDelay),
|
||||
RoundInterval: int64(roundInterval),
|
||||
Network: resp.Payload.Network,
|
||||
MinRelayFee: int64(minRelayFee),
|
||||
BoardingDescriptorTemplate: resp.Payload.BoardingDescriptorTemplate,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -159,8 +160,8 @@ func (a *restClient) ListVtxos(
|
||||
|
||||
spendableVtxos = append(spendableVtxos, client.Vtxo{
|
||||
VtxoKey: client.VtxoKey{
|
||||
Txid: v.Outpoint.Txid,
|
||||
VOut: uint32(v.Outpoint.Vout),
|
||||
Txid: v.Outpoint.VtxoInput.Txid,
|
||||
VOut: uint32(v.Outpoint.VtxoInput.Vout),
|
||||
},
|
||||
Amount: uint64(amount),
|
||||
RoundTxid: v.PoolTxid,
|
||||
@@ -191,8 +192,8 @@ func (a *restClient) ListVtxos(
|
||||
|
||||
spentVtxos = append(spentVtxos, client.Vtxo{
|
||||
VtxoKey: client.VtxoKey{
|
||||
Txid: v.Outpoint.Txid,
|
||||
VOut: uint32(v.Outpoint.Vout),
|
||||
Txid: v.Outpoint.VtxoInput.Txid,
|
||||
VOut: uint32(v.Outpoint.VtxoInput.Vout),
|
||||
},
|
||||
Amount: uint64(amount),
|
||||
RoundTxid: v.PoolTxid,
|
||||
@@ -243,29 +244,31 @@ func (a *restClient) GetRound(
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (a *restClient) Onboard(
|
||||
ctx context.Context, tx, userPubkey string, congestionTree tree.CongestionTree,
|
||||
) error {
|
||||
body := models.V1OnboardRequest{
|
||||
BoardingTx: tx,
|
||||
CongestionTree: treeToProto(congestionTree).parse(),
|
||||
UserPubkey: userPubkey,
|
||||
}
|
||||
_, err := a.svc.ArkServiceOnboard(
|
||||
ark_service.NewArkServiceOnboardParams().WithBody(&body),
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
func (a *restClient) RegisterPayment(
|
||||
ctx context.Context, inputs []client.VtxoKey, ephemeralPublicKey string,
|
||||
ctx context.Context, inputs []client.Input, ephemeralPublicKey string,
|
||||
) (string, error) {
|
||||
ins := make([]*models.V1Input, 0, len(inputs))
|
||||
for _, i := range inputs {
|
||||
ins = append(ins, &models.V1Input{
|
||||
Txid: i.Txid,
|
||||
Vout: int64(i.VOut),
|
||||
})
|
||||
var input *models.V1Input
|
||||
|
||||
if len(i.GetDescriptor()) > 0 {
|
||||
input = &models.V1Input{
|
||||
BoardingInput: &models.V1BoardingInput{
|
||||
Txid: i.GetTxID(),
|
||||
Vout: int64(i.GetVOut()),
|
||||
Descriptor: i.GetDescriptor(),
|
||||
},
|
||||
}
|
||||
} else {
|
||||
input = &models.V1Input{
|
||||
VtxoInput: &models.V1VtxoInput{
|
||||
Txid: i.GetTxID(),
|
||||
Vout: int64(i.GetVOut()),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
ins = append(ins, input)
|
||||
}
|
||||
body := &models.V1RegisterPaymentRequest{
|
||||
Inputs: ins,
|
||||
@@ -377,13 +380,11 @@ func (a *restClient) Ping(
|
||||
}
|
||||
|
||||
func (a *restClient) FinalizePayment(
|
||||
ctx context.Context, signedForfeitTxs []string,
|
||||
ctx context.Context, signedForfeitTxs []string, signedRoundTx string,
|
||||
) error {
|
||||
req := &arkv1.FinalizePaymentRequest{
|
||||
SignedForfeitTxs: signedForfeitTxs,
|
||||
}
|
||||
body := models.V1FinalizePaymentRequest{
|
||||
SignedForfeitTxs: req.GetSignedForfeitTxs(),
|
||||
SignedForfeitTxs: signedForfeitTxs,
|
||||
SignedRoundTx: signedRoundTx,
|
||||
}
|
||||
_, err := a.svc.ArkServiceFinalizePayment(
|
||||
ark_service.NewArkServiceFinalizePaymentParams().WithBody(&body),
|
||||
@@ -396,9 +397,15 @@ func (a *restClient) CreatePayment(
|
||||
) (string, []string, error) {
|
||||
ins := make([]*models.V1Input, 0, len(inputs))
|
||||
for _, i := range inputs {
|
||||
if len(i.GetDescriptor()) > 0 {
|
||||
return "", nil, fmt.Errorf("boarding inputs are not allowed in create payment")
|
||||
}
|
||||
|
||||
ins = append(ins, &models.V1Input{
|
||||
Txid: i.Txid,
|
||||
Vout: int64(i.VOut),
|
||||
VtxoInput: &models.V1VtxoInput{
|
||||
Txid: i.Txid,
|
||||
Vout: int64(i.VOut),
|
||||
},
|
||||
})
|
||||
}
|
||||
outs := make([]*models.V1Output, 0, len(outputs))
|
||||
@@ -477,6 +484,23 @@ func (a *restClient) GetRoundByID(
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (a *restClient) GetBoardingAddress(
|
||||
ctx context.Context, pubkey string,
|
||||
) (string, error) {
|
||||
body := models.V1GetBoardingAddressRequest{
|
||||
Pubkey: pubkey,
|
||||
}
|
||||
|
||||
resp, err := a.svc.ArkServiceGetBoardingAddress(
|
||||
ark_service.NewArkServiceGetBoardingAddressParams().WithBody(&body),
|
||||
)
|
||||
if err != nil {
|
||||
return "",
|
||||
err
|
||||
}
|
||||
return resp.Payload.Address, nil
|
||||
}
|
||||
|
||||
func (a *restClient) SendTreeNonces(
|
||||
ctx context.Context, roundID, cosignerPubkey string, nonces bitcointree.TreeNonces,
|
||||
) error {
|
||||
@@ -604,25 +628,3 @@ func (t treeFromProto) parse() tree.CongestionTree {
|
||||
|
||||
return congestionTree
|
||||
}
|
||||
|
||||
type treeToProto tree.CongestionTree
|
||||
|
||||
func (t treeToProto) parse() *models.V1Tree {
|
||||
levels := make([]*models.V1TreeLevel, 0, len(t))
|
||||
for _, level := range t {
|
||||
nodes := make([]*models.V1Node, 0, len(level))
|
||||
for _, n := range level {
|
||||
nodes = append(nodes, &models.V1Node{
|
||||
Txid: n.Txid,
|
||||
Tx: n.Tx,
|
||||
ParentTxid: n.ParentTxid,
|
||||
})
|
||||
}
|
||||
levels = append(levels, &models.V1TreeLevel{
|
||||
Nodes: nodes,
|
||||
})
|
||||
}
|
||||
return &models.V1Tree{
|
||||
Levels: levels,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,6 +62,8 @@ type ClientService interface {
|
||||
|
||||
ArkServiceFinalizePayment(params *ArkServiceFinalizePaymentParams, opts ...ClientOption) (*ArkServiceFinalizePaymentOK, error)
|
||||
|
||||
ArkServiceGetBoardingAddress(params *ArkServiceGetBoardingAddressParams, opts ...ClientOption) (*ArkServiceGetBoardingAddressOK, error)
|
||||
|
||||
ArkServiceGetEventStream(params *ArkServiceGetEventStreamParams, opts ...ClientOption) (*ArkServiceGetEventStreamOK, error)
|
||||
|
||||
ArkServiceGetInfo(params *ArkServiceGetInfoParams, opts ...ClientOption) (*ArkServiceGetInfoOK, error)
|
||||
@@ -72,8 +74,6 @@ type ClientService interface {
|
||||
|
||||
ArkServiceListVtxos(params *ArkServiceListVtxosParams, opts ...ClientOption) (*ArkServiceListVtxosOK, error)
|
||||
|
||||
ArkServiceOnboard(params *ArkServiceOnboardParams, opts ...ClientOption) (*ArkServiceOnboardOK, error)
|
||||
|
||||
ArkServicePing(params *ArkServicePingParams, opts ...ClientOption) (*ArkServicePingOK, error)
|
||||
|
||||
ArkServiceRegisterPayment(params *ArkServiceRegisterPaymentParams, opts ...ClientOption) (*ArkServiceRegisterPaymentOK, error)
|
||||
@@ -233,6 +233,43 @@ func (a *Client) ArkServiceFinalizePayment(params *ArkServiceFinalizePaymentPara
|
||||
return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code())
|
||||
}
|
||||
|
||||
/*
|
||||
ArkServiceGetBoardingAddress ark service get boarding address API
|
||||
*/
|
||||
func (a *Client) ArkServiceGetBoardingAddress(params *ArkServiceGetBoardingAddressParams, opts ...ClientOption) (*ArkServiceGetBoardingAddressOK, error) {
|
||||
// TODO: Validate the params before sending
|
||||
if params == nil {
|
||||
params = NewArkServiceGetBoardingAddressParams()
|
||||
}
|
||||
op := &runtime.ClientOperation{
|
||||
ID: "ArkService_GetBoardingAddress",
|
||||
Method: "POST",
|
||||
PathPattern: "/v1/boarding",
|
||||
ProducesMediaTypes: []string{"application/json"},
|
||||
ConsumesMediaTypes: []string{"application/json"},
|
||||
Schemes: []string{"http"},
|
||||
Params: params,
|
||||
Reader: &ArkServiceGetBoardingAddressReader{formats: a.formats},
|
||||
Context: params.Context,
|
||||
Client: params.HTTPClient,
|
||||
}
|
||||
for _, opt := range opts {
|
||||
opt(op)
|
||||
}
|
||||
|
||||
result, err := a.transport.Submit(op)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
success, ok := result.(*ArkServiceGetBoardingAddressOK)
|
||||
if ok {
|
||||
return success, nil
|
||||
}
|
||||
// unexpected success response
|
||||
unexpectedSuccess := result.(*ArkServiceGetBoardingAddressDefault)
|
||||
return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code())
|
||||
}
|
||||
|
||||
/*
|
||||
ArkServiceGetEventStream ark service get event stream API
|
||||
*/
|
||||
@@ -418,43 +455,6 @@ func (a *Client) ArkServiceListVtxos(params *ArkServiceListVtxosParams, opts ...
|
||||
return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code())
|
||||
}
|
||||
|
||||
/*
|
||||
ArkServiceOnboard ark service onboard API
|
||||
*/
|
||||
func (a *Client) ArkServiceOnboard(params *ArkServiceOnboardParams, opts ...ClientOption) (*ArkServiceOnboardOK, error) {
|
||||
// TODO: Validate the params before sending
|
||||
if params == nil {
|
||||
params = NewArkServiceOnboardParams()
|
||||
}
|
||||
op := &runtime.ClientOperation{
|
||||
ID: "ArkService_Onboard",
|
||||
Method: "POST",
|
||||
PathPattern: "/v1/onboard",
|
||||
ProducesMediaTypes: []string{"application/json"},
|
||||
ConsumesMediaTypes: []string{"application/json"},
|
||||
Schemes: []string{"http"},
|
||||
Params: params,
|
||||
Reader: &ArkServiceOnboardReader{formats: a.formats},
|
||||
Context: params.Context,
|
||||
Client: params.HTTPClient,
|
||||
}
|
||||
for _, opt := range opts {
|
||||
opt(op)
|
||||
}
|
||||
|
||||
result, err := a.transport.Submit(op)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
success, ok := result.(*ArkServiceOnboardOK)
|
||||
if ok {
|
||||
return success, nil
|
||||
}
|
||||
// unexpected success response
|
||||
unexpectedSuccess := result.(*ArkServiceOnboardDefault)
|
||||
return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code())
|
||||
}
|
||||
|
||||
/*
|
||||
ArkServicePing ark service ping API
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package ark_service
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/runtime"
|
||||
cr "github.com/go-openapi/runtime/client"
|
||||
"github.com/go-openapi/strfmt"
|
||||
|
||||
"github.com/ark-network/ark/pkg/client-sdk/client/rest/service/models"
|
||||
)
|
||||
|
||||
// NewArkServiceGetBoardingAddressParams creates a new ArkServiceGetBoardingAddressParams object,
|
||||
// with the default timeout for this client.
|
||||
//
|
||||
// Default values are not hydrated, since defaults are normally applied by the API server side.
|
||||
//
|
||||
// To enforce default values in parameter, use SetDefaults or WithDefaults.
|
||||
func NewArkServiceGetBoardingAddressParams() *ArkServiceGetBoardingAddressParams {
|
||||
return &ArkServiceGetBoardingAddressParams{
|
||||
timeout: cr.DefaultTimeout,
|
||||
}
|
||||
}
|
||||
|
||||
// NewArkServiceGetBoardingAddressParamsWithTimeout creates a new ArkServiceGetBoardingAddressParams object
|
||||
// with the ability to set a timeout on a request.
|
||||
func NewArkServiceGetBoardingAddressParamsWithTimeout(timeout time.Duration) *ArkServiceGetBoardingAddressParams {
|
||||
return &ArkServiceGetBoardingAddressParams{
|
||||
timeout: timeout,
|
||||
}
|
||||
}
|
||||
|
||||
// NewArkServiceGetBoardingAddressParamsWithContext creates a new ArkServiceGetBoardingAddressParams object
|
||||
// with the ability to set a context for a request.
|
||||
func NewArkServiceGetBoardingAddressParamsWithContext(ctx context.Context) *ArkServiceGetBoardingAddressParams {
|
||||
return &ArkServiceGetBoardingAddressParams{
|
||||
Context: ctx,
|
||||
}
|
||||
}
|
||||
|
||||
// NewArkServiceGetBoardingAddressParamsWithHTTPClient creates a new ArkServiceGetBoardingAddressParams object
|
||||
// with the ability to set a custom HTTPClient for a request.
|
||||
func NewArkServiceGetBoardingAddressParamsWithHTTPClient(client *http.Client) *ArkServiceGetBoardingAddressParams {
|
||||
return &ArkServiceGetBoardingAddressParams{
|
||||
HTTPClient: client,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
ArkServiceGetBoardingAddressParams contains all the parameters to send to the API endpoint
|
||||
|
||||
for the ark service get boarding address operation.
|
||||
|
||||
Typically these are written to a http.Request.
|
||||
*/
|
||||
type ArkServiceGetBoardingAddressParams struct {
|
||||
|
||||
// Body.
|
||||
Body *models.V1GetBoardingAddressRequest
|
||||
|
||||
timeout time.Duration
|
||||
Context context.Context
|
||||
HTTPClient *http.Client
|
||||
}
|
||||
|
||||
// WithDefaults hydrates default values in the ark service get boarding address params (not the query body).
|
||||
//
|
||||
// All values with no default are reset to their zero value.
|
||||
func (o *ArkServiceGetBoardingAddressParams) WithDefaults() *ArkServiceGetBoardingAddressParams {
|
||||
o.SetDefaults()
|
||||
return o
|
||||
}
|
||||
|
||||
// SetDefaults hydrates default values in the ark service get boarding address params (not the query body).
|
||||
//
|
||||
// All values with no default are reset to their zero value.
|
||||
func (o *ArkServiceGetBoardingAddressParams) SetDefaults() {
|
||||
// no default values defined for this parameter
|
||||
}
|
||||
|
||||
// WithTimeout adds the timeout to the ark service get boarding address params
|
||||
func (o *ArkServiceGetBoardingAddressParams) WithTimeout(timeout time.Duration) *ArkServiceGetBoardingAddressParams {
|
||||
o.SetTimeout(timeout)
|
||||
return o
|
||||
}
|
||||
|
||||
// SetTimeout adds the timeout to the ark service get boarding address params
|
||||
func (o *ArkServiceGetBoardingAddressParams) SetTimeout(timeout time.Duration) {
|
||||
o.timeout = timeout
|
||||
}
|
||||
|
||||
// WithContext adds the context to the ark service get boarding address params
|
||||
func (o *ArkServiceGetBoardingAddressParams) WithContext(ctx context.Context) *ArkServiceGetBoardingAddressParams {
|
||||
o.SetContext(ctx)
|
||||
return o
|
||||
}
|
||||
|
||||
// SetContext adds the context to the ark service get boarding address params
|
||||
func (o *ArkServiceGetBoardingAddressParams) SetContext(ctx context.Context) {
|
||||
o.Context = ctx
|
||||
}
|
||||
|
||||
// WithHTTPClient adds the HTTPClient to the ark service get boarding address params
|
||||
func (o *ArkServiceGetBoardingAddressParams) WithHTTPClient(client *http.Client) *ArkServiceGetBoardingAddressParams {
|
||||
o.SetHTTPClient(client)
|
||||
return o
|
||||
}
|
||||
|
||||
// SetHTTPClient adds the HTTPClient to the ark service get boarding address params
|
||||
func (o *ArkServiceGetBoardingAddressParams) SetHTTPClient(client *http.Client) {
|
||||
o.HTTPClient = client
|
||||
}
|
||||
|
||||
// WithBody adds the body to the ark service get boarding address params
|
||||
func (o *ArkServiceGetBoardingAddressParams) WithBody(body *models.V1GetBoardingAddressRequest) *ArkServiceGetBoardingAddressParams {
|
||||
o.SetBody(body)
|
||||
return o
|
||||
}
|
||||
|
||||
// SetBody adds the body to the ark service get boarding address params
|
||||
func (o *ArkServiceGetBoardingAddressParams) SetBody(body *models.V1GetBoardingAddressRequest) {
|
||||
o.Body = body
|
||||
}
|
||||
|
||||
// WriteToRequest writes these params to a swagger request
|
||||
func (o *ArkServiceGetBoardingAddressParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
|
||||
|
||||
if err := r.SetTimeout(o.timeout); err != nil {
|
||||
return err
|
||||
}
|
||||
var res []error
|
||||
if o.Body != nil {
|
||||
if err := r.SetBodyParam(o.Body); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package ark_service
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/go-openapi/runtime"
|
||||
"github.com/go-openapi/strfmt"
|
||||
|
||||
"github.com/ark-network/ark/pkg/client-sdk/client/rest/service/models"
|
||||
)
|
||||
|
||||
// ArkServiceGetBoardingAddressReader is a Reader for the ArkServiceGetBoardingAddress structure.
|
||||
type ArkServiceGetBoardingAddressReader struct {
|
||||
formats strfmt.Registry
|
||||
}
|
||||
|
||||
// ReadResponse reads a server response into the received o.
|
||||
func (o *ArkServiceGetBoardingAddressReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
|
||||
switch response.Code() {
|
||||
case 200:
|
||||
result := NewArkServiceGetBoardingAddressOK()
|
||||
if err := result.readResponse(response, consumer, o.formats); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
default:
|
||||
result := NewArkServiceGetBoardingAddressDefault(response.Code())
|
||||
if err := result.readResponse(response, consumer, o.formats); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if response.Code()/100 == 2 {
|
||||
return result, nil
|
||||
}
|
||||
return nil, result
|
||||
}
|
||||
}
|
||||
|
||||
// NewArkServiceGetBoardingAddressOK creates a ArkServiceGetBoardingAddressOK with default headers values
|
||||
func NewArkServiceGetBoardingAddressOK() *ArkServiceGetBoardingAddressOK {
|
||||
return &ArkServiceGetBoardingAddressOK{}
|
||||
}
|
||||
|
||||
/*
|
||||
ArkServiceGetBoardingAddressOK describes a response with status code 200, with default header values.
|
||||
|
||||
A successful response.
|
||||
*/
|
||||
type ArkServiceGetBoardingAddressOK struct {
|
||||
Payload *models.V1GetBoardingAddressResponse
|
||||
}
|
||||
|
||||
// IsSuccess returns true when this ark service get boarding address o k response has a 2xx status code
|
||||
func (o *ArkServiceGetBoardingAddressOK) IsSuccess() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// IsRedirect returns true when this ark service get boarding address o k response has a 3xx status code
|
||||
func (o *ArkServiceGetBoardingAddressOK) IsRedirect() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IsClientError returns true when this ark service get boarding address o k response has a 4xx status code
|
||||
func (o *ArkServiceGetBoardingAddressOK) IsClientError() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IsServerError returns true when this ark service get boarding address o k response has a 5xx status code
|
||||
func (o *ArkServiceGetBoardingAddressOK) IsServerError() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IsCode returns true when this ark service get boarding address o k response a status code equal to that given
|
||||
func (o *ArkServiceGetBoardingAddressOK) IsCode(code int) bool {
|
||||
return code == 200
|
||||
}
|
||||
|
||||
// Code gets the status code for the ark service get boarding address o k response
|
||||
func (o *ArkServiceGetBoardingAddressOK) Code() int {
|
||||
return 200
|
||||
}
|
||||
|
||||
func (o *ArkServiceGetBoardingAddressOK) Error() string {
|
||||
payload, _ := json.Marshal(o.Payload)
|
||||
return fmt.Sprintf("[POST /v1/boarding][%d] arkServiceGetBoardingAddressOK %s", 200, payload)
|
||||
}
|
||||
|
||||
func (o *ArkServiceGetBoardingAddressOK) String() string {
|
||||
payload, _ := json.Marshal(o.Payload)
|
||||
return fmt.Sprintf("[POST /v1/boarding][%d] arkServiceGetBoardingAddressOK %s", 200, payload)
|
||||
}
|
||||
|
||||
func (o *ArkServiceGetBoardingAddressOK) GetPayload() *models.V1GetBoardingAddressResponse {
|
||||
return o.Payload
|
||||
}
|
||||
|
||||
func (o *ArkServiceGetBoardingAddressOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
|
||||
|
||||
o.Payload = new(models.V1GetBoardingAddressResponse)
|
||||
|
||||
// response payload
|
||||
if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewArkServiceGetBoardingAddressDefault creates a ArkServiceGetBoardingAddressDefault with default headers values
|
||||
func NewArkServiceGetBoardingAddressDefault(code int) *ArkServiceGetBoardingAddressDefault {
|
||||
return &ArkServiceGetBoardingAddressDefault{
|
||||
_statusCode: code,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
ArkServiceGetBoardingAddressDefault describes a response with status code -1, with default header values.
|
||||
|
||||
An unexpected error response.
|
||||
*/
|
||||
type ArkServiceGetBoardingAddressDefault struct {
|
||||
_statusCode int
|
||||
|
||||
Payload *models.RPCStatus
|
||||
}
|
||||
|
||||
// IsSuccess returns true when this ark service get boarding address default response has a 2xx status code
|
||||
func (o *ArkServiceGetBoardingAddressDefault) IsSuccess() bool {
|
||||
return o._statusCode/100 == 2
|
||||
}
|
||||
|
||||
// IsRedirect returns true when this ark service get boarding address default response has a 3xx status code
|
||||
func (o *ArkServiceGetBoardingAddressDefault) IsRedirect() bool {
|
||||
return o._statusCode/100 == 3
|
||||
}
|
||||
|
||||
// IsClientError returns true when this ark service get boarding address default response has a 4xx status code
|
||||
func (o *ArkServiceGetBoardingAddressDefault) IsClientError() bool {
|
||||
return o._statusCode/100 == 4
|
||||
}
|
||||
|
||||
// IsServerError returns true when this ark service get boarding address default response has a 5xx status code
|
||||
func (o *ArkServiceGetBoardingAddressDefault) IsServerError() bool {
|
||||
return o._statusCode/100 == 5
|
||||
}
|
||||
|
||||
// IsCode returns true when this ark service get boarding address default response a status code equal to that given
|
||||
func (o *ArkServiceGetBoardingAddressDefault) IsCode(code int) bool {
|
||||
return o._statusCode == code
|
||||
}
|
||||
|
||||
// Code gets the status code for the ark service get boarding address default response
|
||||
func (o *ArkServiceGetBoardingAddressDefault) Code() int {
|
||||
return o._statusCode
|
||||
}
|
||||
|
||||
func (o *ArkServiceGetBoardingAddressDefault) Error() string {
|
||||
payload, _ := json.Marshal(o.Payload)
|
||||
return fmt.Sprintf("[POST /v1/boarding][%d] ArkService_GetBoardingAddress default %s", o._statusCode, payload)
|
||||
}
|
||||
|
||||
func (o *ArkServiceGetBoardingAddressDefault) String() string {
|
||||
payload, _ := json.Marshal(o.Payload)
|
||||
return fmt.Sprintf("[POST /v1/boarding][%d] ArkService_GetBoardingAddress default %s", o._statusCode, payload)
|
||||
}
|
||||
|
||||
func (o *ArkServiceGetBoardingAddressDefault) GetPayload() *models.RPCStatus {
|
||||
return o.Payload
|
||||
}
|
||||
|
||||
func (o *ArkServiceGetBoardingAddressDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
|
||||
|
||||
o.Payload = new(models.RPCStatus)
|
||||
|
||||
// response payload
|
||||
if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -1,150 +0,0 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package ark_service
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/runtime"
|
||||
cr "github.com/go-openapi/runtime/client"
|
||||
"github.com/go-openapi/strfmt"
|
||||
|
||||
"github.com/ark-network/ark/pkg/client-sdk/client/rest/service/models"
|
||||
)
|
||||
|
||||
// NewArkServiceOnboardParams creates a new ArkServiceOnboardParams object,
|
||||
// with the default timeout for this client.
|
||||
//
|
||||
// Default values are not hydrated, since defaults are normally applied by the API server side.
|
||||
//
|
||||
// To enforce default values in parameter, use SetDefaults or WithDefaults.
|
||||
func NewArkServiceOnboardParams() *ArkServiceOnboardParams {
|
||||
return &ArkServiceOnboardParams{
|
||||
timeout: cr.DefaultTimeout,
|
||||
}
|
||||
}
|
||||
|
||||
// NewArkServiceOnboardParamsWithTimeout creates a new ArkServiceOnboardParams object
|
||||
// with the ability to set a timeout on a request.
|
||||
func NewArkServiceOnboardParamsWithTimeout(timeout time.Duration) *ArkServiceOnboardParams {
|
||||
return &ArkServiceOnboardParams{
|
||||
timeout: timeout,
|
||||
}
|
||||
}
|
||||
|
||||
// NewArkServiceOnboardParamsWithContext creates a new ArkServiceOnboardParams object
|
||||
// with the ability to set a context for a request.
|
||||
func NewArkServiceOnboardParamsWithContext(ctx context.Context) *ArkServiceOnboardParams {
|
||||
return &ArkServiceOnboardParams{
|
||||
Context: ctx,
|
||||
}
|
||||
}
|
||||
|
||||
// NewArkServiceOnboardParamsWithHTTPClient creates a new ArkServiceOnboardParams object
|
||||
// with the ability to set a custom HTTPClient for a request.
|
||||
func NewArkServiceOnboardParamsWithHTTPClient(client *http.Client) *ArkServiceOnboardParams {
|
||||
return &ArkServiceOnboardParams{
|
||||
HTTPClient: client,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
ArkServiceOnboardParams contains all the parameters to send to the API endpoint
|
||||
|
||||
for the ark service onboard operation.
|
||||
|
||||
Typically these are written to a http.Request.
|
||||
*/
|
||||
type ArkServiceOnboardParams struct {
|
||||
|
||||
// Body.
|
||||
Body *models.V1OnboardRequest
|
||||
|
||||
timeout time.Duration
|
||||
Context context.Context
|
||||
HTTPClient *http.Client
|
||||
}
|
||||
|
||||
// WithDefaults hydrates default values in the ark service onboard params (not the query body).
|
||||
//
|
||||
// All values with no default are reset to their zero value.
|
||||
func (o *ArkServiceOnboardParams) WithDefaults() *ArkServiceOnboardParams {
|
||||
o.SetDefaults()
|
||||
return o
|
||||
}
|
||||
|
||||
// SetDefaults hydrates default values in the ark service onboard params (not the query body).
|
||||
//
|
||||
// All values with no default are reset to their zero value.
|
||||
func (o *ArkServiceOnboardParams) SetDefaults() {
|
||||
// no default values defined for this parameter
|
||||
}
|
||||
|
||||
// WithTimeout adds the timeout to the ark service onboard params
|
||||
func (o *ArkServiceOnboardParams) WithTimeout(timeout time.Duration) *ArkServiceOnboardParams {
|
||||
o.SetTimeout(timeout)
|
||||
return o
|
||||
}
|
||||
|
||||
// SetTimeout adds the timeout to the ark service onboard params
|
||||
func (o *ArkServiceOnboardParams) SetTimeout(timeout time.Duration) {
|
||||
o.timeout = timeout
|
||||
}
|
||||
|
||||
// WithContext adds the context to the ark service onboard params
|
||||
func (o *ArkServiceOnboardParams) WithContext(ctx context.Context) *ArkServiceOnboardParams {
|
||||
o.SetContext(ctx)
|
||||
return o
|
||||
}
|
||||
|
||||
// SetContext adds the context to the ark service onboard params
|
||||
func (o *ArkServiceOnboardParams) SetContext(ctx context.Context) {
|
||||
o.Context = ctx
|
||||
}
|
||||
|
||||
// WithHTTPClient adds the HTTPClient to the ark service onboard params
|
||||
func (o *ArkServiceOnboardParams) WithHTTPClient(client *http.Client) *ArkServiceOnboardParams {
|
||||
o.SetHTTPClient(client)
|
||||
return o
|
||||
}
|
||||
|
||||
// SetHTTPClient adds the HTTPClient to the ark service onboard params
|
||||
func (o *ArkServiceOnboardParams) SetHTTPClient(client *http.Client) {
|
||||
o.HTTPClient = client
|
||||
}
|
||||
|
||||
// WithBody adds the body to the ark service onboard params
|
||||
func (o *ArkServiceOnboardParams) WithBody(body *models.V1OnboardRequest) *ArkServiceOnboardParams {
|
||||
o.SetBody(body)
|
||||
return o
|
||||
}
|
||||
|
||||
// SetBody adds the body to the ark service onboard params
|
||||
func (o *ArkServiceOnboardParams) SetBody(body *models.V1OnboardRequest) {
|
||||
o.Body = body
|
||||
}
|
||||
|
||||
// WriteToRequest writes these params to a swagger request
|
||||
func (o *ArkServiceOnboardParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
|
||||
|
||||
if err := r.SetTimeout(o.timeout); err != nil {
|
||||
return err
|
||||
}
|
||||
var res []error
|
||||
if o.Body != nil {
|
||||
if err := r.SetBodyParam(o.Body); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1,185 +0,0 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package ark_service
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/go-openapi/runtime"
|
||||
"github.com/go-openapi/strfmt"
|
||||
|
||||
"github.com/ark-network/ark/pkg/client-sdk/client/rest/service/models"
|
||||
)
|
||||
|
||||
// ArkServiceOnboardReader is a Reader for the ArkServiceOnboard structure.
|
||||
type ArkServiceOnboardReader struct {
|
||||
formats strfmt.Registry
|
||||
}
|
||||
|
||||
// ReadResponse reads a server response into the received o.
|
||||
func (o *ArkServiceOnboardReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
|
||||
switch response.Code() {
|
||||
case 200:
|
||||
result := NewArkServiceOnboardOK()
|
||||
if err := result.readResponse(response, consumer, o.formats); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
default:
|
||||
result := NewArkServiceOnboardDefault(response.Code())
|
||||
if err := result.readResponse(response, consumer, o.formats); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if response.Code()/100 == 2 {
|
||||
return result, nil
|
||||
}
|
||||
return nil, result
|
||||
}
|
||||
}
|
||||
|
||||
// NewArkServiceOnboardOK creates a ArkServiceOnboardOK with default headers values
|
||||
func NewArkServiceOnboardOK() *ArkServiceOnboardOK {
|
||||
return &ArkServiceOnboardOK{}
|
||||
}
|
||||
|
||||
/*
|
||||
ArkServiceOnboardOK describes a response with status code 200, with default header values.
|
||||
|
||||
A successful response.
|
||||
*/
|
||||
type ArkServiceOnboardOK struct {
|
||||
Payload models.V1OnboardResponse
|
||||
}
|
||||
|
||||
// IsSuccess returns true when this ark service onboard o k response has a 2xx status code
|
||||
func (o *ArkServiceOnboardOK) IsSuccess() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// IsRedirect returns true when this ark service onboard o k response has a 3xx status code
|
||||
func (o *ArkServiceOnboardOK) IsRedirect() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IsClientError returns true when this ark service onboard o k response has a 4xx status code
|
||||
func (o *ArkServiceOnboardOK) IsClientError() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IsServerError returns true when this ark service onboard o k response has a 5xx status code
|
||||
func (o *ArkServiceOnboardOK) IsServerError() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IsCode returns true when this ark service onboard o k response a status code equal to that given
|
||||
func (o *ArkServiceOnboardOK) IsCode(code int) bool {
|
||||
return code == 200
|
||||
}
|
||||
|
||||
// Code gets the status code for the ark service onboard o k response
|
||||
func (o *ArkServiceOnboardOK) Code() int {
|
||||
return 200
|
||||
}
|
||||
|
||||
func (o *ArkServiceOnboardOK) Error() string {
|
||||
payload, _ := json.Marshal(o.Payload)
|
||||
return fmt.Sprintf("[POST /v1/onboard][%d] arkServiceOnboardOK %s", 200, payload)
|
||||
}
|
||||
|
||||
func (o *ArkServiceOnboardOK) String() string {
|
||||
payload, _ := json.Marshal(o.Payload)
|
||||
return fmt.Sprintf("[POST /v1/onboard][%d] arkServiceOnboardOK %s", 200, payload)
|
||||
}
|
||||
|
||||
func (o *ArkServiceOnboardOK) GetPayload() models.V1OnboardResponse {
|
||||
return o.Payload
|
||||
}
|
||||
|
||||
func (o *ArkServiceOnboardOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
|
||||
|
||||
// response payload
|
||||
if err := consumer.Consume(response.Body(), &o.Payload); err != nil && err != io.EOF {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewArkServiceOnboardDefault creates a ArkServiceOnboardDefault with default headers values
|
||||
func NewArkServiceOnboardDefault(code int) *ArkServiceOnboardDefault {
|
||||
return &ArkServiceOnboardDefault{
|
||||
_statusCode: code,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
ArkServiceOnboardDefault describes a response with status code -1, with default header values.
|
||||
|
||||
An unexpected error response.
|
||||
*/
|
||||
type ArkServiceOnboardDefault struct {
|
||||
_statusCode int
|
||||
|
||||
Payload *models.RPCStatus
|
||||
}
|
||||
|
||||
// IsSuccess returns true when this ark service onboard default response has a 2xx status code
|
||||
func (o *ArkServiceOnboardDefault) IsSuccess() bool {
|
||||
return o._statusCode/100 == 2
|
||||
}
|
||||
|
||||
// IsRedirect returns true when this ark service onboard default response has a 3xx status code
|
||||
func (o *ArkServiceOnboardDefault) IsRedirect() bool {
|
||||
return o._statusCode/100 == 3
|
||||
}
|
||||
|
||||
// IsClientError returns true when this ark service onboard default response has a 4xx status code
|
||||
func (o *ArkServiceOnboardDefault) IsClientError() bool {
|
||||
return o._statusCode/100 == 4
|
||||
}
|
||||
|
||||
// IsServerError returns true when this ark service onboard default response has a 5xx status code
|
||||
func (o *ArkServiceOnboardDefault) IsServerError() bool {
|
||||
return o._statusCode/100 == 5
|
||||
}
|
||||
|
||||
// IsCode returns true when this ark service onboard default response a status code equal to that given
|
||||
func (o *ArkServiceOnboardDefault) IsCode(code int) bool {
|
||||
return o._statusCode == code
|
||||
}
|
||||
|
||||
// Code gets the status code for the ark service onboard default response
|
||||
func (o *ArkServiceOnboardDefault) Code() int {
|
||||
return o._statusCode
|
||||
}
|
||||
|
||||
func (o *ArkServiceOnboardDefault) Error() string {
|
||||
payload, _ := json.Marshal(o.Payload)
|
||||
return fmt.Sprintf("[POST /v1/onboard][%d] ArkService_Onboard default %s", o._statusCode, payload)
|
||||
}
|
||||
|
||||
func (o *ArkServiceOnboardDefault) String() string {
|
||||
payload, _ := json.Marshal(o.Payload)
|
||||
return fmt.Sprintf("[POST /v1/onboard][%d] ArkService_Onboard default %s", o._statusCode, payload)
|
||||
}
|
||||
|
||||
func (o *ArkServiceOnboardDefault) GetPayload() *models.RPCStatus {
|
||||
return o.Payload
|
||||
}
|
||||
|
||||
func (o *ArkServiceOnboardDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
|
||||
|
||||
o.Payload = new(models.RPCStatus)
|
||||
|
||||
// response payload
|
||||
if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -1,150 +0,0 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package ark_service
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/runtime"
|
||||
cr "github.com/go-openapi/runtime/client"
|
||||
"github.com/go-openapi/strfmt"
|
||||
|
||||
"github.com/ark-network/ark/pkg/client-sdk/client/rest/service/models"
|
||||
)
|
||||
|
||||
// NewArkServiceTrustedOnboardingParams creates a new ArkServiceTrustedOnboardingParams object,
|
||||
// with the default timeout for this client.
|
||||
//
|
||||
// Default values are not hydrated, since defaults are normally applied by the API server side.
|
||||
//
|
||||
// To enforce default values in parameter, use SetDefaults or WithDefaults.
|
||||
func NewArkServiceTrustedOnboardingParams() *ArkServiceTrustedOnboardingParams {
|
||||
return &ArkServiceTrustedOnboardingParams{
|
||||
timeout: cr.DefaultTimeout,
|
||||
}
|
||||
}
|
||||
|
||||
// NewArkServiceTrustedOnboardingParamsWithTimeout creates a new ArkServiceTrustedOnboardingParams object
|
||||
// with the ability to set a timeout on a request.
|
||||
func NewArkServiceTrustedOnboardingParamsWithTimeout(timeout time.Duration) *ArkServiceTrustedOnboardingParams {
|
||||
return &ArkServiceTrustedOnboardingParams{
|
||||
timeout: timeout,
|
||||
}
|
||||
}
|
||||
|
||||
// NewArkServiceTrustedOnboardingParamsWithContext creates a new ArkServiceTrustedOnboardingParams object
|
||||
// with the ability to set a context for a request.
|
||||
func NewArkServiceTrustedOnboardingParamsWithContext(ctx context.Context) *ArkServiceTrustedOnboardingParams {
|
||||
return &ArkServiceTrustedOnboardingParams{
|
||||
Context: ctx,
|
||||
}
|
||||
}
|
||||
|
||||
// NewArkServiceTrustedOnboardingParamsWithHTTPClient creates a new ArkServiceTrustedOnboardingParams object
|
||||
// with the ability to set a custom HTTPClient for a request.
|
||||
func NewArkServiceTrustedOnboardingParamsWithHTTPClient(client *http.Client) *ArkServiceTrustedOnboardingParams {
|
||||
return &ArkServiceTrustedOnboardingParams{
|
||||
HTTPClient: client,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
ArkServiceTrustedOnboardingParams contains all the parameters to send to the API endpoint
|
||||
|
||||
for the ark service trusted onboarding operation.
|
||||
|
||||
Typically these are written to a http.Request.
|
||||
*/
|
||||
type ArkServiceTrustedOnboardingParams struct {
|
||||
|
||||
// Body.
|
||||
Body *models.V1TrustedOnboardingRequest
|
||||
|
||||
timeout time.Duration
|
||||
Context context.Context
|
||||
HTTPClient *http.Client
|
||||
}
|
||||
|
||||
// WithDefaults hydrates default values in the ark service trusted onboarding params (not the query body).
|
||||
//
|
||||
// All values with no default are reset to their zero value.
|
||||
func (o *ArkServiceTrustedOnboardingParams) WithDefaults() *ArkServiceTrustedOnboardingParams {
|
||||
o.SetDefaults()
|
||||
return o
|
||||
}
|
||||
|
||||
// SetDefaults hydrates default values in the ark service trusted onboarding params (not the query body).
|
||||
//
|
||||
// All values with no default are reset to their zero value.
|
||||
func (o *ArkServiceTrustedOnboardingParams) SetDefaults() {
|
||||
// no default values defined for this parameter
|
||||
}
|
||||
|
||||
// WithTimeout adds the timeout to the ark service trusted onboarding params
|
||||
func (o *ArkServiceTrustedOnboardingParams) WithTimeout(timeout time.Duration) *ArkServiceTrustedOnboardingParams {
|
||||
o.SetTimeout(timeout)
|
||||
return o
|
||||
}
|
||||
|
||||
// SetTimeout adds the timeout to the ark service trusted onboarding params
|
||||
func (o *ArkServiceTrustedOnboardingParams) SetTimeout(timeout time.Duration) {
|
||||
o.timeout = timeout
|
||||
}
|
||||
|
||||
// WithContext adds the context to the ark service trusted onboarding params
|
||||
func (o *ArkServiceTrustedOnboardingParams) WithContext(ctx context.Context) *ArkServiceTrustedOnboardingParams {
|
||||
o.SetContext(ctx)
|
||||
return o
|
||||
}
|
||||
|
||||
// SetContext adds the context to the ark service trusted onboarding params
|
||||
func (o *ArkServiceTrustedOnboardingParams) SetContext(ctx context.Context) {
|
||||
o.Context = ctx
|
||||
}
|
||||
|
||||
// WithHTTPClient adds the HTTPClient to the ark service trusted onboarding params
|
||||
func (o *ArkServiceTrustedOnboardingParams) WithHTTPClient(client *http.Client) *ArkServiceTrustedOnboardingParams {
|
||||
o.SetHTTPClient(client)
|
||||
return o
|
||||
}
|
||||
|
||||
// SetHTTPClient adds the HTTPClient to the ark service trusted onboarding params
|
||||
func (o *ArkServiceTrustedOnboardingParams) SetHTTPClient(client *http.Client) {
|
||||
o.HTTPClient = client
|
||||
}
|
||||
|
||||
// WithBody adds the body to the ark service trusted onboarding params
|
||||
func (o *ArkServiceTrustedOnboardingParams) WithBody(body *models.V1TrustedOnboardingRequest) *ArkServiceTrustedOnboardingParams {
|
||||
o.SetBody(body)
|
||||
return o
|
||||
}
|
||||
|
||||
// SetBody adds the body to the ark service trusted onboarding params
|
||||
func (o *ArkServiceTrustedOnboardingParams) SetBody(body *models.V1TrustedOnboardingRequest) {
|
||||
o.Body = body
|
||||
}
|
||||
|
||||
// WriteToRequest writes these params to a swagger request
|
||||
func (o *ArkServiceTrustedOnboardingParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
|
||||
|
||||
if err := r.SetTimeout(o.timeout); err != nil {
|
||||
return err
|
||||
}
|
||||
var res []error
|
||||
if o.Body != nil {
|
||||
if err := r.SetBodyParam(o.Body); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1,187 +0,0 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package ark_service
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/go-openapi/runtime"
|
||||
"github.com/go-openapi/strfmt"
|
||||
|
||||
"github.com/ark-network/ark/pkg/client-sdk/client/rest/service/models"
|
||||
)
|
||||
|
||||
// ArkServiceTrustedOnboardingReader is a Reader for the ArkServiceTrustedOnboarding structure.
|
||||
type ArkServiceTrustedOnboardingReader struct {
|
||||
formats strfmt.Registry
|
||||
}
|
||||
|
||||
// ReadResponse reads a server response into the received o.
|
||||
func (o *ArkServiceTrustedOnboardingReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
|
||||
switch response.Code() {
|
||||
case 200:
|
||||
result := NewArkServiceTrustedOnboardingOK()
|
||||
if err := result.readResponse(response, consumer, o.formats); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
default:
|
||||
result := NewArkServiceTrustedOnboardingDefault(response.Code())
|
||||
if err := result.readResponse(response, consumer, o.formats); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if response.Code()/100 == 2 {
|
||||
return result, nil
|
||||
}
|
||||
return nil, result
|
||||
}
|
||||
}
|
||||
|
||||
// NewArkServiceTrustedOnboardingOK creates a ArkServiceTrustedOnboardingOK with default headers values
|
||||
func NewArkServiceTrustedOnboardingOK() *ArkServiceTrustedOnboardingOK {
|
||||
return &ArkServiceTrustedOnboardingOK{}
|
||||
}
|
||||
|
||||
/*
|
||||
ArkServiceTrustedOnboardingOK describes a response with status code 200, with default header values.
|
||||
|
||||
A successful response.
|
||||
*/
|
||||
type ArkServiceTrustedOnboardingOK struct {
|
||||
Payload *models.V1TrustedOnboardingResponse
|
||||
}
|
||||
|
||||
// IsSuccess returns true when this ark service trusted onboarding o k response has a 2xx status code
|
||||
func (o *ArkServiceTrustedOnboardingOK) IsSuccess() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// IsRedirect returns true when this ark service trusted onboarding o k response has a 3xx status code
|
||||
func (o *ArkServiceTrustedOnboardingOK) IsRedirect() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IsClientError returns true when this ark service trusted onboarding o k response has a 4xx status code
|
||||
func (o *ArkServiceTrustedOnboardingOK) IsClientError() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IsServerError returns true when this ark service trusted onboarding o k response has a 5xx status code
|
||||
func (o *ArkServiceTrustedOnboardingOK) IsServerError() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IsCode returns true when this ark service trusted onboarding o k response a status code equal to that given
|
||||
func (o *ArkServiceTrustedOnboardingOK) IsCode(code int) bool {
|
||||
return code == 200
|
||||
}
|
||||
|
||||
// Code gets the status code for the ark service trusted onboarding o k response
|
||||
func (o *ArkServiceTrustedOnboardingOK) Code() int {
|
||||
return 200
|
||||
}
|
||||
|
||||
func (o *ArkServiceTrustedOnboardingOK) Error() string {
|
||||
payload, _ := json.Marshal(o.Payload)
|
||||
return fmt.Sprintf("[POST /v1/onboard/address][%d] arkServiceTrustedOnboardingOK %s", 200, payload)
|
||||
}
|
||||
|
||||
func (o *ArkServiceTrustedOnboardingOK) String() string {
|
||||
payload, _ := json.Marshal(o.Payload)
|
||||
return fmt.Sprintf("[POST /v1/onboard/address][%d] arkServiceTrustedOnboardingOK %s", 200, payload)
|
||||
}
|
||||
|
||||
func (o *ArkServiceTrustedOnboardingOK) GetPayload() *models.V1TrustedOnboardingResponse {
|
||||
return o.Payload
|
||||
}
|
||||
|
||||
func (o *ArkServiceTrustedOnboardingOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
|
||||
|
||||
o.Payload = new(models.V1TrustedOnboardingResponse)
|
||||
|
||||
// response payload
|
||||
if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewArkServiceTrustedOnboardingDefault creates a ArkServiceTrustedOnboardingDefault with default headers values
|
||||
func NewArkServiceTrustedOnboardingDefault(code int) *ArkServiceTrustedOnboardingDefault {
|
||||
return &ArkServiceTrustedOnboardingDefault{
|
||||
_statusCode: code,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
ArkServiceTrustedOnboardingDefault describes a response with status code -1, with default header values.
|
||||
|
||||
An unexpected error response.
|
||||
*/
|
||||
type ArkServiceTrustedOnboardingDefault struct {
|
||||
_statusCode int
|
||||
|
||||
Payload *models.RPCStatus
|
||||
}
|
||||
|
||||
// IsSuccess returns true when this ark service trusted onboarding default response has a 2xx status code
|
||||
func (o *ArkServiceTrustedOnboardingDefault) IsSuccess() bool {
|
||||
return o._statusCode/100 == 2
|
||||
}
|
||||
|
||||
// IsRedirect returns true when this ark service trusted onboarding default response has a 3xx status code
|
||||
func (o *ArkServiceTrustedOnboardingDefault) IsRedirect() bool {
|
||||
return o._statusCode/100 == 3
|
||||
}
|
||||
|
||||
// IsClientError returns true when this ark service trusted onboarding default response has a 4xx status code
|
||||
func (o *ArkServiceTrustedOnboardingDefault) IsClientError() bool {
|
||||
return o._statusCode/100 == 4
|
||||
}
|
||||
|
||||
// IsServerError returns true when this ark service trusted onboarding default response has a 5xx status code
|
||||
func (o *ArkServiceTrustedOnboardingDefault) IsServerError() bool {
|
||||
return o._statusCode/100 == 5
|
||||
}
|
||||
|
||||
// IsCode returns true when this ark service trusted onboarding default response a status code equal to that given
|
||||
func (o *ArkServiceTrustedOnboardingDefault) IsCode(code int) bool {
|
||||
return o._statusCode == code
|
||||
}
|
||||
|
||||
// Code gets the status code for the ark service trusted onboarding default response
|
||||
func (o *ArkServiceTrustedOnboardingDefault) Code() int {
|
||||
return o._statusCode
|
||||
}
|
||||
|
||||
func (o *ArkServiceTrustedOnboardingDefault) Error() string {
|
||||
payload, _ := json.Marshal(o.Payload)
|
||||
return fmt.Sprintf("[POST /v1/onboard/address][%d] ArkService_TrustedOnboarding default %s", o._statusCode, payload)
|
||||
}
|
||||
|
||||
func (o *ArkServiceTrustedOnboardingDefault) String() string {
|
||||
payload, _ := json.Marshal(o.Payload)
|
||||
return fmt.Sprintf("[POST /v1/onboard/address][%d] ArkService_TrustedOnboarding default %s", o._statusCode, payload)
|
||||
}
|
||||
|
||||
func (o *ArkServiceTrustedOnboardingDefault) GetPayload() *models.RPCStatus {
|
||||
return o.Payload
|
||||
}
|
||||
|
||||
func (o *ArkServiceTrustedOnboardingDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
|
||||
|
||||
o.Payload = new(models.RPCStatus)
|
||||
|
||||
// response payload
|
||||
if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package models
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// V1BoardingInput v1 boarding input
|
||||
//
|
||||
// swagger:model v1BoardingInput
|
||||
type V1BoardingInput struct {
|
||||
|
||||
// descriptor
|
||||
Descriptor string `json:"descriptor,omitempty"`
|
||||
|
||||
// txid
|
||||
Txid string `json:"txid,omitempty"`
|
||||
|
||||
// vout
|
||||
Vout int64 `json:"vout,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this v1 boarding input
|
||||
func (m *V1BoardingInput) Validate(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validates this v1 boarding input based on context it is used
|
||||
func (m *V1BoardingInput) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *V1BoardingInput) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *V1BoardingInput) UnmarshalBinary(b []byte) error {
|
||||
var res V1BoardingInput
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
@@ -19,6 +19,9 @@ type V1FinalizePaymentRequest struct {
|
||||
|
||||
// Forfeit txs signed by the user.
|
||||
SignedForfeitTxs []string `json:"signedForfeitTxs"`
|
||||
|
||||
// If payment has reverse boarding, the user must sign the associated inputs.
|
||||
SignedRoundTx string `json:"signedRoundTx,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this v1 finalize payment request
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package models
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// V1GetBoardingAddressRequest v1 get boarding address request
|
||||
//
|
||||
// swagger:model v1GetBoardingAddressRequest
|
||||
type V1GetBoardingAddressRequest struct {
|
||||
|
||||
// pubkey
|
||||
Pubkey string `json:"pubkey,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this v1 get boarding address request
|
||||
func (m *V1GetBoardingAddressRequest) Validate(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validates this v1 get boarding address request based on context it is used
|
||||
func (m *V1GetBoardingAddressRequest) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *V1GetBoardingAddressRequest) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *V1GetBoardingAddressRequest) UnmarshalBinary(b []byte) error {
|
||||
var res V1GetBoardingAddressRequest
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package models
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// V1GetBoardingAddressResponse v1 get boarding address response
|
||||
//
|
||||
// swagger:model v1GetBoardingAddressResponse
|
||||
type V1GetBoardingAddressResponse struct {
|
||||
|
||||
// address
|
||||
Address string `json:"address,omitempty"`
|
||||
|
||||
// descriptor
|
||||
Descriptor string `json:"descriptor,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this v1 get boarding address response
|
||||
func (m *V1GetBoardingAddressResponse) Validate(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validates this v1 get boarding address response based on context it is used
|
||||
func (m *V1GetBoardingAddressResponse) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *V1GetBoardingAddressResponse) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *V1GetBoardingAddressResponse) UnmarshalBinary(b []byte) error {
|
||||
var res V1GetBoardingAddressResponse
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
@@ -17,6 +17,9 @@ import (
|
||||
// swagger:model v1GetInfoResponse
|
||||
type V1GetInfoResponse struct {
|
||||
|
||||
// boarding descriptor template
|
||||
BoardingDescriptorTemplate string `json:"boardingDescriptorTemplate,omitempty"`
|
||||
|
||||
// min relay fee
|
||||
MinRelayFee string `json:"minRelayFee,omitempty"`
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ package models
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
@@ -17,20 +18,126 @@ import (
|
||||
// swagger:model v1Input
|
||||
type V1Input struct {
|
||||
|
||||
// txid
|
||||
Txid string `json:"txid,omitempty"`
|
||||
// boarding input
|
||||
BoardingInput *V1BoardingInput `json:"boardingInput,omitempty"`
|
||||
|
||||
// vout
|
||||
Vout int64 `json:"vout,omitempty"`
|
||||
// vtxo input
|
||||
VtxoInput *V1VtxoInput `json:"vtxoInput,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this v1 input
|
||||
func (m *V1Input) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validateBoardingInput(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateVtxoInput(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validates this v1 input based on context it is used
|
||||
func (m *V1Input) validateBoardingInput(formats strfmt.Registry) error {
|
||||
if swag.IsZero(m.BoardingInput) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
if m.BoardingInput != nil {
|
||||
if err := m.BoardingInput.Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("boardingInput")
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("boardingInput")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *V1Input) validateVtxoInput(formats strfmt.Registry) error {
|
||||
if swag.IsZero(m.VtxoInput) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
if m.VtxoInput != nil {
|
||||
if err := m.VtxoInput.Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("vtxoInput")
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("vtxoInput")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validate this v1 input based on the context it is used
|
||||
func (m *V1Input) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.contextValidateBoardingInput(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.contextValidateVtxoInput(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *V1Input) contextValidateBoardingInput(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
if m.BoardingInput != nil {
|
||||
|
||||
if swag.IsZero(m.BoardingInput) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := m.BoardingInput.ContextValidate(ctx, formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("boardingInput")
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("boardingInput")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *V1Input) contextValidateVtxoInput(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
if m.VtxoInput != nil {
|
||||
|
||||
if swag.IsZero(m.VtxoInput) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := m.VtxoInput.ContextValidate(ctx, formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("vtxoInput")
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("vtxoInput")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -1,115 +0,0 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package models
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// V1OnboardRequest v1 onboard request
|
||||
//
|
||||
// swagger:model v1OnboardRequest
|
||||
type V1OnboardRequest struct {
|
||||
|
||||
// boarding tx
|
||||
BoardingTx string `json:"boardingTx,omitempty"`
|
||||
|
||||
// congestion tree
|
||||
CongestionTree *V1Tree `json:"congestionTree,omitempty"`
|
||||
|
||||
// user pubkey
|
||||
UserPubkey string `json:"userPubkey,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this v1 onboard request
|
||||
func (m *V1OnboardRequest) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validateCongestionTree(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *V1OnboardRequest) validateCongestionTree(formats strfmt.Registry) error {
|
||||
if swag.IsZero(m.CongestionTree) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
if m.CongestionTree != nil {
|
||||
if err := m.CongestionTree.Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("congestionTree")
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("congestionTree")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validate this v1 onboard request based on the context it is used
|
||||
func (m *V1OnboardRequest) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.contextValidateCongestionTree(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *V1OnboardRequest) contextValidateCongestionTree(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
if m.CongestionTree != nil {
|
||||
|
||||
if swag.IsZero(m.CongestionTree) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := m.CongestionTree.ContextValidate(ctx, formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("congestionTree")
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("congestionTree")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *V1OnboardRequest) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *V1OnboardRequest) UnmarshalBinary(b []byte) error {
|
||||
var res V1OnboardRequest
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package models
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
// V1OnboardResponse v1 onboard response
|
||||
//
|
||||
// swagger:model v1OnboardResponse
|
||||
type V1OnboardResponse interface{}
|
||||
@@ -1,50 +0,0 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package models
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// V1TrustedOnboardingRequest v1 trusted onboarding request
|
||||
//
|
||||
// swagger:model v1TrustedOnboardingRequest
|
||||
type V1TrustedOnboardingRequest struct {
|
||||
|
||||
// user pubkey
|
||||
UserPubkey string `json:"userPubkey,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this v1 trusted onboarding request
|
||||
func (m *V1TrustedOnboardingRequest) Validate(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validates this v1 trusted onboarding request based on context it is used
|
||||
func (m *V1TrustedOnboardingRequest) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *V1TrustedOnboardingRequest) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *V1TrustedOnboardingRequest) UnmarshalBinary(b []byte) error {
|
||||
var res V1TrustedOnboardingRequest
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package models
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// V1TrustedOnboardingResponse v1 trusted onboarding response
|
||||
//
|
||||
// swagger:model v1TrustedOnboardingResponse
|
||||
type V1TrustedOnboardingResponse struct {
|
||||
|
||||
// address
|
||||
Address string `json:"address,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this v1 trusted onboarding response
|
||||
func (m *V1TrustedOnboardingResponse) Validate(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validates this v1 trusted onboarding response based on context it is used
|
||||
func (m *V1TrustedOnboardingResponse) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *V1TrustedOnboardingResponse) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *V1TrustedOnboardingResponse) UnmarshalBinary(b []byte) error {
|
||||
var res V1TrustedOnboardingResponse
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
53
pkg/client-sdk/client/rest/service/models/v1_vtxo_input.go
Normal file
53
pkg/client-sdk/client/rest/service/models/v1_vtxo_input.go
Normal file
@@ -0,0 +1,53 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package models
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// V1VtxoInput v1 vtxo input
|
||||
//
|
||||
// swagger:model v1VtxoInput
|
||||
type V1VtxoInput struct {
|
||||
|
||||
// txid
|
||||
Txid string `json:"txid,omitempty"`
|
||||
|
||||
// vout
|
||||
Vout int64 `json:"vout,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this v1 vtxo input
|
||||
func (m *V1VtxoInput) Validate(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validates this v1 vtxo input based on context it is used
|
||||
func (m *V1VtxoInput) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *V1VtxoInput) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *V1VtxoInput) UnmarshalBinary(b []byte) error {
|
||||
var res V1VtxoInput
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/ark-network/ark/common"
|
||||
"github.com/ark-network/ark/common/descriptor"
|
||||
"github.com/ark-network/ark/common/tree"
|
||||
"github.com/ark-network/ark/pkg/client-sdk/client"
|
||||
"github.com/ark-network/ark/pkg/client-sdk/explorer"
|
||||
@@ -23,12 +24,7 @@ import (
|
||||
"github.com/decred/dcrd/dcrec/secp256k1/v4"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/vulpemventures/go-elements/address"
|
||||
"github.com/vulpemventures/go-elements/elementsutil"
|
||||
"github.com/vulpemventures/go-elements/network"
|
||||
"github.com/vulpemventures/go-elements/payment"
|
||||
"github.com/vulpemventures/go-elements/psetv2"
|
||||
"github.com/vulpemventures/go-elements/taproot"
|
||||
"github.com/vulpemventures/go-elements/transaction"
|
||||
)
|
||||
|
||||
type liquidReceiver struct {
|
||||
@@ -139,92 +135,24 @@ func LoadCovenantClientWithWallet(
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (a *covenantArkClient) Onboard(
|
||||
ctx context.Context, amount uint64,
|
||||
) (string, error) {
|
||||
if amount <= 0 {
|
||||
return "", fmt.Errorf("invalid amount to onboard %d", amount)
|
||||
}
|
||||
|
||||
offchainAddr, _, err := a.wallet.NewAddress(ctx, false)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
net := utils.ToElementsNetwork(a.Network)
|
||||
_, userPubkey, aspPubkey, _ := common.DecodeAddress(offchainAddr)
|
||||
userPubkeyStr := hex.EncodeToString(userPubkey.SerializeCompressed())
|
||||
congestionTreeLeaf := tree.Receiver{
|
||||
Pubkey: userPubkeyStr,
|
||||
Amount: amount,
|
||||
}
|
||||
|
||||
treeFactoryFn, sharedOutputScript, sharedOutputAmount, err := tree.CraftCongestionTree(
|
||||
net.AssetID,
|
||||
aspPubkey,
|
||||
[]tree.Receiver{congestionTreeLeaf},
|
||||
a.MinRelayFee,
|
||||
a.RoundLifetime,
|
||||
a.UnilateralExitDelay,
|
||||
)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
pay, err := payment.FromScript(sharedOutputScript, &net, nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
addr, err := pay.TaprootAddress()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
onchainReceiver := NewLiquidReceiver(addr, sharedOutputAmount)
|
||||
|
||||
pset, err := a.sendOnchain(ctx, []Receiver{onchainReceiver})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
ptx, _ := psetv2.NewPsetFromBase64(pset)
|
||||
utx, _ := ptx.UnsignedTx()
|
||||
txid := utx.TxHash().String()
|
||||
|
||||
congestionTree, err := treeFactoryFn(psetv2.InputArgs{
|
||||
Txid: txid,
|
||||
TxIndex: 0,
|
||||
})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if err := a.client.Onboard(
|
||||
ctx, pset, userPubkeyStr, congestionTree,
|
||||
); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return txid, nil
|
||||
}
|
||||
|
||||
func (a *covenantArkClient) Balance(
|
||||
ctx context.Context, computeVtxoExpiration bool,
|
||||
) (*Balance, error) {
|
||||
offchainAddrs, onchainAddrs, redeemAddrs, err := a.wallet.GetAddresses(ctx)
|
||||
offchainAddrs, boardingAddrs, redeemAddrs, err := a.wallet.GetAddresses(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
const nbWorkers = 3
|
||||
wg := &sync.WaitGroup{}
|
||||
wg.Add(3 * len(offchainAddrs))
|
||||
wg.Add(nbWorkers * len(offchainAddrs))
|
||||
|
||||
chRes := make(chan balanceRes, 3)
|
||||
chRes := make(chan balanceRes, nbWorkers*len(offchainAddrs))
|
||||
for i := range offchainAddrs {
|
||||
offchainAddr := offchainAddrs[i]
|
||||
onchainAddr := onchainAddrs[i]
|
||||
boardingAddr := boardingAddrs[i]
|
||||
redeemAddr := redeemAddrs[i]
|
||||
|
||||
go func(addr string) {
|
||||
defer wg.Done()
|
||||
balance, amountByExpiration, err := a.getOffchainBalance(
|
||||
@@ -241,17 +169,7 @@ func (a *covenantArkClient) Balance(
|
||||
}
|
||||
}(offchainAddr)
|
||||
|
||||
go func(addr string) {
|
||||
defer wg.Done()
|
||||
balance, err := a.explorer.GetBalance(addr)
|
||||
if err != nil {
|
||||
chRes <- balanceRes{err: err}
|
||||
return
|
||||
}
|
||||
chRes <- balanceRes{onchainSpendableBalance: balance}
|
||||
}(onchainAddr)
|
||||
|
||||
go func(addr string) {
|
||||
getDelayedBalance := func(addr string) {
|
||||
defer wg.Done()
|
||||
|
||||
spendableBalance, lockedBalance, err := a.explorer.GetRedeemedVtxosBalance(
|
||||
@@ -267,7 +185,10 @@ func (a *covenantArkClient) Balance(
|
||||
onchainLockedBalance: lockedBalance,
|
||||
err: err,
|
||||
}
|
||||
}(redeemAddr)
|
||||
}
|
||||
|
||||
go getDelayedBalance(boardingAddr)
|
||||
go getDelayedBalance(redeemAddr)
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
@@ -317,7 +238,7 @@ func (a *covenantArkClient) Balance(
|
||||
}
|
||||
|
||||
count++
|
||||
if count == 3 {
|
||||
if count == nbWorkers {
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -519,7 +440,7 @@ func (a *covenantArkClient) CollaborativeRedeem(
|
||||
})
|
||||
}
|
||||
|
||||
inputs := make([]client.VtxoKey, 0, len(selectedCoins))
|
||||
inputs := make([]client.Input, 0, len(selectedCoins))
|
||||
|
||||
for _, coin := range selectedCoins {
|
||||
inputs = append(inputs, client.VtxoKey{
|
||||
@@ -538,7 +459,7 @@ func (a *covenantArkClient) CollaborativeRedeem(
|
||||
}
|
||||
|
||||
poolTxID, err := a.handleRoundStream(
|
||||
ctx, paymentID, selectedCoins, receivers,
|
||||
ctx, paymentID, selectedCoins, false, receivers,
|
||||
)
|
||||
if err != nil {
|
||||
return "", err
|
||||
@@ -554,8 +475,85 @@ func (a *covenantArkClient) SendAsync(
|
||||
return "", fmt.Errorf("not implemented")
|
||||
}
|
||||
|
||||
func (a *covenantArkClient) ClaimAsync(ctx context.Context) (string, error) {
|
||||
return "", fmt.Errorf("not implemented")
|
||||
func (a *covenantArkClient) Claim(ctx context.Context) (string, error) {
|
||||
myselfOffchain, _, err := a.wallet.NewAddress(ctx, false)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
_, mypubkey, _, err := common.DecodeAddress(myselfOffchain)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
boardingUtxos, err := a.getClaimableBoardingUtxos(ctx)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
var pendingBalance uint64
|
||||
for _, vtxo := range boardingUtxos {
|
||||
pendingBalance += vtxo.Amount
|
||||
}
|
||||
if pendingBalance == 0 {
|
||||
return "", fmt.Errorf("no funds to claim")
|
||||
}
|
||||
|
||||
receiver := client.Output{
|
||||
Address: myselfOffchain,
|
||||
Amount: pendingBalance,
|
||||
}
|
||||
|
||||
desc := strings.ReplaceAll(a.BoardingDescriptorTemplate, "USER", hex.EncodeToString(schnorr.SerializePubKey(mypubkey)))
|
||||
|
||||
return a.selfTransferAllPendingPayments(ctx, boardingUtxos, receiver, desc)
|
||||
}
|
||||
|
||||
func (a *covenantArkClient) getClaimableBoardingUtxos(ctx context.Context) ([]explorer.Utxo, error) {
|
||||
offchainAddrs, boardingAddrs, _, err := a.wallet.GetAddresses(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
claimable := make([]explorer.Utxo, 0)
|
||||
now := time.Now()
|
||||
|
||||
_, myPubkey, _, err := common.DecodeAddress(offchainAddrs[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
myPubkeyStr := hex.EncodeToString(schnorr.SerializePubKey(myPubkey))
|
||||
descriptorStr := strings.ReplaceAll(
|
||||
a.BoardingDescriptorTemplate, "USER", myPubkeyStr,
|
||||
)
|
||||
desc, err := descriptor.ParseTaprootDescriptor(descriptorStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_, boardingTimeout, err := descriptor.ParseBoardingDescriptor(*desc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, addr := range boardingAddrs {
|
||||
boardingUtxos, err := a.explorer.GetUtxos(addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, utxo := range boardingUtxos {
|
||||
u := utxo.ToUtxo(boardingTimeout)
|
||||
|
||||
if u.SpendableAt.Before(now) {
|
||||
continue
|
||||
}
|
||||
claimable = append(claimable, u)
|
||||
}
|
||||
}
|
||||
|
||||
return claimable, nil
|
||||
}
|
||||
|
||||
func (a *covenantArkClient) sendOnchain(
|
||||
@@ -599,14 +597,14 @@ func (a *covenantArkClient) sendOnchain(
|
||||
}
|
||||
}
|
||||
|
||||
utxos, delayedUtxos, change, err := a.coinSelectOnchain(
|
||||
utxos, change, err := a.coinSelectOnchain(
|
||||
ctx, targetAmount, nil,
|
||||
)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if err := a.addInputs(ctx, updater, utxos, delayedUtxos, net); err != nil {
|
||||
if err := a.addInputs(ctx, updater, utxos); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
@@ -649,14 +647,14 @@ func (a *covenantArkClient) sendOnchain(
|
||||
updater.Pset.Outputs = updater.Pset.Outputs[:len(updater.Pset.Outputs)-1]
|
||||
}
|
||||
// reselect the difference
|
||||
selected, delayedSelected, newChange, err := a.coinSelectOnchain(
|
||||
ctx, feeAmount-change, append(utxos, delayedUtxos...),
|
||||
selected, newChange, err := a.coinSelectOnchain(
|
||||
ctx, feeAmount-change, utxos,
|
||||
)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if err := a.addInputs(ctx, updater, selected, delayedSelected, net); err != nil {
|
||||
if err := a.addInputs(ctx, updater, selected); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
@@ -787,7 +785,7 @@ func (a *covenantArkClient) sendOffchain(
|
||||
receiversOutput = append(receiversOutput, changeReceiver)
|
||||
}
|
||||
|
||||
inputs := make([]client.VtxoKey, 0, len(selectedCoins))
|
||||
inputs := make([]client.Input, 0, len(selectedCoins))
|
||||
for _, coin := range selectedCoins {
|
||||
inputs = append(inputs, client.VtxoKey{
|
||||
Txid: coin.Txid,
|
||||
@@ -811,7 +809,7 @@ func (a *covenantArkClient) sendOffchain(
|
||||
log.Infof("payment registered with id: %s", paymentID)
|
||||
|
||||
poolTxID, err := a.handleRoundStream(
|
||||
ctx, paymentID, selectedCoins, receiversOutput,
|
||||
ctx, paymentID, selectedCoins, false, receiversOutput,
|
||||
)
|
||||
if err != nil {
|
||||
return "", err
|
||||
@@ -821,126 +819,60 @@ func (a *covenantArkClient) sendOffchain(
|
||||
}
|
||||
|
||||
func (a *covenantArkClient) addInputs(
|
||||
ctx context.Context, updater *psetv2.Updater, utxos, delayedUtxos []explorer.Utxo, net network.Network,
|
||||
ctx context.Context,
|
||||
updater *psetv2.Updater,
|
||||
utxos []explorer.Utxo,
|
||||
) error {
|
||||
offchainAddr, onchainAddr, err := a.wallet.NewAddress(ctx, false)
|
||||
// TODO works only with single-key wallet
|
||||
offchain, _, err := a.wallet.NewAddress(ctx, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, userPubkey, aspPubkey, _ := common.DecodeAddress(offchainAddr)
|
||||
|
||||
changeScript, err := address.ToOutputScript(onchainAddr)
|
||||
_, userPubkey, aspPubkey, err := common.DecodeAddress(offchain)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, utxo := range utxos {
|
||||
sequence, err := utxo.Sequence()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := updater.AddInputs([]psetv2.InputArgs{
|
||||
{
|
||||
Txid: utxo.Txid,
|
||||
TxIndex: utxo.Vout,
|
||||
Txid: utxo.Txid,
|
||||
TxIndex: utxo.Vout,
|
||||
Sequence: sequence,
|
||||
},
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
assetID, err := elementsutil.AssetHashToBytes(utxo.Asset)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
value, err := elementsutil.ValueToBytes(utxo.Amount)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
witnessUtxo := transaction.TxOutput{
|
||||
Asset: assetID,
|
||||
Value: value,
|
||||
Script: changeScript,
|
||||
Nonce: []byte{0x00},
|
||||
}
|
||||
|
||||
if err := updater.AddInWitnessUtxo(
|
||||
len(updater.Pset.Inputs)-1, &witnessUtxo,
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if len(delayedUtxos) > 0 {
|
||||
_, leafProof, script, _, err := tree.ComputeVtxoTaprootScript(
|
||||
userPubkey, aspPubkey, uint(a.UnilateralExitDelay), net,
|
||||
_, leafProof, _, _, err := tree.ComputeVtxoTaprootScript(
|
||||
userPubkey, aspPubkey, utxo.Delay, utils.ToElementsNetwork(a.Network),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, utxo := range delayedUtxos {
|
||||
if err := a.addVtxoInput(
|
||||
updater,
|
||||
psetv2.InputArgs{
|
||||
Txid: utxo.Txid,
|
||||
TxIndex: utxo.Vout,
|
||||
},
|
||||
uint(a.UnilateralExitDelay),
|
||||
leafProof,
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
inputIndex := len(updater.Pset.Inputs) - 1
|
||||
|
||||
assetID, err := elementsutil.AssetHashToBytes(utxo.Asset)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
value, err := elementsutil.ValueToBytes(utxo.Amount)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
witnessUtxo := transaction.NewTxOutput(assetID, value, script)
|
||||
|
||||
if err := updater.AddInWitnessUtxo(
|
||||
len(updater.Pset.Inputs)-1, witnessUtxo,
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := updater.AddInTapLeafScript(inputIndex, psetv2.NewTapLeafScript(*leafProof, tree.UnspendableKey())); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *covenantArkClient) addVtxoInput(
|
||||
updater *psetv2.Updater, inputArgs psetv2.InputArgs, exitDelay uint,
|
||||
tapLeafProof *taproot.TapscriptElementsProof,
|
||||
) error {
|
||||
sequence, err := common.BIP68EncodeAsNumber(exitDelay)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
nextInputIndex := len(updater.Pset.Inputs)
|
||||
if err := updater.AddInputs([]psetv2.InputArgs{inputArgs}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
updater.Pset.Inputs[nextInputIndex].Sequence = sequence
|
||||
|
||||
return updater.AddInTapLeafScript(
|
||||
nextInputIndex,
|
||||
psetv2.NewTapLeafScript(
|
||||
*tapLeafProof,
|
||||
tree.UnspendableKey(),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
func (a *covenantArkClient) handleRoundStream(
|
||||
ctx context.Context,
|
||||
paymentID string, vtxosToSign []client.Vtxo, receivers []client.Output,
|
||||
paymentID string,
|
||||
vtxosToSign []client.Vtxo,
|
||||
mustSignRoundTx bool,
|
||||
receivers []client.Output,
|
||||
) (string, error) {
|
||||
eventsCh, err := a.client.GetEventStream(ctx, paymentID)
|
||||
if err != nil {
|
||||
@@ -972,20 +904,20 @@ func (a *covenantArkClient) handleRoundStream(
|
||||
pingStop()
|
||||
log.Info("a round finalization started")
|
||||
|
||||
signedForfeitTxs, err := a.handleRoundFinalization(
|
||||
ctx, event.(client.RoundFinalizationEvent), vtxosToSign, receivers,
|
||||
signedForfeitTxs, signedRoundTx, err := a.handleRoundFinalization(
|
||||
ctx, event.(client.RoundFinalizationEvent), vtxosToSign, mustSignRoundTx, receivers,
|
||||
)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if len(signedForfeitTxs) <= 0 {
|
||||
if len(signedForfeitTxs) <= 0 && len(vtxosToSign) > 0 {
|
||||
log.Info("no forfeit txs to sign, waiting for the next round")
|
||||
continue
|
||||
}
|
||||
|
||||
log.Info("finalizing payment... ")
|
||||
if err := a.client.FinalizePayment(ctx, signedForfeitTxs); err != nil {
|
||||
if err := a.client.FinalizePayment(ctx, signedForfeitTxs, signedRoundTx); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
@@ -998,15 +930,29 @@ func (a *covenantArkClient) handleRoundStream(
|
||||
|
||||
func (a *covenantArkClient) handleRoundFinalization(
|
||||
ctx context.Context, event client.RoundFinalizationEvent,
|
||||
vtxos []client.Vtxo, receivers []client.Output,
|
||||
) ([]string, error) {
|
||||
if err := a.validateCongestionTree(event, receivers); err != nil {
|
||||
return nil, fmt.Errorf("failed to verify congestion tree: %s", err)
|
||||
vtxos []client.Vtxo, mustSignRoundTx bool, receivers []client.Output,
|
||||
) (signedForfeits []string, signedRoundTx string, err error) {
|
||||
if err = a.validateCongestionTree(event, receivers); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return a.loopAndSign(
|
||||
ctx, event.ForfeitTxs, vtxos, event.Connectors,
|
||||
)
|
||||
if len(vtxos) > 0 {
|
||||
signedForfeits, err = a.loopAndSign(
|
||||
ctx, event.ForfeitTxs, vtxos, event.Connectors,
|
||||
)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if mustSignRoundTx {
|
||||
signedRoundTx, err = a.wallet.SignTransaction(ctx, a.explorer, event.Tx)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (a *covenantArkClient) validateCongestionTree(
|
||||
@@ -1197,23 +1143,49 @@ func (a *covenantArkClient) signForfeitTx(
|
||||
|
||||
func (a *covenantArkClient) coinSelectOnchain(
|
||||
ctx context.Context, targetAmount uint64, exclude []explorer.Utxo,
|
||||
) ([]explorer.Utxo, []explorer.Utxo, uint64, error) {
|
||||
offchainAddrs, onchainAddrs, _, err := a.wallet.GetAddresses(ctx)
|
||||
) ([]explorer.Utxo, uint64, error) {
|
||||
offchainAddrs, boardingAddrs, redemptionAddrs, err := a.wallet.GetAddresses(ctx)
|
||||
if err != nil {
|
||||
return nil, nil, 0, err
|
||||
return nil, 0, err
|
||||
}
|
||||
net := utils.ToElementsNetwork(a.Network)
|
||||
|
||||
_, myPubkey, _, err := common.DecodeAddress(offchainAddrs[0])
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
myPubkeyStr := hex.EncodeToString(schnorr.SerializePubKey(myPubkey))
|
||||
descriptorStr := strings.ReplaceAll(
|
||||
a.BoardingDescriptorTemplate, "USER", myPubkeyStr,
|
||||
)
|
||||
desc, err := descriptor.ParseTaprootDescriptor(descriptorStr)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
_, boardingTimeout, err := descriptor.ParseBoardingDescriptor(*desc)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
|
||||
fetchedUtxos := make([]explorer.Utxo, 0)
|
||||
for _, onchainAddr := range onchainAddrs {
|
||||
utxos, err := a.explorer.GetUtxos(onchainAddr)
|
||||
for _, addr := range boardingAddrs {
|
||||
utxos, err := a.explorer.GetUtxos(addr)
|
||||
if err != nil {
|
||||
return nil, nil, 0, err
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
for _, utxo := range utxos {
|
||||
u := utxo.ToUtxo(boardingTimeout)
|
||||
if u.SpendableAt.Before(now) {
|
||||
fetchedUtxos = append(fetchedUtxos, u)
|
||||
}
|
||||
}
|
||||
fetchedUtxos = append(fetchedUtxos, utxos...)
|
||||
}
|
||||
|
||||
utxos := make([]explorer.Utxo, 0)
|
||||
selected := make([]explorer.Utxo, 0)
|
||||
selectedAmount := uint64(0)
|
||||
for _, utxo := range fetchedUtxos {
|
||||
if selectedAmount >= targetAmount {
|
||||
@@ -1226,61 +1198,51 @@ func (a *covenantArkClient) coinSelectOnchain(
|
||||
}
|
||||
}
|
||||
|
||||
utxos = append(utxos, utxo)
|
||||
selected = append(selected, utxo)
|
||||
selectedAmount += utxo.Amount
|
||||
}
|
||||
|
||||
if selectedAmount >= targetAmount {
|
||||
return utxos, nil, selectedAmount - targetAmount, nil
|
||||
return selected, selectedAmount - targetAmount, nil
|
||||
}
|
||||
|
||||
fetchedUtxos = make([]explorer.Utxo, 0)
|
||||
for _, offchainAddr := range offchainAddrs {
|
||||
_, userPubkey, aspPubkey, _ := common.DecodeAddress(offchainAddr)
|
||||
_, _, _, addr, err := tree.ComputeVtxoTaprootScript(
|
||||
userPubkey, aspPubkey, uint(a.UnilateralExitDelay), net,
|
||||
)
|
||||
for _, addr := range redemptionAddrs {
|
||||
utxos, err := a.explorer.GetUtxos(addr)
|
||||
if err != nil {
|
||||
return nil, nil, 0, err
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
utxos, err = a.explorer.GetUtxos(addr)
|
||||
if err != nil {
|
||||
return nil, nil, 0, err
|
||||
for _, utxo := range utxos {
|
||||
u := utxo.ToUtxo(uint(a.UnilateralExitDelay))
|
||||
if u.SpendableAt.Before(now) {
|
||||
fetchedUtxos = append(fetchedUtxos, u)
|
||||
}
|
||||
}
|
||||
fetchedUtxos = append(fetchedUtxos, utxos...)
|
||||
}
|
||||
|
||||
delayedUtxos := make([]explorer.Utxo, 0)
|
||||
for _, utxo := range fetchedUtxos {
|
||||
if selectedAmount >= targetAmount {
|
||||
break
|
||||
}
|
||||
|
||||
availableAt := time.Unix(utxo.Status.Blocktime, 0).Add(
|
||||
time.Duration(a.UnilateralExitDelay) * time.Second,
|
||||
)
|
||||
if availableAt.After(time.Now()) {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, excluded := range exclude {
|
||||
if utxo.Txid == excluded.Txid && utxo.Vout == excluded.Vout {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
delayedUtxos = append(delayedUtxos, utxo)
|
||||
selected = append(selected, utxo)
|
||||
selectedAmount += utxo.Amount
|
||||
}
|
||||
|
||||
if selectedAmount < targetAmount {
|
||||
return nil, nil, 0, fmt.Errorf(
|
||||
return nil, 0, fmt.Errorf(
|
||||
"not enough funds to cover amount %d", targetAmount,
|
||||
)
|
||||
}
|
||||
|
||||
return utxos, delayedUtxos, selectedAmount - targetAmount, nil
|
||||
return selected, selectedAmount - targetAmount, nil
|
||||
}
|
||||
|
||||
func (a *covenantArkClient) getRedeemBranches(
|
||||
@@ -1373,3 +1335,39 @@ func (a *covenantArkClient) getVtxos(
|
||||
|
||||
return vtxos, nil
|
||||
}
|
||||
|
||||
func (a *covenantArkClient) selfTransferAllPendingPayments(
|
||||
ctx context.Context, boardingUtxo []explorer.Utxo, myself client.Output, boardingDescriptor string,
|
||||
) (string, error) {
|
||||
inputs := make([]client.Input, 0, len(boardingUtxo))
|
||||
|
||||
for _, utxo := range boardingUtxo {
|
||||
inputs = append(inputs, client.BoardingInput{
|
||||
VtxoKey: client.VtxoKey{
|
||||
Txid: utxo.Txid,
|
||||
VOut: utxo.Vout,
|
||||
},
|
||||
Descriptor: boardingDescriptor,
|
||||
})
|
||||
}
|
||||
|
||||
outputs := []client.Output{myself}
|
||||
|
||||
paymentID, err := a.client.RegisterPayment(ctx, inputs, "") // ephemeralPublicKey is not required for covenant
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if err := a.client.ClaimPayment(ctx, paymentID, outputs); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
roundTxid, err := a.handleRoundStream(
|
||||
ctx, paymentID, make([]client.Vtxo, 0), len(boardingUtxo) > 0, outputs,
|
||||
)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return roundTxid, nil
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
|
||||
"github.com/ark-network/ark/common"
|
||||
"github.com/ark-network/ark/common/bitcointree"
|
||||
"github.com/ark-network/ark/common/descriptor"
|
||||
"github.com/ark-network/ark/common/tree"
|
||||
"github.com/ark-network/ark/pkg/client-sdk/client"
|
||||
"github.com/ark-network/ark/pkg/client-sdk/explorer"
|
||||
@@ -22,7 +23,6 @@ import (
|
||||
"github.com/btcsuite/btcd/btcec/v2/schnorr"
|
||||
"github.com/btcsuite/btcd/btcutil"
|
||||
"github.com/btcsuite/btcd/btcutil/psbt"
|
||||
"github.com/btcsuite/btcd/chaincfg"
|
||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||
"github.com/btcsuite/btcd/txscript"
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
@@ -139,176 +139,24 @@ func LoadCovenantlessClientWithWallet(
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (a *covenantlessArkClient) Onboard(
|
||||
ctx context.Context, amount uint64,
|
||||
) (string, error) {
|
||||
if amount <= 0 {
|
||||
return "", fmt.Errorf("invalid amount to onboard %d", amount)
|
||||
}
|
||||
|
||||
offchainAddr, _, err := a.wallet.NewAddress(ctx, false)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
_, userPubkey, aspPubkey, _ := common.DecodeAddress(offchainAddr)
|
||||
userPubkeyStr := hex.EncodeToString(userPubkey.SerializeCompressed())
|
||||
|
||||
congestionTreeLeaf := bitcointree.Receiver{
|
||||
Pubkey: userPubkeyStr,
|
||||
Amount: amount,
|
||||
}
|
||||
|
||||
leaves := []bitcointree.Receiver{congestionTreeLeaf}
|
||||
|
||||
ephemeralKey, err := secp256k1.GeneratePrivateKey()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
cosigners := []*secp256k1.PublicKey{ephemeralKey.PubKey()} // TODO asp as cosigner
|
||||
|
||||
sharedOutputScript, sharedOutputAmount, err := bitcointree.CraftSharedOutput(
|
||||
cosigners,
|
||||
aspPubkey,
|
||||
leaves,
|
||||
a.MinRelayFee,
|
||||
a.RoundLifetime,
|
||||
a.UnilateralExitDelay,
|
||||
)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
netParams := utils.ToBitcoinNetwork(a.Network)
|
||||
|
||||
address, err := btcutil.NewAddressTaproot(sharedOutputScript[2:], &netParams)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
onchainReceiver := NewBitcoinReceiver(
|
||||
address.EncodeAddress(), uint64(sharedOutputAmount),
|
||||
)
|
||||
|
||||
partialTx, err := a.sendOnchain(ctx, []Receiver{onchainReceiver})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
ptx, err := psbt.NewFromRawBytes(strings.NewReader(partialTx), true)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
txid := ptx.UnsignedTx.TxHash().String()
|
||||
|
||||
congestionTree, err := bitcointree.CraftCongestionTree(
|
||||
&wire.OutPoint{
|
||||
Hash: ptx.UnsignedTx.TxHash(),
|
||||
Index: 0,
|
||||
},
|
||||
cosigners,
|
||||
aspPubkey,
|
||||
leaves,
|
||||
a.MinRelayFee,
|
||||
a.RoundLifetime,
|
||||
a.UnilateralExitDelay,
|
||||
)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
sweepClosure := bitcointree.CSVSigClosure{
|
||||
Pubkey: aspPubkey,
|
||||
Seconds: uint(a.RoundLifetime),
|
||||
}
|
||||
|
||||
sweepTapLeaf, err := sweepClosure.Leaf()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
sweepTapTree := txscript.AssembleTaprootScriptTree(*sweepTapLeaf)
|
||||
root := sweepTapTree.RootNode.TapHash()
|
||||
|
||||
signer := bitcointree.NewTreeSignerSession(
|
||||
ephemeralKey,
|
||||
congestionTree,
|
||||
int64(a.MinRelayFee),
|
||||
root.CloneBytes(),
|
||||
)
|
||||
|
||||
nonces, err := signer.GetNonces() // TODO send nonces to ASP
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
coordinator, err := bitcointree.NewTreeCoordinatorSession(
|
||||
congestionTree,
|
||||
int64(a.MinRelayFee),
|
||||
root.CloneBytes(),
|
||||
cosigners,
|
||||
)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if err := coordinator.AddNonce(ephemeralKey.PubKey(), nonces); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
aggregatedNonces, err := coordinator.AggregateNonces()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if err := signer.SetKeys(cosigners); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if err := signer.SetAggregatedNonces(aggregatedNonces); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
sigs, err := signer.Sign()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if err := coordinator.AddSig(ephemeralKey.PubKey(), sigs); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
signedTree, err := coordinator.SignTree()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if err := a.client.Onboard(
|
||||
ctx, partialTx, userPubkeyStr, signedTree,
|
||||
); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return txid, nil
|
||||
}
|
||||
|
||||
func (a *covenantlessArkClient) Balance(
|
||||
ctx context.Context, computeVtxoExpiration bool,
|
||||
) (*Balance, error) {
|
||||
offchainAddrs, onchainAddrs, redeemAddrs, err := a.wallet.GetAddresses(ctx)
|
||||
offchainAddrs, boardingAddrs, redeemAddrs, err := a.wallet.GetAddresses(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
const nbWorkers = 3
|
||||
wg := &sync.WaitGroup{}
|
||||
wg.Add(3 * len(offchainAddrs))
|
||||
wg.Add(nbWorkers * len(offchainAddrs))
|
||||
|
||||
chRes := make(chan balanceRes, 3)
|
||||
chRes := make(chan balanceRes, nbWorkers*len(offchainAddrs))
|
||||
for i := range offchainAddrs {
|
||||
offchainAddr := offchainAddrs[i]
|
||||
onchainAddr := onchainAddrs[i]
|
||||
boardingAddr := boardingAddrs[i]
|
||||
redeemAddr := redeemAddrs[i]
|
||||
|
||||
go func(addr string) {
|
||||
defer wg.Done()
|
||||
balance, amountByExpiration, err := a.getOffchainBalance(
|
||||
@@ -325,17 +173,7 @@ func (a *covenantlessArkClient) Balance(
|
||||
}
|
||||
}(offchainAddr)
|
||||
|
||||
go func(addr string) {
|
||||
defer wg.Done()
|
||||
balance, err := a.explorer.GetBalance(addr)
|
||||
if err != nil {
|
||||
chRes <- balanceRes{err: err}
|
||||
return
|
||||
}
|
||||
chRes <- balanceRes{onchainSpendableBalance: balance}
|
||||
}(onchainAddr)
|
||||
|
||||
go func(addr string) {
|
||||
getDelayedBalance := func(addr string) {
|
||||
defer wg.Done()
|
||||
|
||||
spendableBalance, lockedBalance, err := a.explorer.GetRedeemedVtxosBalance(
|
||||
@@ -351,7 +189,10 @@ func (a *covenantlessArkClient) Balance(
|
||||
onchainLockedBalance: lockedBalance,
|
||||
err: err,
|
||||
}
|
||||
}(redeemAddr)
|
||||
}
|
||||
|
||||
go getDelayedBalance(boardingAddr)
|
||||
go getDelayedBalance(redeemAddr)
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
@@ -401,7 +242,7 @@ func (a *covenantlessArkClient) Balance(
|
||||
}
|
||||
|
||||
count++
|
||||
if count == 3 {
|
||||
if count == nbWorkers {
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -603,7 +444,7 @@ func (a *covenantlessArkClient) CollaborativeRedeem(
|
||||
})
|
||||
}
|
||||
|
||||
inputs := make([]client.VtxoKey, 0, len(selectedCoins))
|
||||
inputs := make([]client.Input, 0, len(selectedCoins))
|
||||
|
||||
for _, coin := range selectedCoins {
|
||||
inputs = append(inputs, client.VtxoKey{
|
||||
@@ -631,7 +472,7 @@ func (a *covenantlessArkClient) CollaborativeRedeem(
|
||||
}
|
||||
|
||||
poolTxID, err := a.handleRoundStream(
|
||||
ctx, paymentID, selectedCoins, receivers, roundEphemeralKey,
|
||||
ctx, paymentID, selectedCoins, false, receivers, roundEphemeralKey,
|
||||
)
|
||||
if err != nil {
|
||||
return "", err
|
||||
@@ -751,9 +592,7 @@ func (a *covenantlessArkClient) SendAsync(
|
||||
return signedRedeemTx, nil
|
||||
}
|
||||
|
||||
func (a *covenantlessArkClient) ClaimAsync(
|
||||
ctx context.Context,
|
||||
) (string, error) {
|
||||
func (a *covenantlessArkClient) Claim(ctx context.Context) (string, error) {
|
||||
myselfOffchain, _, err := a.wallet.NewAddress(ctx, false)
|
||||
if err != nil {
|
||||
return "", err
|
||||
@@ -764,10 +603,23 @@ func (a *covenantlessArkClient) ClaimAsync(
|
||||
return "", err
|
||||
}
|
||||
|
||||
_, mypubkey, _, err := common.DecodeAddress(myselfOffchain)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
boardingUtxos, err := a.getClaimableBoardingUtxos(ctx)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
var pendingBalance uint64
|
||||
for _, vtxo := range pendingVtxos {
|
||||
pendingBalance += vtxo.Amount
|
||||
}
|
||||
for _, vtxo := range boardingUtxos {
|
||||
pendingBalance += vtxo.Amount
|
||||
}
|
||||
if pendingBalance == 0 {
|
||||
return "", nil
|
||||
}
|
||||
@@ -776,7 +628,9 @@ func (a *covenantlessArkClient) ClaimAsync(
|
||||
Address: myselfOffchain,
|
||||
Amount: pendingBalance,
|
||||
}
|
||||
return a.selfTransferAllPendingPayments(ctx, pendingVtxos, receiver)
|
||||
|
||||
desc := strings.ReplaceAll(a.BoardingDescriptorTemplate, "USER", hex.EncodeToString(schnorr.SerializePubKey(mypubkey)))
|
||||
return a.selfTransferAllPendingPayments(ctx, pendingVtxos, boardingUtxos, receiver, desc)
|
||||
}
|
||||
|
||||
func (a *covenantlessArkClient) sendOnchain(
|
||||
@@ -822,14 +676,14 @@ func (a *covenantlessArkClient) sendOnchain(
|
||||
updater.Upsbt.Outputs = append(updater.Upsbt.Outputs, psbt.POutput{})
|
||||
}
|
||||
|
||||
utxos, delayedUtxos, change, err := a.coinSelectOnchain(
|
||||
utxos, change, err := a.coinSelectOnchain(
|
||||
ctx, targetAmount, nil,
|
||||
)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if err := a.addInputs(ctx, updater, utxos, delayedUtxos, &netParams); err != nil {
|
||||
if err := a.addInputs(ctx, updater, utxos); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
@@ -869,14 +723,14 @@ func (a *covenantlessArkClient) sendOnchain(
|
||||
updater.Upsbt.UnsignedTx.TxOut = updater.Upsbt.UnsignedTx.TxOut[:len(updater.Upsbt.UnsignedTx.TxOut)-1]
|
||||
}
|
||||
// reselect the difference
|
||||
selected, delayedSelected, newChange, err := a.coinSelectOnchain(
|
||||
ctx, feeAmount-change, append(utxos, delayedUtxos...),
|
||||
selected, newChange, err := a.coinSelectOnchain(
|
||||
ctx, feeAmount-change, utxos,
|
||||
)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if err := a.addInputs(ctx, updater, selected, delayedSelected, &netParams); err != nil {
|
||||
if err := a.addInputs(ctx, updater, selected); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
@@ -995,7 +849,7 @@ func (a *covenantlessArkClient) sendOffchain(
|
||||
receiversOutput = append(receiversOutput, changeReceiver)
|
||||
}
|
||||
|
||||
inputs := make([]client.VtxoKey, 0, len(selectedCoins))
|
||||
inputs := make([]client.Input, 0, len(selectedCoins))
|
||||
for _, coin := range selectedCoins {
|
||||
inputs = append(inputs, client.VtxoKey{
|
||||
Txid: coin.Txid,
|
||||
@@ -1024,7 +878,7 @@ func (a *covenantlessArkClient) sendOffchain(
|
||||
log.Infof("payment registered with id: %s", paymentID)
|
||||
|
||||
poolTxID, err := a.handleRoundStream(
|
||||
ctx, paymentID, selectedCoins, receiversOutput, roundEphemeralKey,
|
||||
ctx, paymentID, selectedCoins, false, receiversOutput, roundEphemeralKey,
|
||||
)
|
||||
if err != nil {
|
||||
return "", err
|
||||
@@ -1034,16 +888,17 @@ func (a *covenantlessArkClient) sendOffchain(
|
||||
}
|
||||
|
||||
func (a *covenantlessArkClient) addInputs(
|
||||
ctx context.Context, updater *psbt.Updater,
|
||||
utxos, delayedUtxos []explorer.Utxo, net *chaincfg.Params,
|
||||
ctx context.Context,
|
||||
updater *psbt.Updater,
|
||||
utxos []explorer.Utxo,
|
||||
) error {
|
||||
offchainAddr, onchainAddr, err := a.wallet.NewAddress(ctx, false)
|
||||
// TODO works only with single-key wallet
|
||||
offchain, _, err := a.wallet.NewAddress(ctx, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
addr, _ := btcutil.DecodeAddress(onchainAddr, net)
|
||||
|
||||
changeScript, err := txscript.PayToAddrScript(addr)
|
||||
_, userPubkey, aspPubkey, err := common.DecodeAddress(offchain)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1054,107 +909,41 @@ func (a *covenantlessArkClient) addInputs(
|
||||
return err
|
||||
}
|
||||
|
||||
sequence, err := utxo.Sequence()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
updater.Upsbt.UnsignedTx.AddTxIn(&wire.TxIn{
|
||||
PreviousOutPoint: wire.OutPoint{
|
||||
Hash: *previousHash,
|
||||
Index: utxo.Vout,
|
||||
},
|
||||
Sequence: sequence,
|
||||
})
|
||||
|
||||
updater.Upsbt.Inputs = append(updater.Upsbt.Inputs, psbt.PInput{})
|
||||
|
||||
if err := updater.AddInWitnessUtxo(
|
||||
&wire.TxOut{
|
||||
Value: int64(utxo.Amount),
|
||||
PkScript: changeScript,
|
||||
},
|
||||
len(updater.Upsbt.UnsignedTx.TxIn)-1,
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if len(delayedUtxos) > 0 {
|
||||
_, userPubkey, aspPubkey, _ := common.DecodeAddress(offchainAddr)
|
||||
|
||||
vtxoTapKey, leafProof, err := bitcointree.ComputeVtxoTaprootScript(
|
||||
userPubkey, aspPubkey, uint(a.UnilateralExitDelay),
|
||||
_, leafProof, err := bitcointree.ComputeVtxoTaprootScript(
|
||||
userPubkey, aspPubkey, utxo.Delay,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
p2tr, err := btcutil.NewAddressTaproot(schnorr.SerializePubKey(vtxoTapKey), net)
|
||||
controlBlock := leafProof.ToControlBlock(bitcointree.UnspendableKey())
|
||||
controlBlockBytes, err := controlBlock.ToBytes()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
script, err := txscript.PayToAddrScript(p2tr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, utxo := range delayedUtxos {
|
||||
previousHash, err := chainhash.NewHashFromStr(utxo.Txid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := a.addVtxoInput(
|
||||
updater,
|
||||
&wire.OutPoint{
|
||||
Hash: *previousHash,
|
||||
Index: utxo.Vout,
|
||||
updater.Upsbt.Inputs = append(updater.Upsbt.Inputs, psbt.PInput{
|
||||
TaprootLeafScript: []*psbt.TaprootTapLeafScript{
|
||||
{
|
||||
ControlBlock: controlBlockBytes,
|
||||
Script: leafProof.Script,
|
||||
LeafVersion: leafProof.LeafVersion,
|
||||
},
|
||||
uint(a.UnilateralExitDelay),
|
||||
leafProof,
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := updater.AddInWitnessUtxo(
|
||||
&wire.TxOut{
|
||||
Value: int64(utxo.Amount),
|
||||
PkScript: script,
|
||||
},
|
||||
len(updater.Upsbt.Inputs)-1,
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *covenantlessArkClient) addVtxoInput(
|
||||
updater *psbt.Updater, inputArgs *wire.OutPoint, exitDelay uint,
|
||||
tapLeafProof *txscript.TapscriptProof,
|
||||
) error {
|
||||
sequence, err := common.BIP68EncodeAsNumber(exitDelay)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
nextInputIndex := len(updater.Upsbt.Inputs)
|
||||
updater.Upsbt.UnsignedTx.AddTxIn(&wire.TxIn{
|
||||
PreviousOutPoint: *inputArgs,
|
||||
Sequence: sequence,
|
||||
})
|
||||
updater.Upsbt.Inputs = append(updater.Upsbt.Inputs, psbt.PInput{})
|
||||
|
||||
controlBlock := tapLeafProof.ToControlBlock(bitcointree.UnspendableKey())
|
||||
controlBlockBytes, err := controlBlock.ToBytes()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
updater.Upsbt.Inputs[nextInputIndex].TaprootLeafScript = []*psbt.TaprootTapLeafScript{
|
||||
{
|
||||
ControlBlock: controlBlockBytes,
|
||||
Script: tapLeafProof.Script,
|
||||
LeafVersion: tapLeafProof.LeafVersion,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -1164,6 +953,7 @@ func (a *covenantlessArkClient) handleRoundStream(
|
||||
ctx context.Context,
|
||||
paymentID string,
|
||||
vtxosToSign []client.Vtxo,
|
||||
mustSignRoundTx bool,
|
||||
receivers []client.Output,
|
||||
roundEphemeralKey *secp256k1.PrivateKey,
|
||||
) (string, error) {
|
||||
@@ -1218,20 +1008,20 @@ func (a *covenantlessArkClient) handleRoundStream(
|
||||
pingStop()
|
||||
log.Info("a round finalization started")
|
||||
|
||||
signedForfeitTxs, err := a.handleRoundFinalization(
|
||||
ctx, event.(client.RoundFinalizationEvent), vtxosToSign, receivers,
|
||||
signedForfeitTxs, signedRoundTx, err := a.handleRoundFinalization(
|
||||
ctx, event.(client.RoundFinalizationEvent), vtxosToSign, mustSignRoundTx, receivers,
|
||||
)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if len(signedForfeitTxs) <= 0 {
|
||||
if len(signedForfeitTxs) <= 0 && len(vtxosToSign) > 0 {
|
||||
log.Info("no forfeit txs to sign, waiting for the next round")
|
||||
continue
|
||||
}
|
||||
|
||||
log.Info("finalizing payment... ")
|
||||
if err := a.client.FinalizePayment(ctx, signedForfeitTxs); err != nil {
|
||||
if err := a.client.FinalizePayment(ctx, signedForfeitTxs, signedRoundTx); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
@@ -1311,15 +1101,29 @@ func (a *covenantlessArkClient) handleRoundSigningNoncesGenerated(
|
||||
|
||||
func (a *covenantlessArkClient) handleRoundFinalization(
|
||||
ctx context.Context, event client.RoundFinalizationEvent,
|
||||
vtxos []client.Vtxo, receivers []client.Output,
|
||||
) ([]string, error) {
|
||||
vtxos []client.Vtxo, mustSignRoundTx bool, receivers []client.Output,
|
||||
) (signedForfeits []string, signedRoundTx string, err error) {
|
||||
if err := a.validateCongestionTree(event, receivers); err != nil {
|
||||
return nil, fmt.Errorf("failed to verify congestion tree: %s", err)
|
||||
return nil, "", fmt.Errorf("failed to verify congestion tree: %s", err)
|
||||
}
|
||||
|
||||
return a.loopAndSign(
|
||||
ctx, event.ForfeitTxs, vtxos, event.Connectors,
|
||||
)
|
||||
if len(vtxos) > 0 {
|
||||
signedForfeits, err = a.loopAndSign(
|
||||
ctx, event.ForfeitTxs, vtxos, event.Connectors,
|
||||
)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if mustSignRoundTx {
|
||||
signedRoundTx, err = a.wallet.SignTransaction(ctx, a.explorer, event.Tx)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (a *covenantlessArkClient) validateCongestionTree(
|
||||
@@ -1516,24 +1320,49 @@ func (a *covenantlessArkClient) loopAndSign(
|
||||
|
||||
func (a *covenantlessArkClient) coinSelectOnchain(
|
||||
ctx context.Context, targetAmount uint64, exclude []explorer.Utxo,
|
||||
) ([]explorer.Utxo, []explorer.Utxo, uint64, error) {
|
||||
offchainAddrs, onchainAddrs, _, err := a.wallet.GetAddresses(ctx)
|
||||
) ([]explorer.Utxo, uint64, error) {
|
||||
offchainAddrs, boardingAddrs, redemptionAddrs, err := a.wallet.GetAddresses(ctx)
|
||||
if err != nil {
|
||||
return nil, nil, 0, err
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
net := utils.ToBitcoinNetwork(a.Network)
|
||||
_, myPubkey, _, err := common.DecodeAddress(offchainAddrs[0])
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
myPubkeyStr := hex.EncodeToString(schnorr.SerializePubKey(myPubkey))
|
||||
descriptorStr := strings.ReplaceAll(
|
||||
a.BoardingDescriptorTemplate, "USER", myPubkeyStr,
|
||||
)
|
||||
desc, err := descriptor.ParseTaprootDescriptor(descriptorStr)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
_, boardingTimeout, err := descriptor.ParseBoardingDescriptor(*desc)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
|
||||
fetchedUtxos := make([]explorer.Utxo, 0)
|
||||
for _, onchainAddr := range onchainAddrs {
|
||||
utxos, err := a.explorer.GetUtxos(onchainAddr)
|
||||
for _, addr := range boardingAddrs {
|
||||
utxos, err := a.explorer.GetUtxos(addr)
|
||||
if err != nil {
|
||||
return nil, nil, 0, err
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
for _, utxo := range utxos {
|
||||
u := utxo.ToUtxo(boardingTimeout)
|
||||
if u.SpendableAt.Before(now) {
|
||||
fetchedUtxos = append(fetchedUtxos, u)
|
||||
}
|
||||
}
|
||||
fetchedUtxos = append(fetchedUtxos, utxos...)
|
||||
}
|
||||
|
||||
utxos := make([]explorer.Utxo, 0)
|
||||
selected := make([]explorer.Utxo, 0)
|
||||
selectedAmount := uint64(0)
|
||||
for _, utxo := range fetchedUtxos {
|
||||
if selectedAmount >= targetAmount {
|
||||
@@ -1546,70 +1375,51 @@ func (a *covenantlessArkClient) coinSelectOnchain(
|
||||
}
|
||||
}
|
||||
|
||||
utxos = append(utxos, utxo)
|
||||
selected = append(selected, utxo)
|
||||
selectedAmount += utxo.Amount
|
||||
}
|
||||
|
||||
if selectedAmount >= targetAmount {
|
||||
return utxos, nil, selectedAmount - targetAmount, nil
|
||||
return selected, selectedAmount - targetAmount, nil
|
||||
}
|
||||
|
||||
fetchedUtxos = make([]explorer.Utxo, 0)
|
||||
for _, offchainAddr := range offchainAddrs {
|
||||
_, userPubkey, aspPubkey, _ := common.DecodeAddress(offchainAddr)
|
||||
|
||||
vtxoTapKey, _, err := bitcointree.ComputeVtxoTaprootScript(
|
||||
userPubkey, aspPubkey, uint(a.UnilateralExitDelay),
|
||||
)
|
||||
for _, addr := range redemptionAddrs {
|
||||
utxos, err := a.explorer.GetUtxos(addr)
|
||||
if err != nil {
|
||||
return nil, nil, 0, err
|
||||
}
|
||||
p2tr, err := btcutil.NewAddressTaproot(
|
||||
schnorr.SerializePubKey(vtxoTapKey), &net,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, nil, 0, err
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
addr := p2tr.EncodeAddress()
|
||||
|
||||
utxos, err = a.explorer.GetUtxos(addr)
|
||||
if err != nil {
|
||||
return nil, nil, 0, err
|
||||
for _, utxo := range utxos {
|
||||
u := utxo.ToUtxo(uint(a.UnilateralExitDelay))
|
||||
if u.SpendableAt.Before(now) {
|
||||
fetchedUtxos = append(fetchedUtxos, u)
|
||||
}
|
||||
}
|
||||
fetchedUtxos = append(fetchedUtxos, utxos...)
|
||||
}
|
||||
|
||||
delayedUtxos := make([]explorer.Utxo, 0)
|
||||
for _, utxo := range fetchedUtxos {
|
||||
if selectedAmount >= targetAmount {
|
||||
break
|
||||
}
|
||||
|
||||
availableAt := time.Unix(utxo.Status.Blocktime, 0).Add(
|
||||
time.Duration(a.UnilateralExitDelay) * time.Second,
|
||||
)
|
||||
if availableAt.After(time.Now()) {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, excluded := range exclude {
|
||||
if utxo.Txid == excluded.Txid && utxo.Vout == excluded.Vout {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
delayedUtxos = append(delayedUtxos, utxo)
|
||||
selected = append(selected, utxo)
|
||||
selectedAmount += utxo.Amount
|
||||
}
|
||||
|
||||
if selectedAmount < targetAmount {
|
||||
return nil, nil, 0, fmt.Errorf(
|
||||
return nil, 0, fmt.Errorf(
|
||||
"not enough funds to cover amount %d", targetAmount,
|
||||
)
|
||||
}
|
||||
|
||||
return utxos, delayedUtxos, selectedAmount - targetAmount, nil
|
||||
return selected, selectedAmount - targetAmount, nil
|
||||
}
|
||||
|
||||
func (a *covenantlessArkClient) getRedeemBranches(
|
||||
@@ -1673,6 +1483,53 @@ func (a *covenantlessArkClient) getOffchainBalance(
|
||||
return balance, amountByExpiration, nil
|
||||
}
|
||||
|
||||
func (a *covenantlessArkClient) getClaimableBoardingUtxos(ctx context.Context) ([]explorer.Utxo, error) {
|
||||
offchainAddrs, boardingAddrs, _, err := a.wallet.GetAddresses(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_, myPubkey, _, err := common.DecodeAddress(offchainAddrs[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
myPubkeyStr := hex.EncodeToString(schnorr.SerializePubKey(myPubkey))
|
||||
descriptorStr := strings.ReplaceAll(
|
||||
a.BoardingDescriptorTemplate, "USER", myPubkeyStr,
|
||||
)
|
||||
desc, err := descriptor.ParseTaprootDescriptor(descriptorStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_, boardingTimeout, err := descriptor.ParseBoardingDescriptor(*desc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
claimable := make([]explorer.Utxo, 0)
|
||||
now := time.Now()
|
||||
|
||||
for _, addr := range boardingAddrs {
|
||||
boardingUtxos, err := a.explorer.GetUtxos(addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, utxo := range boardingUtxos {
|
||||
u := utxo.ToUtxo(boardingTimeout)
|
||||
if u.SpendableAt.Before(now) {
|
||||
continue
|
||||
}
|
||||
claimable = append(claimable, u)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return claimable, nil
|
||||
}
|
||||
|
||||
func (a *covenantlessArkClient) getVtxos(
|
||||
ctx context.Context, addr string, computeVtxoExpiration bool,
|
||||
) ([]client.Vtxo, []client.Vtxo, error) {
|
||||
@@ -1718,14 +1575,25 @@ func (a *covenantlessArkClient) getVtxos(
|
||||
}
|
||||
|
||||
func (a *covenantlessArkClient) selfTransferAllPendingPayments(
|
||||
ctx context.Context, pendingVtxos []client.Vtxo, myself client.Output,
|
||||
ctx context.Context, pendingVtxos []client.Vtxo, boardingUtxo []explorer.Utxo, myself client.Output, boardingDescriptor string,
|
||||
) (string, error) {
|
||||
inputs := make([]client.VtxoKey, 0, len(pendingVtxos))
|
||||
inputs := make([]client.Input, 0, len(pendingVtxos)+len(boardingUtxo))
|
||||
|
||||
for _, coin := range pendingVtxos {
|
||||
inputs = append(inputs, coin.VtxoKey)
|
||||
}
|
||||
|
||||
for _, utxo := range boardingUtxo {
|
||||
fmt.Println(utxo)
|
||||
fmt.Println(boardingDescriptor)
|
||||
inputs = append(inputs, client.BoardingInput{
|
||||
VtxoKey: client.VtxoKey{
|
||||
Txid: utxo.Txid,
|
||||
VOut: utxo.Vout,
|
||||
},
|
||||
Descriptor: boardingDescriptor,
|
||||
})
|
||||
}
|
||||
outputs := []client.Output{myself}
|
||||
|
||||
roundEphemeralKey, err := secp256k1.GeneratePrivateKey()
|
||||
@@ -1747,7 +1615,7 @@ func (a *covenantlessArkClient) selfTransferAllPendingPayments(
|
||||
}
|
||||
|
||||
roundTxid, err := a.handleRoundStream(
|
||||
ctx, paymentID, pendingVtxos, outputs, roundEphemeralKey,
|
||||
ctx, paymentID, pendingVtxos, len(boardingUtxo) > 0, outputs, roundEphemeralKey,
|
||||
)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
||||
@@ -38,31 +38,27 @@ func main() {
|
||||
defer aliceArkClient.Lock(ctx, password)
|
||||
|
||||
log.Info("alice is acquiring onchain funds...")
|
||||
_, aliceOnchainAddr, err := aliceArkClient.Receive(ctx)
|
||||
_, aliceBoardingAddr, err := aliceArkClient.Receive(ctx)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if _, err := runCommand("nigiri", "faucet", "--liquid", aliceOnchainAddr); err != nil {
|
||||
if _, err := runCommand("nigiri", "faucet", "--liquid", aliceBoardingAddr); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
time.Sleep(5 * time.Second)
|
||||
|
||||
onboardAmount := uint64(20000)
|
||||
onboardAmount := uint64(1_0000_0000) // 1 BTC
|
||||
log.Infof("alice is onboarding with %d sats offchain...", onboardAmount)
|
||||
txid, err := aliceArkClient.Onboard(ctx, onboardAmount)
|
||||
|
||||
log.Infof("alice claiming onboarding funds...")
|
||||
txid, err := aliceArkClient.Claim(ctx)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if err := generateBlock(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
time.Sleep(5 * time.Second)
|
||||
|
||||
log.Infof("alice onboarded with tx: %s", txid)
|
||||
log.Infof("onboarding completed in round tx: %s", txid)
|
||||
|
||||
aliceBalance, err := aliceArkClient.Balance(ctx, false)
|
||||
if err != nil {
|
||||
|
||||
@@ -38,31 +38,19 @@ func main() {
|
||||
defer aliceArkClient.Lock(ctx, password)
|
||||
|
||||
log.Info("alice is acquiring onchain funds...")
|
||||
_, aliceOnchainAddr, err := aliceArkClient.Receive(ctx)
|
||||
_, boardingAddress, err := aliceArkClient.Receive(ctx)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if _, err := runCommand("nigiri", "faucet", aliceOnchainAddr); err != nil {
|
||||
if _, err := runCommand("nigiri", "faucet", boardingAddress); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
time.Sleep(5 * time.Second)
|
||||
|
||||
onboardAmount := uint64(20000)
|
||||
onboardAmount := uint64(1_0000_0000) // 1 BTC
|
||||
log.Infof("alice is onboarding with %d sats offchain...", onboardAmount)
|
||||
txid, err := aliceArkClient.Onboard(ctx, onboardAmount)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if err := generateBlock(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
time.Sleep(5 * time.Second)
|
||||
|
||||
log.Infof("alice onboarded with tx: %s", txid)
|
||||
|
||||
aliceBalance, err := aliceArkClient.Balance(ctx, false)
|
||||
if err != nil {
|
||||
@@ -72,6 +60,14 @@ func main() {
|
||||
log.Infof("alice onchain balance: %d", aliceBalance.OnchainBalance.SpendableAmount)
|
||||
log.Infof("alice offchain balance: %d", aliceBalance.OffchainBalance.Total)
|
||||
|
||||
log.Infof("alice claiming onboarding funds...")
|
||||
txid, err := aliceArkClient.Claim(ctx)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
log.Infof("alice claimed onboarding funds in round %s", txid)
|
||||
|
||||
fmt.Println("")
|
||||
log.Info("bob is setting up his ark wallet...")
|
||||
bobArkClient, err := setupArkClient()
|
||||
@@ -137,7 +133,7 @@ func main() {
|
||||
|
||||
fmt.Println("")
|
||||
log.Info("bob is claiming the incoming payment...")
|
||||
roundTxid, err := bobArkClient.ClaimAsync(ctx)
|
||||
roundTxid, err := bobArkClient.Claim(ctx)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -25,6 +25,35 @@ const (
|
||||
)
|
||||
|
||||
type Utxo struct {
|
||||
Txid string
|
||||
Vout uint32
|
||||
Amount uint64
|
||||
Asset string // liquid only
|
||||
Delay uint
|
||||
SpendableAt time.Time
|
||||
}
|
||||
|
||||
func (u *Utxo) Sequence() (uint32, error) {
|
||||
return common.BIP68EncodeAsNumber(u.Delay)
|
||||
}
|
||||
|
||||
func newUtxo(explorerUtxo ExplorerUtxo, delay uint) Utxo {
|
||||
utxoTime := explorerUtxo.Status.Blocktime
|
||||
if utxoTime == 0 {
|
||||
utxoTime = time.Now().Unix()
|
||||
}
|
||||
|
||||
return Utxo{
|
||||
Txid: explorerUtxo.Txid,
|
||||
Vout: explorerUtxo.Vout,
|
||||
Amount: explorerUtxo.Amount,
|
||||
Asset: explorerUtxo.Asset,
|
||||
Delay: delay,
|
||||
SpendableAt: time.Unix(utxoTime, 0).Add(time.Duration(delay) * time.Second),
|
||||
}
|
||||
}
|
||||
|
||||
type ExplorerUtxo struct {
|
||||
Txid string `json:"txid"`
|
||||
Vout uint32 `json:"vout"`
|
||||
Amount uint64 `json:"value"`
|
||||
@@ -35,10 +64,14 @@ type Utxo struct {
|
||||
} `json:"status"`
|
||||
}
|
||||
|
||||
func (e ExplorerUtxo) ToUtxo(delay uint) Utxo {
|
||||
return newUtxo(e, delay)
|
||||
}
|
||||
|
||||
type Explorer interface {
|
||||
GetTxHex(txid string) (string, error)
|
||||
Broadcast(txHex string) (string, error)
|
||||
GetUtxos(addr string) ([]Utxo, error)
|
||||
GetUtxos(addr string) ([]ExplorerUtxo, error)
|
||||
GetBalance(addr string) (uint64, error)
|
||||
GetRedeemedVtxosBalance(
|
||||
addr string, unilateralExitDelay int64,
|
||||
@@ -143,7 +176,7 @@ func (e *explorerSvc) Broadcast(txStr string) (string, error) {
|
||||
return txid, nil
|
||||
}
|
||||
|
||||
func (e *explorerSvc) GetUtxos(addr string) ([]Utxo, error) {
|
||||
func (e *explorerSvc) GetUtxos(addr string) ([]ExplorerUtxo, error) {
|
||||
resp, err := http.Get(fmt.Sprintf("%s/address/%s/utxo", e.baseUrl, addr))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -157,7 +190,7 @@ func (e *explorerSvc) GetUtxos(addr string) ([]Utxo, error) {
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf(string(body))
|
||||
}
|
||||
payload := []Utxo{}
|
||||
payload := []ExplorerUtxo{}
|
||||
if err := json.Unmarshal(body, &payload); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@ module github.com/ark-network/ark/pkg/client-sdk
|
||||
|
||||
go 1.22.6
|
||||
|
||||
replace github.com/ark-network/ark/common => ../../common
|
||||
|
||||
require (
|
||||
github.com/ark-network/ark/api-spec v0.0.0-20240815203029-edc4534dfc87
|
||||
github.com/ark-network/ark/common v0.0.0-20240815203029-edc4534dfc87
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
|
||||
github.com/ark-network/ark/api-spec v0.0.0-20240815203029-edc4534dfc87 h1:VBY4KqHqxE4q6NnmvEZTLvLZoNA0Q6NhMhjBs1hzy9Y=
|
||||
github.com/ark-network/ark/api-spec v0.0.0-20240815203029-edc4534dfc87/go.mod h1:m5H86Dx+k8cQjLXeYL1MV+h3x/XnhJCXJP/PL3KgZqY=
|
||||
github.com/ark-network/ark/common v0.0.0-20240815203029-edc4534dfc87 h1:TIv00zlpxLKmY2LjFAIMF8RxNtn9rFqQsv73Lwoj2ds=
|
||||
github.com/ark-network/ark/common v0.0.0-20240815203029-edc4534dfc87/go.mod h1:aYAGDfoeBLofnZt9n85wusFyCkrS7hvwdo5TynBlkuY=
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
||||
github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
|
||||
|
||||
@@ -21,14 +21,15 @@ const (
|
||||
)
|
||||
|
||||
type storeData struct {
|
||||
AspUrl string `json:"asp_url"`
|
||||
AspPubkey string `json:"asp_pubkey"`
|
||||
WalletType string `json:"wallet_type"`
|
||||
ClientType string `json:"client_type"`
|
||||
Network string `json:"network"`
|
||||
RoundLifetime string `json:"round_lifetime"`
|
||||
UnilateralExitDelay string `json:"unilateral_exit_delay"`
|
||||
MinRelayFee string `json:"min_relay_fee"`
|
||||
AspUrl string `json:"asp_url"`
|
||||
AspPubkey string `json:"asp_pubkey"`
|
||||
WalletType string `json:"wallet_type"`
|
||||
ClientType string `json:"client_type"`
|
||||
Network string `json:"network"`
|
||||
RoundLifetime string `json:"round_lifetime"`
|
||||
UnilateralExitDelay string `json:"unilateral_exit_delay"`
|
||||
MinRelayFee string `json:"min_relay_fee"`
|
||||
BoardingDescriptorTemplate string `json:"boarding_descriptor_template"`
|
||||
}
|
||||
|
||||
func (d storeData) isEmpty() bool {
|
||||
@@ -43,27 +44,29 @@ func (d storeData) decode() store.StoreData {
|
||||
buf, _ := hex.DecodeString(d.AspPubkey)
|
||||
aspPubkey, _ := secp256k1.ParsePubKey(buf)
|
||||
return store.StoreData{
|
||||
AspUrl: d.AspUrl,
|
||||
AspPubkey: aspPubkey,
|
||||
WalletType: d.WalletType,
|
||||
ClientType: d.ClientType,
|
||||
Network: network,
|
||||
RoundLifetime: int64(roundLifetime),
|
||||
UnilateralExitDelay: int64(unilateralExitDelay),
|
||||
MinRelayFee: uint64(minRelayFee),
|
||||
AspUrl: d.AspUrl,
|
||||
AspPubkey: aspPubkey,
|
||||
WalletType: d.WalletType,
|
||||
ClientType: d.ClientType,
|
||||
Network: network,
|
||||
RoundLifetime: int64(roundLifetime),
|
||||
UnilateralExitDelay: int64(unilateralExitDelay),
|
||||
MinRelayFee: uint64(minRelayFee),
|
||||
BoardingDescriptorTemplate: d.BoardingDescriptorTemplate,
|
||||
}
|
||||
}
|
||||
|
||||
func (d storeData) asMap() map[string]string {
|
||||
return map[string]string{
|
||||
"asp_url": d.AspUrl,
|
||||
"asp_pubkey": d.AspPubkey,
|
||||
"wallet_type": d.WalletType,
|
||||
"client_type": d.ClientType,
|
||||
"network": d.Network,
|
||||
"round_lifetime": d.RoundLifetime,
|
||||
"unilateral_exit_delay": d.UnilateralExitDelay,
|
||||
"min_relay_fee": d.MinRelayFee,
|
||||
"asp_url": d.AspUrl,
|
||||
"asp_pubkey": d.AspPubkey,
|
||||
"wallet_type": d.WalletType,
|
||||
"client_type": d.ClientType,
|
||||
"network": d.Network,
|
||||
"round_lifetime": d.RoundLifetime,
|
||||
"unilateral_exit_delay": d.UnilateralExitDelay,
|
||||
"min_relay_fee": d.MinRelayFee,
|
||||
"boarding_descriptor_template": d.BoardingDescriptorTemplate,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,14 +103,15 @@ func (s *Store) GetDatadir() string {
|
||||
|
||||
func (s *Store) AddData(ctx context.Context, data store.StoreData) error {
|
||||
sd := &storeData{
|
||||
AspUrl: data.AspUrl,
|
||||
AspPubkey: hex.EncodeToString(data.AspPubkey.SerializeCompressed()),
|
||||
WalletType: data.WalletType,
|
||||
ClientType: data.ClientType,
|
||||
Network: data.Network.Name,
|
||||
RoundLifetime: fmt.Sprintf("%d", data.RoundLifetime),
|
||||
UnilateralExitDelay: fmt.Sprintf("%d", data.UnilateralExitDelay),
|
||||
MinRelayFee: fmt.Sprintf("%d", data.MinRelayFee),
|
||||
AspUrl: data.AspUrl,
|
||||
AspPubkey: hex.EncodeToString(data.AspPubkey.SerializeCompressed()),
|
||||
WalletType: data.WalletType,
|
||||
ClientType: data.ClientType,
|
||||
Network: data.Network.Name,
|
||||
RoundLifetime: fmt.Sprintf("%d", data.RoundLifetime),
|
||||
UnilateralExitDelay: fmt.Sprintf("%d", data.UnilateralExitDelay),
|
||||
MinRelayFee: fmt.Sprintf("%d", data.MinRelayFee),
|
||||
BoardingDescriptorTemplate: data.BoardingDescriptorTemplate,
|
||||
}
|
||||
|
||||
if err := s.write(sd); err != nil {
|
||||
|
||||
@@ -13,14 +13,15 @@ const (
|
||||
)
|
||||
|
||||
type StoreData struct {
|
||||
AspUrl string
|
||||
AspPubkey *secp256k1.PublicKey
|
||||
WalletType string
|
||||
ClientType string
|
||||
Network common.Network
|
||||
RoundLifetime int64
|
||||
UnilateralExitDelay int64
|
||||
MinRelayFee uint64
|
||||
AspUrl string
|
||||
AspPubkey *secp256k1.PublicKey
|
||||
WalletType string
|
||||
ClientType string
|
||||
Network common.Network
|
||||
RoundLifetime int64
|
||||
UnilateralExitDelay int64
|
||||
MinRelayFee uint64
|
||||
BoardingDescriptorTemplate string
|
||||
}
|
||||
|
||||
type ConfigStore interface {
|
||||
|
||||
@@ -18,14 +18,15 @@ func TestStore(t *testing.T) {
|
||||
key, _ := btcec.NewPrivateKey()
|
||||
ctx := context.Background()
|
||||
testStoreData := store.StoreData{
|
||||
AspUrl: "localhost:7070",
|
||||
AspPubkey: key.PubKey(),
|
||||
WalletType: wallet.SingleKeyWallet,
|
||||
ClientType: client.GrpcClient,
|
||||
Network: common.LiquidRegTest,
|
||||
RoundLifetime: 512,
|
||||
UnilateralExitDelay: 512,
|
||||
MinRelayFee: 300,
|
||||
AspUrl: "localhost:7070",
|
||||
AspPubkey: key.PubKey(),
|
||||
WalletType: wallet.SingleKeyWallet,
|
||||
ClientType: client.GrpcClient,
|
||||
Network: common.LiquidRegTest,
|
||||
RoundLifetime: 512,
|
||||
UnilateralExitDelay: 512,
|
||||
MinRelayFee: 300,
|
||||
BoardingDescriptorTemplate: "tr(0250929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0,{ and(pk(873079a0091c9b16abd1f8c508320b07f0d50144d09ccd792ce9c915dac60465), pk(USER)), and(older(604672), pk(USER)) })",
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
|
||||
@@ -9,12 +9,12 @@ import (
|
||||
|
||||
"github.com/ark-network/ark/common"
|
||||
"github.com/ark-network/ark/common/bitcointree"
|
||||
"github.com/ark-network/ark/common/descriptor"
|
||||
"github.com/ark-network/ark/pkg/client-sdk/explorer"
|
||||
"github.com/ark-network/ark/pkg/client-sdk/internal/utils"
|
||||
"github.com/ark-network/ark/pkg/client-sdk/store"
|
||||
"github.com/ark-network/ark/pkg/client-sdk/wallet"
|
||||
walletstore "github.com/ark-network/ark/pkg/client-sdk/wallet/singlekey/store"
|
||||
"github.com/btcsuite/btcd/btcec/v2/ecdsa"
|
||||
"github.com/btcsuite/btcd/btcec/v2/schnorr"
|
||||
"github.com/btcsuite/btcd/btcutil"
|
||||
"github.com/btcsuite/btcd/btcutil/psbt"
|
||||
@@ -41,42 +41,42 @@ func NewBitcoinWallet(
|
||||
func (w *bitcoinWallet) GetAddresses(
|
||||
ctx context.Context,
|
||||
) ([]string, []string, []string, error) {
|
||||
offchainAddr, onchainAddr, redemptionAddr, err := w.getAddress(ctx)
|
||||
offchainAddr, boardingAddr, redemptionAddr, err := w.getAddress(ctx)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
offchainAddrs := []string{offchainAddr}
|
||||
onchainAddrs := []string{onchainAddr}
|
||||
boardingAddrs := []string{boardingAddr}
|
||||
redemptionAddrs := []string{redemptionAddr}
|
||||
return offchainAddrs, onchainAddrs, redemptionAddrs, nil
|
||||
return offchainAddrs, boardingAddrs, redemptionAddrs, nil
|
||||
}
|
||||
|
||||
func (w *bitcoinWallet) NewAddress(
|
||||
ctx context.Context, _ bool,
|
||||
) (string, string, error) {
|
||||
offchainAddr, onchainAddr, _, err := w.getAddress(ctx)
|
||||
offchainAddr, boardingAddr, _, err := w.getAddress(ctx)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
return offchainAddr, onchainAddr, nil
|
||||
return offchainAddr, boardingAddr, nil
|
||||
}
|
||||
|
||||
func (w *bitcoinWallet) NewAddresses(
|
||||
ctx context.Context, _ bool, num int,
|
||||
) ([]string, []string, error) {
|
||||
offchainAddr, onchainAddr, _, err := w.getAddress(ctx)
|
||||
offchainAddr, boardingAddr, _, err := w.getAddress(ctx)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
offchainAddrs := make([]string, 0, num)
|
||||
onchainAddrs := make([]string, 0, num)
|
||||
boardingAddrs := make([]string, 0, num)
|
||||
for i := 0; i < num; i++ {
|
||||
offchainAddrs = append(offchainAddrs, offchainAddr)
|
||||
onchainAddrs = append(onchainAddrs, onchainAddr)
|
||||
boardingAddrs = append(boardingAddrs, boardingAddr)
|
||||
}
|
||||
return offchainAddrs, onchainAddrs, nil
|
||||
return offchainAddrs, boardingAddrs, nil
|
||||
}
|
||||
|
||||
func (s *bitcoinWallet) SignTransaction(
|
||||
@@ -92,11 +92,6 @@ func (s *bitcoinWallet) SignTransaction(
|
||||
return "", err
|
||||
}
|
||||
|
||||
data, err := s.configStore.GetData(ctx)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
for i, input := range updater.Upsbt.UnsignedTx.TxIn {
|
||||
if updater.Upsbt.Inputs[i].WitnessUtxo != nil {
|
||||
continue
|
||||
@@ -122,28 +117,11 @@ func (s *bitcoinWallet) SignTransaction(
|
||||
return "", err
|
||||
}
|
||||
|
||||
sighashType := txscript.SigHashAll
|
||||
|
||||
if utxo.PkScript[0] == txscript.OP_1 {
|
||||
sighashType = txscript.SigHashDefault
|
||||
}
|
||||
|
||||
if err := updater.AddInSighashType(sighashType, i); err != nil {
|
||||
if err := updater.AddInSighashType(txscript.SigHashDefault, i); err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
_, onchainAddr, _, err := s.getAddress(ctx)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
net := utils.ToBitcoinNetwork(data.Network)
|
||||
addr, _ := btcutil.DecodeAddress(onchainAddr, &net)
|
||||
onchainWalletScript, err := txscript.PayToAddrScript(addr)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
prevouts := make(map[wire.OutPoint]*wire.TxOut)
|
||||
|
||||
for i, input := range updater.Upsbt.Inputs {
|
||||
@@ -158,36 +136,6 @@ func (s *bitcoinWallet) SignTransaction(
|
||||
txsighashes := txscript.NewTxSigHashes(updater.Upsbt.UnsignedTx, prevoutFetcher)
|
||||
|
||||
for i, input := range ptx.Inputs {
|
||||
if bytes.Equal(input.WitnessUtxo.PkScript, onchainWalletScript) {
|
||||
if err := updater.AddInSighashType(txscript.SigHashAll, i); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
preimage, err := txscript.CalcWitnessSigHash(
|
||||
input.WitnessUtxo.PkScript,
|
||||
txsighashes,
|
||||
txscript.SigHashAll,
|
||||
updater.Upsbt.UnsignedTx,
|
||||
i,
|
||||
int64(input.WitnessUtxo.Value),
|
||||
)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
sig := ecdsa.Sign(s.privateKey, preimage)
|
||||
signatureWithSighashType := append(sig.Serialize(), byte(txscript.SigHashAll))
|
||||
|
||||
updater.Upsbt.Inputs[i].PartialSigs = []*psbt.PartialSig{
|
||||
{
|
||||
PubKey: s.walletData.Pubkey.SerializeCompressed(),
|
||||
Signature: signatureWithSighashType,
|
||||
},
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
if len(input.TaprootLeafScript) > 0 {
|
||||
pubkey := s.walletData.Pubkey
|
||||
for _, leaf := range input.TaprootLeafScript {
|
||||
@@ -269,11 +217,6 @@ func (w *bitcoinWallet) getAddress(
|
||||
|
||||
netParams := utils.ToBitcoinNetwork(data.Network)
|
||||
|
||||
onchainAddr, err := btcutil.NewAddressWitnessPubKeyHash(btcutil.Hash160(w.walletData.Pubkey.SerializeCompressed()), &netParams)
|
||||
if err != nil {
|
||||
return "", "", "", err
|
||||
}
|
||||
|
||||
vtxoTapKey, _, err := bitcointree.ComputeVtxoTaprootScript(
|
||||
w.walletData.Pubkey, data.AspPubkey, uint(data.UnilateralExitDelay),
|
||||
)
|
||||
@@ -289,5 +232,35 @@ func (w *bitcoinWallet) getAddress(
|
||||
return "", "", "", err
|
||||
}
|
||||
|
||||
return offchainAddr, onchainAddr.EncodeAddress(), redemptionAddr.EncodeAddress(), nil
|
||||
myPubkeyStr := hex.EncodeToString(schnorr.SerializePubKey(w.walletData.Pubkey))
|
||||
descriptorStr := strings.ReplaceAll(
|
||||
data.BoardingDescriptorTemplate, "USER", myPubkeyStr,
|
||||
)
|
||||
|
||||
desc, err := descriptor.ParseTaprootDescriptor(descriptorStr)
|
||||
if err != nil {
|
||||
return "", "", "", err
|
||||
}
|
||||
|
||||
_, boardingTimeout, err := descriptor.ParseBoardingDescriptor(*desc)
|
||||
if err != nil {
|
||||
return "", "", "", err
|
||||
}
|
||||
|
||||
boardingTapKey, _, err := bitcointree.ComputeVtxoTaprootScript(
|
||||
w.walletData.Pubkey, data.AspPubkey, boardingTimeout,
|
||||
)
|
||||
if err != nil {
|
||||
return "", "", "", err
|
||||
}
|
||||
|
||||
boardingAddr, err := btcutil.NewAddressTaproot(
|
||||
schnorr.SerializePubKey(boardingTapKey),
|
||||
&netParams,
|
||||
)
|
||||
if err != nil {
|
||||
return "", "", "", err
|
||||
}
|
||||
|
||||
return offchainAddr, boardingAddr.EncodeAddress(), redemptionAddr.EncodeAddress(), nil
|
||||
}
|
||||
|
||||
@@ -3,20 +3,21 @@ package singlekeywallet
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/ark-network/ark/common"
|
||||
"github.com/ark-network/ark/common/descriptor"
|
||||
"github.com/ark-network/ark/common/tree"
|
||||
"github.com/ark-network/ark/pkg/client-sdk/explorer"
|
||||
"github.com/ark-network/ark/pkg/client-sdk/internal/utils"
|
||||
"github.com/ark-network/ark/pkg/client-sdk/store"
|
||||
"github.com/ark-network/ark/pkg/client-sdk/wallet"
|
||||
walletstore "github.com/ark-network/ark/pkg/client-sdk/wallet/singlekey/store"
|
||||
"github.com/btcsuite/btcd/btcec/v2/ecdsa"
|
||||
"github.com/btcsuite/btcd/btcec/v2/schnorr"
|
||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||
"github.com/btcsuite/btcd/txscript"
|
||||
"github.com/vulpemventures/go-elements/payment"
|
||||
"github.com/vulpemventures/go-elements/psetv2"
|
||||
"github.com/vulpemventures/go-elements/transaction"
|
||||
)
|
||||
@@ -40,42 +41,42 @@ func NewLiquidWallet(
|
||||
func (w *liquidWallet) GetAddresses(
|
||||
ctx context.Context,
|
||||
) ([]string, []string, []string, error) {
|
||||
offchainAddr, onchainAddr, redemptionAddr, err := w.getAddress(ctx)
|
||||
offchainAddr, boardingAddr, redemptionAddr, err := w.getAddress(ctx)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
offchainAddrs := []string{offchainAddr}
|
||||
onchainAddrs := []string{onchainAddr}
|
||||
boardingAddrs := []string{boardingAddr}
|
||||
redemptionAddrs := []string{redemptionAddr}
|
||||
return offchainAddrs, onchainAddrs, redemptionAddrs, nil
|
||||
return offchainAddrs, boardingAddrs, redemptionAddrs, nil
|
||||
}
|
||||
|
||||
func (w *liquidWallet) NewAddress(
|
||||
ctx context.Context, _ bool,
|
||||
) (string, string, error) {
|
||||
offchainAddr, onchainAddr, _, err := w.getAddress(ctx)
|
||||
offchainAddr, boardingAddr, _, err := w.getAddress(ctx)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
return offchainAddr, onchainAddr, nil
|
||||
return offchainAddr, boardingAddr, nil
|
||||
}
|
||||
|
||||
func (w *liquidWallet) NewAddresses(
|
||||
ctx context.Context, _ bool, num int,
|
||||
) ([]string, []string, error) {
|
||||
offchainAddr, onchainAddr, _, err := w.getAddress(ctx)
|
||||
offchainAddr, boardingAddr, _, err := w.getAddress(ctx)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
offchainAddrs := make([]string, 0, num)
|
||||
onchainAddrs := make([]string, 0, num)
|
||||
boardingAddrs := make([]string, 0, num)
|
||||
for i := 0; i < num; i++ {
|
||||
offchainAddrs = append(offchainAddrs, offchainAddr)
|
||||
onchainAddrs = append(onchainAddrs, onchainAddr)
|
||||
boardingAddrs = append(boardingAddrs, boardingAddr)
|
||||
}
|
||||
return offchainAddrs, onchainAddrs, nil
|
||||
return offchainAddrs, boardingAddrs, nil
|
||||
}
|
||||
|
||||
func (s *liquidWallet) SignTransaction(
|
||||
@@ -114,13 +115,7 @@ func (s *liquidWallet) SignTransaction(
|
||||
return "", err
|
||||
}
|
||||
|
||||
sighashType := txscript.SigHashAll
|
||||
|
||||
if utxo.Script[0] == txscript.OP_1 {
|
||||
sighashType = txscript.SigHashDefault
|
||||
}
|
||||
|
||||
if err := updater.AddInSighashType(i, sighashType); err != nil {
|
||||
if err := updater.AddInSighashType(i, txscript.SigHashDefault); err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
@@ -135,8 +130,6 @@ func (s *liquidWallet) SignTransaction(
|
||||
return "", err
|
||||
}
|
||||
liquidNet := utils.ToElementsNetwork(storeData.Network)
|
||||
p2wpkh := payment.FromPublicKey(s.walletData.Pubkey, &liquidNet, nil)
|
||||
onchainWalletScript := p2wpkh.WitnessScript
|
||||
|
||||
utx, err := pset.UnsignedTx()
|
||||
if err != nil {
|
||||
@@ -156,33 +149,6 @@ func (s *liquidWallet) SignTransaction(
|
||||
serializedPubKey := s.walletData.Pubkey.SerializeCompressed()
|
||||
|
||||
for i, input := range pset.Inputs {
|
||||
prevout := input.GetUtxo()
|
||||
|
||||
if bytes.Equal(prevout.Script, onchainWalletScript) {
|
||||
p, err := payment.FromScript(prevout.Script, &liquidNet, nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
preimage := utx.HashForWitnessV0(
|
||||
i, p.Script, prevout.Value, txscript.SigHashAll,
|
||||
)
|
||||
|
||||
sig := ecdsa.Sign(s.privateKey, preimage[:])
|
||||
|
||||
signatureWithSighashType := append(
|
||||
sig.Serialize(), byte(txscript.SigHashAll),
|
||||
)
|
||||
|
||||
err = signer.SignInput(
|
||||
i, signatureWithSighashType, serializedPubKey, nil, nil,
|
||||
)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if len(input.TapLeafScript) > 0 {
|
||||
genesis, err := chainhash.NewHashFromStr(liquidNet.GenesisBlockHash)
|
||||
if err != nil {
|
||||
@@ -276,12 +242,6 @@ func (w *liquidWallet) getAddress(
|
||||
|
||||
liquidNet := utils.ToElementsNetwork(data.Network)
|
||||
|
||||
p2wpkh := payment.FromPublicKey(w.walletData.Pubkey, &liquidNet, nil)
|
||||
onchainAddr, err := p2wpkh.WitnessPubKeyHash()
|
||||
if err != nil {
|
||||
return "", "", "", err
|
||||
}
|
||||
|
||||
_, _, _, redemptionAddr, err := tree.ComputeVtxoTaprootScript(
|
||||
w.walletData.Pubkey, data.AspPubkey, uint(data.UnilateralExitDelay), liquidNet,
|
||||
)
|
||||
@@ -289,5 +249,27 @@ func (w *liquidWallet) getAddress(
|
||||
return "", "", "", err
|
||||
}
|
||||
|
||||
return offchainAddr, onchainAddr, redemptionAddr, nil
|
||||
myPubkeyStr := hex.EncodeToString(schnorr.SerializePubKey(w.walletData.Pubkey))
|
||||
descriptorStr := strings.ReplaceAll(
|
||||
data.BoardingDescriptorTemplate, "USER", myPubkeyStr,
|
||||
)
|
||||
|
||||
desc, err := descriptor.ParseTaprootDescriptor(descriptorStr)
|
||||
if err != nil {
|
||||
return "", "", "", err
|
||||
}
|
||||
|
||||
_, boardingTimeout, err := descriptor.ParseBoardingDescriptor(*desc)
|
||||
if err != nil {
|
||||
return "", "", "", err
|
||||
}
|
||||
|
||||
_, _, _, boardingAddr, err := tree.ComputeVtxoTaprootScript(
|
||||
w.walletData.Pubkey, data.AspPubkey, boardingTimeout, liquidNet,
|
||||
)
|
||||
if err != nil {
|
||||
return "", "", "", err
|
||||
}
|
||||
|
||||
return offchainAddr, boardingAddr, redemptionAddr, nil
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ type WalletService interface {
|
||||
IsLocked() bool
|
||||
GetAddresses(
|
||||
ctx context.Context,
|
||||
) (offchainAddresses, onchainAddresses, redemptionAddresses []string, err error)
|
||||
) (offchainAddresses, boardingAddresses, redemptionAddresses []string, err error)
|
||||
NewAddress(
|
||||
ctx context.Context, change bool,
|
||||
) (offchainAddr, onchainAddr string, err error)
|
||||
@@ -29,5 +29,5 @@ type WalletService interface {
|
||||
) (offchainAddresses, onchainAddresses []string, err error)
|
||||
SignTransaction(
|
||||
ctx context.Context, explorerSvc explorer.Explorer, tx string,
|
||||
) (singedTx string, err error)
|
||||
) (signedTx string, err error)
|
||||
}
|
||||
|
||||
@@ -21,14 +21,15 @@ func TestWallet(t *testing.T) {
|
||||
key, _ := btcec.NewPrivateKey()
|
||||
password := "password"
|
||||
testStoreData := store.StoreData{
|
||||
AspUrl: "localhost:7070",
|
||||
AspPubkey: key.PubKey(),
|
||||
WalletType: wallet.SingleKeyWallet,
|
||||
ClientType: client.GrpcClient,
|
||||
Network: common.LiquidRegTest,
|
||||
RoundLifetime: 512,
|
||||
UnilateralExitDelay: 512,
|
||||
MinRelayFee: 300,
|
||||
AspUrl: "localhost:7070",
|
||||
AspPubkey: key.PubKey(),
|
||||
WalletType: wallet.SingleKeyWallet,
|
||||
ClientType: client.GrpcClient,
|
||||
Network: common.LiquidRegTest,
|
||||
RoundLifetime: 512,
|
||||
UnilateralExitDelay: 512,
|
||||
MinRelayFee: 300,
|
||||
BoardingDescriptorTemplate: "tr(0250929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0,{ and(pk(873079a0091c9b16abd1f8c508320b07f0d50144d09ccd792ce9c915dac60465), pk(USER)), and(older(604672), pk(USER)) })",
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
|
||||
@@ -27,7 +27,6 @@ func init() {
|
||||
js.Global().Set("lock", LockWrapper())
|
||||
js.Global().Set("locked", IsLockedWrapper())
|
||||
js.Global().Set("balance", BalanceWrapper())
|
||||
js.Global().Set("onboard", OnboardWrapper())
|
||||
js.Global().Set("receive", ReceiveWrapper())
|
||||
js.Global().Set("sendOnChain", SendOnChainWrapper())
|
||||
js.Global().Set("sendOffChain", SendOffChainWrapper())
|
||||
|
||||
@@ -140,33 +140,18 @@ func BalanceWrapper() js.Func {
|
||||
})
|
||||
}
|
||||
|
||||
func OnboardWrapper() js.Func {
|
||||
return JSPromise(func(args []js.Value) (interface{}, error) {
|
||||
if len(args) != 1 {
|
||||
return nil, errors.New("invalid number of args")
|
||||
}
|
||||
amount := uint64(args[0].Int())
|
||||
|
||||
txID, err := arkSdkClient.Onboard(context.Background(), amount)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return js.ValueOf(txID), nil
|
||||
})
|
||||
}
|
||||
|
||||
func ReceiveWrapper() js.Func {
|
||||
return JSPromise(func(args []js.Value) (interface{}, error) {
|
||||
if arkSdkClient == nil {
|
||||
return nil, errors.New("ARK SDK client is not initialized")
|
||||
}
|
||||
offchainAddr, onchainAddr, err := arkSdkClient.Receive(context.Background())
|
||||
offchainAddr, boardingAddr, err := arkSdkClient.Receive(context.Background())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := map[string]interface{}{
|
||||
"offchainAddr": offchainAddr,
|
||||
"onchainAddr": onchainAddr,
|
||||
"boardingAddr": boardingAddr,
|
||||
}
|
||||
return js.ValueOf(result), nil
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user