-
Notifications
You must be signed in to change notification settings - Fork 111
Expand file tree
/
Copy pathseller.go
More file actions
115 lines (90 loc) · 3.74 KB
/
Copy pathseller.go
File metadata and controls
115 lines (90 loc) · 3.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package views
import (
"encoding/json"
"github.com/LFDT-Panurus/panurus/integration/token/dvp/views/house"
"github.com/LFDT-Panurus/panurus/token/services/nfttx"
"github.com/LFDT-Panurus/panurus/token/services/ttx"
"github.com/hyperledger-labs/fabric-smart-client/platform/common/utils/assert"
"github.com/hyperledger-labs/fabric-smart-client/platform/view/services/id"
"github.com/hyperledger-labs/fabric-smart-client/platform/view/view"
)
// Sell contains the sell instructions
type Sell struct {
// Wallet is the wallet from which recipient identities must be derived
Wallet string
// HouseID is the house ID of the house to sell
HouseID string
// Buyer is the identity of the buyer (it is identifier as defined in the topology)
Buyer string
}
type SellHouseView struct {
*Sell
}
func (d *SellHouseView) Call(context view.Context) (any, error) {
// Prepare a new token transaction.
// It will contain two legs:
// 1. The first leg will be used to transfer the house to the buyer.
// 2. The second leg will be used to transfer the cash to the seller.
idProvider, err := id.GetProvider(context)
assert.NoError(err, "failed getting identity provider")
tx, err := ttx.NewAnonymousTransaction(
context,
ttx.WithAuditor(idProvider.Identity("auditor")),
)
assert.NoError(err, "failed to create a new token transaction")
// Prepare House Transfer
tx, house, err := d.prepareHouseTransfer(context, tx)
assert.NoError(err, "failed to prepare house transfer")
// Prepare Payment
tx, err = d.preparePayment(context, tx, house)
assert.NoError(err, "failed to prepare payment")
// Collect signature from the parties
_, err = context.RunView(ttx.NewCollectEndorsementsView(tx))
assert.NoError(err, "failed to collect endorsements")
// Send to the ordering service and wait for confirmation
_, err = context.RunView(ttx.NewOrderingAndFinalityView(tx))
assert.NoError(err, "failed ordering and finality")
return tx.ID(), nil
}
func (d *SellHouseView) preparePayment(context view.Context, tx *ttx.Transaction, house *house.House) (*ttx.Transaction, error) {
// we need the house's valuation
wallet := nfttx.MyWallet(context)
assert.NotNil(wallet, "failed getting default wallet")
// exchange pseudonyms for the token transfer
me, other, err := ttx.ExchangeRecipientIdentities(context, d.Wallet, view.Identity(d.Buyer))
assert.NoError(err, "failed exchanging identities")
// collect token transfer from the buyer
_, err = context.RunView(ttx.NewCollectActionsView(tx,
&ttx.ActionTransfer{
From: other,
Type: "USD",
Amount: house.Valuation,
Recipient: me,
}))
assert.NoError(err, "failed collecting token action")
return tx, nil
}
func (d *SellHouseView) prepareHouseTransfer(context view.Context, tx *ttx.Transaction) (*ttx.Transaction, *house.House, error) {
// let's prepare the NFT transfer
wallet := nfttx.MyWallet(context)
assert.NotNil(wallet, "failed getting default wallet")
house := &house.House{}
assert.NoError(wallet.QueryByKey(context.Context(), house, "LinearID", d.HouseID), "failed loading house with id %s", d.HouseID)
buyer, err := nfttx.RequestRecipientIdentity(context, view.Identity(d.Buyer))
assert.NoError(err, "failed getting buyer identity")
assert.NotNil(wallet, "failed getting default wallet")
// Transfer ownership of the house to the buyer
assert.NoError(nfttx.Wrap(tx).Transfer(context.Context(), wallet, house, buyer), "failed transferring house")
return tx, house, nil
}
type SellHouseViewFactory struct{}
func (s SellHouseViewFactory) NewView(in []byte) (view.View, error) {
f := &SellHouseView{Sell: &Sell{}}
err := json.Unmarshal(in, f)
assert.NoError(err, "failed unmarshalling input")
return f, nil
}