mirror of
https://github.com/aljazceru/ark.git
synced 2025-12-17 12:14:21 +01:00
Add support for Out Of Round txs (#359)
* [common] rework address encoding * new address encoding * replace offchain address by vtxo output key in DB * merge migrations files into init one * fix txbuilder fixtures * fix transaction events * OOR scheme * fix conflicts * [sdk] OOR * update WASM wrappers * revert renaming * revert API changes * update parser.go * fix vtxosToTxsCovenantless * add settled and spent in Utxo and Transaction * Fixes (#5) * Revert unneeded changes and rename claim to settle * Revert changes to wasm and rename claim to settle --------- Co-authored-by: Pietralberto Mazza <18440657+altafan@users.noreply.github.com>
This commit is contained in:
@@ -1070,7 +1070,7 @@
|
||||
"swept": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"pending": {
|
||||
"isOor": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"redeemTx": {
|
||||
|
||||
@@ -318,7 +318,7 @@ message Vtxo {
|
||||
string spent_by = 4;
|
||||
int64 expire_at = 5;
|
||||
bool swept = 6;
|
||||
bool pending = 7;
|
||||
bool is_oor = 7;
|
||||
string redeem_tx = 8;
|
||||
uint64 amount = 9;
|
||||
string pubkey = 10;
|
||||
|
||||
@@ -2436,7 +2436,7 @@ type Vtxo struct {
|
||||
SpentBy string `protobuf:"bytes,4,opt,name=spent_by,json=spentBy,proto3" json:"spent_by,omitempty"`
|
||||
ExpireAt int64 `protobuf:"varint,5,opt,name=expire_at,json=expireAt,proto3" json:"expire_at,omitempty"`
|
||||
Swept bool `protobuf:"varint,6,opt,name=swept,proto3" json:"swept,omitempty"`
|
||||
Pending bool `protobuf:"varint,7,opt,name=pending,proto3" json:"pending,omitempty"`
|
||||
IsOor bool `protobuf:"varint,7,opt,name=is_oor,json=isOor,proto3" json:"is_oor,omitempty"`
|
||||
RedeemTx string `protobuf:"bytes,8,opt,name=redeem_tx,json=redeemTx,proto3" json:"redeem_tx,omitempty"`
|
||||
Amount uint64 `protobuf:"varint,9,opt,name=amount,proto3" json:"amount,omitempty"`
|
||||
Pubkey string `protobuf:"bytes,10,opt,name=pubkey,proto3" json:"pubkey,omitempty"`
|
||||
@@ -2516,9 +2516,9 @@ func (x *Vtxo) GetSwept() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *Vtxo) GetPending() bool {
|
||||
func (x *Vtxo) GetIsOor() bool {
|
||||
if x != nil {
|
||||
return x.Pending
|
||||
return x.IsOor
|
||||
}
|
||||
return false
|
||||
}
|
||||
@@ -3067,7 +3067,7 @@ var file_ark_v1_service_proto_rawDesc = []byte{
|
||||
0x52, 0x04, 0x74, 0x78, 0x69, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x78, 0x18, 0x02, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x02, 0x74, 0x78, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74,
|
||||
0x5f, 0x74, 0x78, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x61, 0x72,
|
||||
0x65, 0x6e, 0x74, 0x54, 0x78, 0x69, 0x64, 0x22, 0x9e, 0x02, 0x0a, 0x04, 0x56, 0x74, 0x78, 0x6f,
|
||||
0x65, 0x6e, 0x74, 0x54, 0x78, 0x69, 0x64, 0x22, 0x9b, 0x02, 0x0a, 0x04, 0x56, 0x74, 0x78, 0x6f,
|
||||
0x12, 0x2c, 0x0a, 0x08, 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x10, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x75, 0x74, 0x70,
|
||||
0x6f, 0x69, 0x6e, 0x74, 0x52, 0x08, 0x6f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x14,
|
||||
@@ -3079,177 +3079,177 @@ var file_ark_v1_service_proto_rawDesc = []byte{
|
||||
0x0a, 0x09, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28,
|
||||
0x03, 0x52, 0x08, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x41, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x73,
|
||||
0x77, 0x65, 0x70, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x73, 0x77, 0x65, 0x70,
|
||||
0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x18, 0x07, 0x20, 0x01,
|
||||
0x28, 0x08, 0x52, 0x07, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x1b, 0x0a, 0x09, 0x72,
|
||||
0x65, 0x64, 0x65, 0x65, 0x6d, 0x5f, 0x74, 0x78, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08,
|
||||
0x72, 0x65, 0x64, 0x65, 0x65, 0x6d, 0x54, 0x78, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75,
|
||||
0x6e, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74,
|
||||
0x12, 0x16, 0x0a, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x22, 0x1e, 0x0a, 0x1c, 0x47, 0x65, 0x74, 0x54,
|
||||
0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x53, 0x74, 0x72, 0x65, 0x61,
|
||||
0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x8c, 0x01, 0x0a, 0x1d, 0x47, 0x65, 0x74,
|
||||
0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x53, 0x74, 0x72, 0x65,
|
||||
0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x30, 0x0a, 0x05, 0x72, 0x6f,
|
||||
0x75, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x61, 0x72, 0x6b, 0x2e,
|
||||
0x76, 0x31, 0x2e, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x05, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x33, 0x0a, 0x06,
|
||||
0x72, 0x65, 0x64, 0x65, 0x65, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x61,
|
||||
0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x64, 0x65, 0x65, 0x6d, 0x54, 0x72, 0x61, 0x6e,
|
||||
0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x06, 0x72, 0x65, 0x64, 0x65, 0x65,
|
||||
0x6d, 0x42, 0x04, 0x0a, 0x02, 0x74, 0x78, 0x22, 0xd8, 0x01, 0x0a, 0x10, 0x52, 0x6f, 0x75, 0x6e,
|
||||
0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04,
|
||||
0x74, 0x78, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x78, 0x69, 0x64,
|
||||
0x12, 0x31, 0x0a, 0x0b, 0x73, 0x70, 0x65, 0x6e, 0x74, 0x5f, 0x76, 0x74, 0x78, 0x6f, 0x73, 0x18,
|
||||
0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x4f,
|
||||
0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x0a, 0x73, 0x70, 0x65, 0x6e, 0x74, 0x56, 0x74,
|
||||
0x78, 0x6f, 0x73, 0x12, 0x35, 0x0a, 0x0f, 0x73, 0x70, 0x65, 0x6e, 0x64, 0x61, 0x62, 0x6c, 0x65,
|
||||
0x5f, 0x76, 0x74, 0x78, 0x6f, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x61,
|
||||
0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x74, 0x78, 0x6f, 0x52, 0x0e, 0x73, 0x70, 0x65, 0x6e,
|
||||
0x64, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x74, 0x78, 0x6f, 0x73, 0x12, 0x46, 0x0a, 0x16, 0x63, 0x6c,
|
||||
0x61, 0x69, 0x6d, 0x65, 0x64, 0x5f, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x75,
|
||||
0x74, 0x78, 0x6f, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x61, 0x72, 0x6b,
|
||||
0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x14, 0x63, 0x6c,
|
||||
0x61, 0x69, 0x6d, 0x65, 0x64, 0x42, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x55, 0x74, 0x78,
|
||||
0x6f, 0x73, 0x22, 0x91, 0x01, 0x0a, 0x11, 0x52, 0x65, 0x64, 0x65, 0x65, 0x6d, 0x54, 0x72, 0x61,
|
||||
0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x78, 0x69, 0x64,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x78, 0x69, 0x64, 0x12, 0x31, 0x0a, 0x0b,
|
||||
0x73, 0x70, 0x65, 0x6e, 0x74, 0x5f, 0x76, 0x74, 0x78, 0x6f, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28,
|
||||
0x0b, 0x32, 0x10, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x75, 0x74, 0x70, 0x6f,
|
||||
0x69, 0x6e, 0x74, 0x52, 0x0a, 0x73, 0x70, 0x65, 0x6e, 0x74, 0x56, 0x74, 0x78, 0x6f, 0x73, 0x12,
|
||||
0x35, 0x0a, 0x0f, 0x73, 0x70, 0x65, 0x6e, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x76, 0x74, 0x78,
|
||||
0x6f, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76,
|
||||
0x31, 0x2e, 0x56, 0x74, 0x78, 0x6f, 0x52, 0x0e, 0x73, 0x70, 0x65, 0x6e, 0x64, 0x61, 0x62, 0x6c,
|
||||
0x65, 0x56, 0x74, 0x78, 0x6f, 0x73, 0x2a, 0x98, 0x01, 0x0a, 0x0a, 0x52, 0x6f, 0x75, 0x6e, 0x64,
|
||||
0x53, 0x74, 0x61, 0x67, 0x65, 0x12, 0x1b, 0x0a, 0x17, 0x52, 0x4f, 0x55, 0x4e, 0x44, 0x5f, 0x53,
|
||||
0x54, 0x41, 0x47, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44,
|
||||
0x10, 0x00, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x4f, 0x55, 0x4e, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x47,
|
||||
0x45, 0x5f, 0x52, 0x45, 0x47, 0x49, 0x53, 0x54, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01,
|
||||
0x12, 0x1c, 0x0a, 0x18, 0x52, 0x4f, 0x55, 0x4e, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x47, 0x45, 0x5f,
|
||||
0x46, 0x49, 0x4e, 0x41, 0x4c, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x02, 0x12, 0x19,
|
||||
0x0a, 0x15, 0x52, 0x4f, 0x55, 0x4e, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x47, 0x45, 0x5f, 0x46, 0x49,
|
||||
0x4e, 0x41, 0x4c, 0x49, 0x5a, 0x45, 0x44, 0x10, 0x03, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x4f, 0x55,
|
||||
0x4e, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x47, 0x45, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10,
|
||||
0x04, 0x32, 0xeb, 0x0d, 0x0a, 0x0a, 0x41, 0x72, 0x6b, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
|
||||
0x12, 0x4c, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x16, 0x2e, 0x61, 0x72,
|
||||
0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74,
|
||||
0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x10, 0x82, 0xd3,
|
||||
0xe4, 0x93, 0x02, 0x0a, 0x12, 0x08, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x74,
|
||||
0x0a, 0x12, 0x47, 0x65, 0x74, 0x42, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x41, 0x64, 0x64,
|
||||
0x72, 0x65, 0x73, 0x73, 0x12, 0x21, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65,
|
||||
0x74, 0x12, 0x15, 0x0a, 0x06, 0x69, 0x73, 0x5f, 0x6f, 0x6f, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28,
|
||||
0x08, 0x52, 0x05, 0x69, 0x73, 0x4f, 0x6f, 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x72, 0x65, 0x64, 0x65,
|
||||
0x65, 0x6d, 0x5f, 0x74, 0x78, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x64,
|
||||
0x65, 0x65, 0x6d, 0x54, 0x78, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18,
|
||||
0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x16, 0x0a,
|
||||
0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70,
|
||||
0x75, 0x62, 0x6b, 0x65, 0x79, 0x22, 0x1e, 0x0a, 0x1c, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e,
|
||||
0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x8c, 0x01, 0x0a, 0x1d, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61,
|
||||
0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x30, 0x0a, 0x05, 0x72, 0x6f, 0x75, 0x6e, 0x64,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e,
|
||||
0x52, 0x6f, 0x75, 0x6e, 0x64, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x48, 0x00, 0x52, 0x05, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x33, 0x0a, 0x06, 0x72, 0x65, 0x64,
|
||||
0x65, 0x65, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x61, 0x72, 0x6b, 0x2e,
|
||||
0x76, 0x31, 0x2e, 0x52, 0x65, 0x64, 0x65, 0x65, 0x6d, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x06, 0x72, 0x65, 0x64, 0x65, 0x65, 0x6d, 0x42, 0x04,
|
||||
0x0a, 0x02, 0x74, 0x78, 0x22, 0xd8, 0x01, 0x0a, 0x10, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x54, 0x72,
|
||||
0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x78, 0x69,
|
||||
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x78, 0x69, 0x64, 0x12, 0x31, 0x0a,
|
||||
0x0b, 0x73, 0x70, 0x65, 0x6e, 0x74, 0x5f, 0x76, 0x74, 0x78, 0x6f, 0x73, 0x18, 0x02, 0x20, 0x03,
|
||||
0x28, 0x0b, 0x32, 0x10, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x75, 0x74, 0x70,
|
||||
0x6f, 0x69, 0x6e, 0x74, 0x52, 0x0a, 0x73, 0x70, 0x65, 0x6e, 0x74, 0x56, 0x74, 0x78, 0x6f, 0x73,
|
||||
0x12, 0x35, 0x0a, 0x0f, 0x73, 0x70, 0x65, 0x6e, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x76, 0x74,
|
||||
0x78, 0x6f, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x61, 0x72, 0x6b, 0x2e,
|
||||
0x76, 0x31, 0x2e, 0x56, 0x74, 0x78, 0x6f, 0x52, 0x0e, 0x73, 0x70, 0x65, 0x6e, 0x64, 0x61, 0x62,
|
||||
0x6c, 0x65, 0x56, 0x74, 0x78, 0x6f, 0x73, 0x12, 0x46, 0x0a, 0x16, 0x63, 0x6c, 0x61, 0x69, 0x6d,
|
||||
0x65, 0x64, 0x5f, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x75, 0x74, 0x78, 0x6f,
|
||||
0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31,
|
||||
0x2e, 0x4f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x14, 0x63, 0x6c, 0x61, 0x69, 0x6d,
|
||||
0x65, 0x64, 0x42, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x55, 0x74, 0x78, 0x6f, 0x73, 0x22,
|
||||
0x91, 0x01, 0x0a, 0x11, 0x52, 0x65, 0x64, 0x65, 0x65, 0x6d, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61,
|
||||
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x78, 0x69, 0x64, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x78, 0x69, 0x64, 0x12, 0x31, 0x0a, 0x0b, 0x73, 0x70, 0x65,
|
||||
0x6e, 0x74, 0x5f, 0x76, 0x74, 0x78, 0x6f, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10,
|
||||
0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x75, 0x74, 0x70, 0x6f, 0x69, 0x6e, 0x74,
|
||||
0x52, 0x0a, 0x73, 0x70, 0x65, 0x6e, 0x74, 0x56, 0x74, 0x78, 0x6f, 0x73, 0x12, 0x35, 0x0a, 0x0f,
|
||||
0x73, 0x70, 0x65, 0x6e, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x76, 0x74, 0x78, 0x6f, 0x73, 0x18,
|
||||
0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x56,
|
||||
0x74, 0x78, 0x6f, 0x52, 0x0e, 0x73, 0x70, 0x65, 0x6e, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x74,
|
||||
0x78, 0x6f, 0x73, 0x2a, 0x98, 0x01, 0x0a, 0x0a, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x53, 0x74, 0x61,
|
||||
0x67, 0x65, 0x12, 0x1b, 0x0a, 0x17, 0x52, 0x4f, 0x55, 0x4e, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x47,
|
||||
0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12,
|
||||
0x1c, 0x0a, 0x18, 0x52, 0x4f, 0x55, 0x4e, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x47, 0x45, 0x5f, 0x52,
|
||||
0x45, 0x47, 0x49, 0x53, 0x54, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x01, 0x12, 0x1c, 0x0a,
|
||||
0x18, 0x52, 0x4f, 0x55, 0x4e, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x47, 0x45, 0x5f, 0x46, 0x49, 0x4e,
|
||||
0x41, 0x4c, 0x49, 0x5a, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x02, 0x12, 0x19, 0x0a, 0x15, 0x52,
|
||||
0x4f, 0x55, 0x4e, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x47, 0x45, 0x5f, 0x46, 0x49, 0x4e, 0x41, 0x4c,
|
||||
0x49, 0x5a, 0x45, 0x44, 0x10, 0x03, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x4f, 0x55, 0x4e, 0x44, 0x5f,
|
||||
0x53, 0x54, 0x41, 0x47, 0x45, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x04, 0x32, 0xeb,
|
||||
0x0d, 0x0a, 0x0a, 0x41, 0x72, 0x6b, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4c, 0x0a,
|
||||
0x07, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x16, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76,
|
||||
0x31, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x1a, 0x17, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x6e, 0x66,
|
||||
0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x10, 0x82, 0xd3, 0xe4, 0x93, 0x02,
|
||||
0x0a, 0x12, 0x08, 0x2f, 0x76, 0x31, 0x2f, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x74, 0x0a, 0x12, 0x47,
|
||||
0x65, 0x74, 0x42, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73,
|
||||
0x73, 0x12, 0x21, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6f,
|
||||
0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65,
|
||||
0x74, 0x42, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31,
|
||||
0x2e, 0x47, 0x65, 0x74, 0x42, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x41, 0x64, 0x64, 0x72,
|
||||
0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x17, 0x82, 0xd3, 0xe4,
|
||||
0x93, 0x02, 0x11, 0x3a, 0x01, 0x2a, 0x22, 0x0c, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x6f, 0x61, 0x72,
|
||||
0x64, 0x69, 0x6e, 0x67, 0x12, 0x98, 0x01, 0x0a, 0x1a, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65,
|
||||
0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x4e, 0x65, 0x78, 0x74, 0x52, 0x6f,
|
||||
0x75, 0x6e, 0x64, 0x12, 0x29, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67,
|
||||
0x69, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x4e, 0x65,
|
||||
0x78, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a,
|
||||
0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72,
|
||||
0x49, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x4e, 0x65, 0x78, 0x74, 0x52, 0x6f, 0x75,
|
||||
0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93,
|
||||
0x02, 0x1d, 0x3a, 0x01, 0x2a, 0x22, 0x18, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x6f, 0x75, 0x6e, 0x64,
|
||||
0x2f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x12,
|
||||
0x9c, 0x01, 0x0a, 0x1b, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70,
|
||||
0x75, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x4e, 0x65, 0x78, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x12,
|
||||
0x2a, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65,
|
||||
0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x4e, 0x65, 0x78, 0x74, 0x52,
|
||||
0x6f, 0x75, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x61, 0x72,
|
||||
0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x4f, 0x75, 0x74,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x17, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x11,
|
||||
0x3a, 0x01, 0x2a, 0x22, 0x0c, 0x2f, 0x76, 0x31, 0x2f, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x69, 0x6e,
|
||||
0x67, 0x12, 0x98, 0x01, 0x0a, 0x1a, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e,
|
||||
0x70, 0x75, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x4e, 0x65, 0x78, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e,
|
||||
0x3a, 0x01, 0x2a, 0x22, 0x19, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2f, 0x72,
|
||||
0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x12, 0x7d,
|
||||
0x0a, 0x10, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x54, 0x72, 0x65, 0x65, 0x4e, 0x6f, 0x6e, 0x63,
|
||||
0x65, 0x73, 0x12, 0x1f, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d,
|
||||
0x69, 0x74, 0x54, 0x72, 0x65, 0x65, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62,
|
||||
0x6d, 0x69, 0x74, 0x54, 0x72, 0x65, 0x65, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x26, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x3a, 0x01, 0x2a,
|
||||
0x22, 0x1b, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2f, 0x74, 0x72, 0x65, 0x65,
|
||||
0x2f, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x8d, 0x01,
|
||||
0x0a, 0x14, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x54, 0x72, 0x65, 0x65, 0x53, 0x69, 0x67, 0x6e,
|
||||
0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x23, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e,
|
||||
0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x54, 0x72, 0x65, 0x65, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74,
|
||||
0x75, 0x72, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x61, 0x72,
|
||||
0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x54, 0x72, 0x65, 0x65, 0x53,
|
||||
0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x22, 0x2a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x3a, 0x01, 0x2a, 0x22, 0x1f, 0x2f, 0x76,
|
||||
0x31, 0x2f, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2f, 0x74, 0x72, 0x65, 0x65, 0x2f, 0x73, 0x75, 0x62,
|
||||
0x6d, 0x69, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x8e, 0x01,
|
||||
0x0a, 0x16, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x46, 0x6f,
|
||||
0x72, 0x66, 0x65, 0x69, 0x74, 0x54, 0x78, 0x73, 0x12, 0x25, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76,
|
||||
0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x46, 0x6f,
|
||||
0x72, 0x66, 0x65, 0x69, 0x74, 0x54, 0x78, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
||||
0x26, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x53,
|
||||
0x69, 0x67, 0x6e, 0x65, 0x64, 0x46, 0x6f, 0x72, 0x66, 0x65, 0x69, 0x74, 0x54, 0x78, 0x73, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x25, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, 0x3a,
|
||||
0x01, 0x2a, 0x22, 0x1a, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2f, 0x73, 0x75,
|
||||
0x62, 0x6d, 0x69, 0x74, 0x46, 0x6f, 0x72, 0x66, 0x65, 0x69, 0x74, 0x54, 0x78, 0x73, 0x12, 0x6b,
|
||||
0x0a, 0x0e, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d,
|
||||
0x12, 0x1d, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65,
|
||||
0x6e, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
||||
0x1e, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e,
|
||||
0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
|
||||
0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x12, 0x10, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x6f, 0x75,
|
||||
0x6e, 0x64, 0x2f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x30, 0x01, 0x12, 0x56, 0x0a, 0x04, 0x50,
|
||||
0x69, 0x6e, 0x67, 0x12, 0x13, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e,
|
||||
0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76,
|
||||
0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23,
|
||||
0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x12, 0x1b, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x6f, 0x75, 0x6e,
|
||||
0x64, 0x2f, 0x70, 0x69, 0x6e, 0x67, 0x2f, 0x7b, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x5f,
|
||||
0x69, 0x64, 0x7d, 0x12, 0x64, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x61, 0x79,
|
||||
0x6d, 0x65, 0x6e, 0x74, 0x12, 0x1c, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72,
|
||||
0x65, 0x61, 0x74, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61,
|
||||
0x74, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x22, 0x16, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x10, 0x3a, 0x01, 0x2a, 0x22, 0x0b, 0x2f, 0x76,
|
||||
0x31, 0x2f, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x73, 0x0a, 0x0f, 0x43, 0x6f, 0x6d,
|
||||
0x70, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x1e, 0x2e, 0x61,
|
||||
0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x61,
|
||||
0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x61,
|
||||
0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x61,
|
||||
0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82,
|
||||
0xd3, 0xe4, 0x93, 0x02, 0x19, 0x3a, 0x01, 0x2a, 0x22, 0x14, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x61,
|
||||
0x79, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x57,
|
||||
0x0a, 0x08, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x17, 0x2e, 0x61, 0x72, 0x6b,
|
||||
0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74,
|
||||
0x52, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x18, 0x82,
|
||||
0xd3, 0xe4, 0x93, 0x02, 0x12, 0x12, 0x10, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x6f, 0x75, 0x6e, 0x64,
|
||||
0x2f, 0x7b, 0x74, 0x78, 0x69, 0x64, 0x7d, 0x12, 0x64, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x52, 0x6f,
|
||||
0x75, 0x6e, 0x64, 0x42, 0x79, 0x49, 0x64, 0x12, 0x1b, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31,
|
||||
0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x42, 0x79, 0x49, 0x64, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65,
|
||||
0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x42, 0x79, 0x49, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x22, 0x19, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x12, 0x11, 0x2f, 0x76, 0x31, 0x2f,
|
||||
0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2f, 0x69, 0x64, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x5d, 0x0a,
|
||||
0x09, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x74, 0x78, 0x6f, 0x73, 0x12, 0x18, 0x2e, 0x61, 0x72, 0x6b,
|
||||
0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x74, 0x78, 0x6f, 0x73, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69,
|
||||
0x73, 0x74, 0x56, 0x74, 0x78, 0x6f, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
|
||||
0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x12, 0x13, 0x2f, 0x76, 0x31, 0x2f, 0x76, 0x74, 0x78,
|
||||
0x6f, 0x73, 0x2f, 0x7b, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x7d, 0x12, 0x80, 0x01, 0x0a,
|
||||
0x15, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73,
|
||||
0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x24, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e,
|
||||
0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x53,
|
||||
0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x61,
|
||||
0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x12, 0x10, 0x2f, 0x76, 0x31,
|
||||
0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x30, 0x01, 0x42,
|
||||
0x92, 0x01, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x42, 0x0c,
|
||||
0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3d,
|
||||
0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x72, 0x6b, 0x2d, 0x6e,
|
||||
0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x61, 0x72, 0x6b, 0x2f, 0x61, 0x70, 0x69, 0x2d, 0x73,
|
||||
0x70, 0x65, 0x63, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x67, 0x65, 0x6e,
|
||||
0x2f, 0x61, 0x72, 0x6b, 0x2f, 0x76, 0x31, 0x3b, 0x61, 0x72, 0x6b, 0x76, 0x31, 0xa2, 0x02, 0x03,
|
||||
0x41, 0x58, 0x58, 0xaa, 0x02, 0x06, 0x41, 0x72, 0x6b, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x06, 0x41,
|
||||
0x72, 0x6b, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x12, 0x41, 0x72, 0x6b, 0x5c, 0x56, 0x31, 0x5c, 0x47,
|
||||
0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x07, 0x41, 0x72, 0x6b,
|
||||
0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x12, 0x29, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74,
|
||||
0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x4e, 0x65, 0x78, 0x74, 0x52,
|
||||
0x6f, 0x75, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x61, 0x72,
|
||||
0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x70,
|
||||
0x75, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x4e, 0x65, 0x78, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x3a,
|
||||
0x01, 0x2a, 0x22, 0x18, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2f, 0x72, 0x65,
|
||||
0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x12, 0x9c, 0x01, 0x0a,
|
||||
0x1b, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73,
|
||||
0x46, 0x6f, 0x72, 0x4e, 0x65, 0x78, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x2a, 0x2e, 0x61,
|
||||
0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x4f, 0x75,
|
||||
0x74, 0x70, 0x75, 0x74, 0x73, 0x46, 0x6f, 0x72, 0x4e, 0x65, 0x78, 0x74, 0x52, 0x6f, 0x75, 0x6e,
|
||||
0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76,
|
||||
0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74,
|
||||
0x73, 0x46, 0x6f, 0x72, 0x4e, 0x65, 0x78, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x3a, 0x01, 0x2a,
|
||||
0x22, 0x19, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2f, 0x72, 0x65, 0x67, 0x69,
|
||||
0x73, 0x74, 0x65, 0x72, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x12, 0x7d, 0x0a, 0x10, 0x53,
|
||||
0x75, 0x62, 0x6d, 0x69, 0x74, 0x54, 0x72, 0x65, 0x65, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x12,
|
||||
0x1f, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x54,
|
||||
0x72, 0x65, 0x65, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x1a, 0x20, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74,
|
||||
0x54, 0x72, 0x65, 0x65, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x22, 0x26, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x3a, 0x01, 0x2a, 0x22, 0x1b, 0x2f,
|
||||
0x76, 0x31, 0x2f, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2f, 0x74, 0x72, 0x65, 0x65, 0x2f, 0x73, 0x75,
|
||||
0x62, 0x6d, 0x69, 0x74, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x8d, 0x01, 0x0a, 0x14, 0x53,
|
||||
0x75, 0x62, 0x6d, 0x69, 0x74, 0x54, 0x72, 0x65, 0x65, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75,
|
||||
0x72, 0x65, 0x73, 0x12, 0x23, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62,
|
||||
0x6d, 0x69, 0x74, 0x54, 0x72, 0x65, 0x65, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65,
|
||||
0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76,
|
||||
0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x54, 0x72, 0x65, 0x65, 0x53, 0x69, 0x67, 0x6e,
|
||||
0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a,
|
||||
0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x3a, 0x01, 0x2a, 0x22, 0x1f, 0x2f, 0x76, 0x31, 0x2f, 0x72,
|
||||
0x6f, 0x75, 0x6e, 0x64, 0x2f, 0x74, 0x72, 0x65, 0x65, 0x2f, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74,
|
||||
0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x8e, 0x01, 0x0a, 0x16, 0x53,
|
||||
0x75, 0x62, 0x6d, 0x69, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x46, 0x6f, 0x72, 0x66, 0x65,
|
||||
0x69, 0x74, 0x54, 0x78, 0x73, 0x12, 0x25, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x53,
|
||||
0x75, 0x62, 0x6d, 0x69, 0x74, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x46, 0x6f, 0x72, 0x66, 0x65,
|
||||
0x69, 0x74, 0x54, 0x78, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x61,
|
||||
0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x53, 0x69, 0x67, 0x6e,
|
||||
0x65, 0x64, 0x46, 0x6f, 0x72, 0x66, 0x65, 0x69, 0x74, 0x54, 0x78, 0x73, 0x52, 0x65, 0x73, 0x70,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x22, 0x25, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, 0x3a, 0x01, 0x2a, 0x22,
|
||||
0x1a, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2f, 0x73, 0x75, 0x62, 0x6d, 0x69,
|
||||
0x74, 0x46, 0x6f, 0x72, 0x66, 0x65, 0x69, 0x74, 0x54, 0x78, 0x73, 0x12, 0x6b, 0x0a, 0x0e, 0x47,
|
||||
0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x1d, 0x2e,
|
||||
0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53,
|
||||
0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x61,
|
||||
0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x74,
|
||||
0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x18, 0x82, 0xd3,
|
||||
0xe4, 0x93, 0x02, 0x12, 0x12, 0x10, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2f,
|
||||
0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x30, 0x01, 0x12, 0x56, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67,
|
||||
0x12, 0x13, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x50,
|
||||
0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4,
|
||||
0x93, 0x02, 0x1d, 0x12, 0x1b, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2f, 0x70,
|
||||
0x69, 0x6e, 0x67, 0x2f, 0x7b, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x7d,
|
||||
0x12, 0x64, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e,
|
||||
0x74, 0x12, 0x1c, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74,
|
||||
0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
||||
0x1d, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50,
|
||||
0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x16,
|
||||
0x82, 0xd3, 0xe4, 0x93, 0x02, 0x10, 0x3a, 0x01, 0x2a, 0x22, 0x0b, 0x2f, 0x76, 0x31, 0x2f, 0x70,
|
||||
0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x73, 0x0a, 0x0f, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65,
|
||||
0x74, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x1e, 0x2e, 0x61, 0x72, 0x6b, 0x2e,
|
||||
0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65,
|
||||
0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x61, 0x72, 0x6b, 0x2e,
|
||||
0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65,
|
||||
0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82, 0xd3, 0xe4, 0x93,
|
||||
0x02, 0x19, 0x3a, 0x01, 0x2a, 0x22, 0x14, 0x2f, 0x76, 0x31, 0x2f, 0x70, 0x61, 0x79, 0x6d, 0x65,
|
||||
0x6e, 0x74, 0x2f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x57, 0x0a, 0x08, 0x47,
|
||||
0x65, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x12, 0x17, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31,
|
||||
0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x1a, 0x18, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75,
|
||||
0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93,
|
||||
0x02, 0x12, 0x12, 0x10, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2f, 0x7b, 0x74,
|
||||
0x78, 0x69, 0x64, 0x7d, 0x12, 0x64, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64,
|
||||
0x42, 0x79, 0x49, 0x64, 0x12, 0x1b, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65,
|
||||
0x74, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x42, 0x79, 0x49, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x1a, 0x1c, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f,
|
||||
0x75, 0x6e, 0x64, 0x42, 0x79, 0x49, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
|
||||
0x19, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x12, 0x11, 0x2f, 0x76, 0x31, 0x2f, 0x72, 0x6f, 0x75,
|
||||
0x6e, 0x64, 0x2f, 0x69, 0x64, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x5d, 0x0a, 0x09, 0x4c, 0x69,
|
||||
0x73, 0x74, 0x56, 0x74, 0x78, 0x6f, 0x73, 0x12, 0x18, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31,
|
||||
0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56, 0x74, 0x78, 0x6f, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x1a, 0x19, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x56,
|
||||
0x74, 0x78, 0x6f, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1b, 0x82, 0xd3,
|
||||
0xe4, 0x93, 0x02, 0x15, 0x12, 0x13, 0x2f, 0x76, 0x31, 0x2f, 0x76, 0x74, 0x78, 0x6f, 0x73, 0x2f,
|
||||
0x7b, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x7d, 0x12, 0x80, 0x01, 0x0a, 0x15, 0x47, 0x65,
|
||||
0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x53, 0x74, 0x72,
|
||||
0x65, 0x61, 0x6d, 0x12, 0x24, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74,
|
||||
0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x53, 0x74, 0x72, 0x65,
|
||||
0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x61, 0x72, 0x6b, 0x2e,
|
||||
0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x73, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x12, 0x10, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x72,
|
||||
0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x30, 0x01, 0x42, 0x92, 0x01, 0x0a,
|
||||
0x0a, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x72, 0x6b, 0x2e, 0x76, 0x31, 0x42, 0x0c, 0x53, 0x65, 0x72,
|
||||
0x76, 0x69, 0x63, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3d, 0x67, 0x69, 0x74,
|
||||
0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x72, 0x6b, 0x2d, 0x6e, 0x65, 0x74, 0x77,
|
||||
0x6f, 0x72, 0x6b, 0x2f, 0x61, 0x72, 0x6b, 0x2f, 0x61, 0x70, 0x69, 0x2d, 0x73, 0x70, 0x65, 0x63,
|
||||
0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x61, 0x72,
|
||||
0x6b, 0x2f, 0x76, 0x31, 0x3b, 0x61, 0x72, 0x6b, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x41, 0x58, 0x58,
|
||||
0xaa, 0x02, 0x06, 0x41, 0x72, 0x6b, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x06, 0x41, 0x72, 0x6b, 0x5c,
|
||||
0x56, 0x31, 0xe2, 0x02, 0x12, 0x41, 0x72, 0x6b, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d,
|
||||
0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x07, 0x41, 0x72, 0x6b, 0x3a, 0x3a, 0x56,
|
||||
0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
|
||||
@@ -39,7 +39,7 @@ func main() {
|
||||
&configCommand,
|
||||
&dumpCommand,
|
||||
&receiveCommand,
|
||||
&claimCmd,
|
||||
&settleCmd,
|
||||
&sendCommand,
|
||||
&balanceCommand,
|
||||
&redeemCommand,
|
||||
@@ -160,11 +160,11 @@ var (
|
||||
return receive(ctx)
|
||||
},
|
||||
}
|
||||
claimCmd = cli.Command{
|
||||
Name: "claim",
|
||||
Usage: "Claim onboarding funds or pending payments",
|
||||
settleCmd = cli.Command{
|
||||
Name: "settle",
|
||||
Usage: "Settle onboarding funds or oor payments",
|
||||
Action: func(ctx *cli.Context) error {
|
||||
return claim(ctx)
|
||||
return settle(ctx)
|
||||
},
|
||||
Flags: []cli.Flag{passwordFlag},
|
||||
}
|
||||
@@ -266,7 +266,7 @@ func receive(ctx *cli.Context) error {
|
||||
})
|
||||
}
|
||||
|
||||
func claim(ctx *cli.Context) error {
|
||||
func settle(ctx *cli.Context) error {
|
||||
password, err := readPassword(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -275,7 +275,7 @@ func claim(ctx *cli.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
txID, err := arkSdkClient.Claim(ctx.Context)
|
||||
txID, err := arkSdkClient.Settle(ctx.Context)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -15,20 +15,17 @@ import (
|
||||
type VtxoScript common.VtxoScript[bitcoinTapTree]
|
||||
|
||||
func ParseVtxoScript(desc string) (VtxoScript, error) {
|
||||
v := &DefaultVtxoScript{}
|
||||
// TODO add other type
|
||||
err := v.FromDescriptor(desc)
|
||||
if err != nil {
|
||||
v := &ReversibleVtxoScript{}
|
||||
err = v.FromDescriptor(desc)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid vtxo descriptor: %s", desc)
|
||||
}
|
||||
|
||||
return v, nil
|
||||
types := []VtxoScript{
|
||||
&DefaultVtxoScript{},
|
||||
}
|
||||
|
||||
return v, nil
|
||||
for _, v := range types {
|
||||
if err := v.FromDescriptor(desc); err == nil {
|
||||
return v, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("invalid vtxo descriptor: %s", desc)
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -101,94 +98,6 @@ func (v *DefaultVtxoScript) TapTree() (*secp256k1.PublicKey, bitcoinTapTree, err
|
||||
return taprootKey, bitcoinTapTree{tapTree}, nil
|
||||
}
|
||||
|
||||
/*
|
||||
* ReversibleVtxoScript allows sender of the VTXO to revert the transaction
|
||||
* unilateral exit is in favor of the sender
|
||||
* - Owner and ASP (forfeit owner)
|
||||
* - Sender and ASP (forfeit sender)
|
||||
* - Sender after t (unilateral exit)
|
||||
*/
|
||||
type ReversibleVtxoScript struct {
|
||||
Asp *secp256k1.PublicKey
|
||||
Sender *secp256k1.PublicKey
|
||||
Owner *secp256k1.PublicKey
|
||||
ExitDelay uint
|
||||
}
|
||||
|
||||
func (v *ReversibleVtxoScript) ToDescriptor() string {
|
||||
owner := hex.EncodeToString(schnorr.SerializePubKey(v.Owner))
|
||||
sender := hex.EncodeToString(schnorr.SerializePubKey(v.Sender))
|
||||
asp := hex.EncodeToString(schnorr.SerializePubKey(v.Asp))
|
||||
|
||||
return fmt.Sprintf(
|
||||
descriptor.ReversibleVtxoScriptTemplate,
|
||||
hex.EncodeToString(UnspendableKey().SerializeCompressed()),
|
||||
sender,
|
||||
asp,
|
||||
v.ExitDelay,
|
||||
sender,
|
||||
owner,
|
||||
asp,
|
||||
)
|
||||
}
|
||||
|
||||
func (v *ReversibleVtxoScript) FromDescriptor(desc string) error {
|
||||
owner, sender, asp, exitDelay, err := descriptor.ParseReversibleVtxoDescriptor(desc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
v.Owner = owner
|
||||
v.Sender = sender
|
||||
v.Asp = asp
|
||||
v.ExitDelay = exitDelay
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *ReversibleVtxoScript) TapTree() (*secp256k1.PublicKey, bitcoinTapTree, error) {
|
||||
redeemClosure := &CSVSigClosure{
|
||||
Pubkey: v.Sender,
|
||||
Seconds: v.ExitDelay,
|
||||
}
|
||||
|
||||
redeemLeaf, err := redeemClosure.Leaf()
|
||||
if err != nil {
|
||||
return nil, bitcoinTapTree{}, err
|
||||
}
|
||||
|
||||
forfeitClosure := &MultisigClosure{
|
||||
Pubkey: v.Owner,
|
||||
AspPubkey: v.Asp,
|
||||
}
|
||||
|
||||
forfeitLeaf, err := forfeitClosure.Leaf()
|
||||
if err != nil {
|
||||
return nil, bitcoinTapTree{}, err
|
||||
}
|
||||
|
||||
reverseForfeitClosure := &MultisigClosure{
|
||||
Pubkey: v.Sender,
|
||||
AspPubkey: v.Asp,
|
||||
}
|
||||
|
||||
reverseForfeitLeaf, err := reverseForfeitClosure.Leaf()
|
||||
if err != nil {
|
||||
return nil, bitcoinTapTree{}, err
|
||||
}
|
||||
|
||||
tapTree := txscript.AssembleTaprootScriptTree(
|
||||
*redeemLeaf, *forfeitLeaf, *reverseForfeitLeaf,
|
||||
)
|
||||
|
||||
root := tapTree.RootNode.TapHash()
|
||||
taprootKey := txscript.ComputeTaprootOutputKey(
|
||||
UnspendableKey(),
|
||||
root[:],
|
||||
)
|
||||
|
||||
return taprootKey, bitcoinTapTree{tapTree}, nil
|
||||
}
|
||||
|
||||
// bitcoinTapTree is a wrapper around txscript.IndexedTapScriptTree to implement the common.TaprootTree interface
|
||||
type bitcoinTapTree struct {
|
||||
*txscript.IndexedTapScriptTree
|
||||
|
||||
@@ -19,12 +19,8 @@ func TestParseDescriptor(t *testing.T) {
|
||||
aliceKey, err := secp256k1.GeneratePrivateKey()
|
||||
require.NoError(t, err)
|
||||
|
||||
bobKey, err := secp256k1.GeneratePrivateKey()
|
||||
require.NoError(t, err)
|
||||
|
||||
aspPubKey := hex.EncodeToString(schnorr.SerializePubKey(aspKey.PubKey()))
|
||||
alicePubKey := hex.EncodeToString(schnorr.SerializePubKey(aliceKey.PubKey()))
|
||||
bobPubKey := hex.EncodeToString(schnorr.SerializePubKey(bobKey.PubKey()))
|
||||
|
||||
unspendableKey := hex.EncodeToString(bitcointree.UnspendableKey().SerializeCompressed())
|
||||
|
||||
@@ -44,24 +40,4 @@ func TestParseDescriptor(t *testing.T) {
|
||||
require.Equal(t, defaultScriptDescriptor, vtxo.ToDescriptor())
|
||||
require.Equal(t, alicePubKey, hex.EncodeToString(schnorr.SerializePubKey(vtxo.(*bitcointree.DefaultVtxoScript).Owner)))
|
||||
require.Equal(t, aspPubKey, hex.EncodeToString(schnorr.SerializePubKey(vtxo.(*bitcointree.DefaultVtxoScript).Asp)))
|
||||
|
||||
reversibleScriptDescriptor := fmt.Sprintf(
|
||||
descriptor.ReversibleVtxoScriptTemplate,
|
||||
unspendableKey,
|
||||
alicePubKey,
|
||||
aspPubKey,
|
||||
512,
|
||||
alicePubKey,
|
||||
bobPubKey,
|
||||
aspPubKey,
|
||||
)
|
||||
|
||||
vtxo, err = bitcointree.ParseVtxoScript(reversibleScriptDescriptor)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.IsType(t, &bitcointree.ReversibleVtxoScript{}, vtxo)
|
||||
require.Equal(t, reversibleScriptDescriptor, vtxo.ToDescriptor())
|
||||
require.Equal(t, alicePubKey, hex.EncodeToString(schnorr.SerializePubKey(vtxo.(*bitcointree.ReversibleVtxoScript).Sender)))
|
||||
require.Equal(t, bobPubKey, hex.EncodeToString(schnorr.SerializePubKey(vtxo.(*bitcointree.ReversibleVtxoScript).Owner)))
|
||||
require.Equal(t, aspPubKey, hex.EncodeToString(schnorr.SerializePubKey(vtxo.(*bitcointree.ReversibleVtxoScript).Asp)))
|
||||
}
|
||||
|
||||
@@ -11,91 +11,6 @@ import (
|
||||
// tr(unspendable, { and(pk(user), pk(asp)), and(older(timeout), pk(user)) })
|
||||
const DefaultVtxoDescriptorTemplate = "tr(%s,{ and(pk(%s), pk(%s)), and(older(%d), pk(%s)) })"
|
||||
|
||||
// tr(unspendable, { { and(pk(sender), pk(asp)), and(older(timeout), pk(sender)) }, and(pk(receiver), pk(asp)) })
|
||||
const ReversibleVtxoScriptTemplate = "tr(%s,{ { and(pk(%s), pk(%s)), and(older(%d), pk(%s)) }, and(pk(%s), pk(%s)) })"
|
||||
|
||||
func ParseReversibleVtxoDescriptor(
|
||||
descriptor string,
|
||||
) (user, sender, asp *secp256k1.PublicKey, timeout uint, err error) {
|
||||
desc, err := ParseTaprootDescriptor(descriptor)
|
||||
if err != nil {
|
||||
return nil, nil, nil, 0, err
|
||||
}
|
||||
|
||||
if len(desc.ScriptTree) != 3 {
|
||||
return nil, nil, nil, 0, errors.New("not a reversible vtxo script descriptor")
|
||||
}
|
||||
|
||||
for _, leaf := range desc.ScriptTree {
|
||||
if andLeaf, ok := leaf.(*And); ok {
|
||||
if first, ok := andLeaf.First.(*PK); ok {
|
||||
if second, ok := andLeaf.Second.(*PK); ok {
|
||||
keyBytes, err := hex.DecodeString(first.Key.Hex)
|
||||
if err != nil {
|
||||
return nil, nil, nil, 0, err
|
||||
}
|
||||
if sender == nil {
|
||||
sender, err = schnorr.ParsePubKey(keyBytes)
|
||||
if err != nil {
|
||||
return nil, nil, nil, 0, err
|
||||
}
|
||||
} else {
|
||||
user, err = schnorr.ParsePubKey(keyBytes)
|
||||
if err != nil {
|
||||
return nil, nil, nil, 0, err
|
||||
}
|
||||
}
|
||||
|
||||
if asp == nil {
|
||||
keyBytes, err = hex.DecodeString(second.Key.Hex)
|
||||
if err != nil {
|
||||
return nil, nil, nil, 0, err
|
||||
}
|
||||
|
||||
asp, err = schnorr.ParsePubKey(keyBytes)
|
||||
if err != nil {
|
||||
return nil, nil, nil, 0, err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if first, ok := andLeaf.First.(*Older); ok {
|
||||
if second, ok := andLeaf.Second.(*PK); ok {
|
||||
timeout = first.Timeout
|
||||
keyBytes, err := hex.DecodeString(second.Key.Hex)
|
||||
if err != nil {
|
||||
return nil, nil, nil, 0, err
|
||||
}
|
||||
|
||||
sender, err = schnorr.ParsePubKey(keyBytes)
|
||||
if err != nil {
|
||||
return nil, nil, nil, 0, err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if user == nil {
|
||||
return nil, nil, nil, 0, errors.New("descriptor is invalid")
|
||||
}
|
||||
|
||||
if asp == nil {
|
||||
return nil, nil, nil, 0, errors.New("descriptor is invalid")
|
||||
}
|
||||
|
||||
if timeout == 0 {
|
||||
return nil, nil, nil, 0, errors.New("descriptor is invalid")
|
||||
}
|
||||
|
||||
if sender == nil {
|
||||
return nil, nil, nil, 0, errors.New("descriptor is invalid")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func ParseDefaultVtxoDescriptor(
|
||||
descriptor string,
|
||||
) (user, asp *secp256k1.PublicKey, timeout uint, err error) {
|
||||
|
||||
@@ -25,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)
|
||||
Claim(ctx context.Context) (string, error)
|
||||
Settle(ctx context.Context) (string, error)
|
||||
ListVtxos(ctx context.Context) (spendable, spent []client.Vtxo, err error)
|
||||
Dump(ctx context.Context) (seed string, err error)
|
||||
GetTransactionHistory(ctx context.Context) ([]types.Transaction, error)
|
||||
|
||||
@@ -270,6 +270,27 @@ func (a *arkClient) ping(
|
||||
return ticker.Stop
|
||||
}
|
||||
|
||||
func (a *arkClient) ListVtxos(
|
||||
ctx context.Context,
|
||||
) (spendableVtxos, spentVtxos []client.Vtxo, err error) {
|
||||
offchainAddrs, _, _, err := a.wallet.GetAddresses(ctx)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for _, addr := range offchainAddrs {
|
||||
spendable, spent, err := a.client.ListVtxos(ctx, addr.Address)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
spendableVtxos = append(spendableVtxos, spendable...)
|
||||
spentVtxos = append(spentVtxos, spent...)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func getClient(
|
||||
supportedClients utils.SupportedType[utils.ClientFactory], clientType, aspUrl string,
|
||||
) (client.ASPClient, error) {
|
||||
@@ -329,3 +350,15 @@ func getWalletStore(storeType, datadir string) (walletstore.WalletStore, error)
|
||||
func getCreatedAtFromExpiry(roundLifetime int64, expiry time.Time) time.Time {
|
||||
return expiry.Add(-time.Duration(roundLifetime) * time.Second)
|
||||
}
|
||||
|
||||
func filterByOutpoints(vtxos []client.Vtxo, outpoints []client.Outpoint) []client.Vtxo {
|
||||
filtered := make([]client.Vtxo, 0, len(vtxos))
|
||||
for _, vtxo := range vtxos {
|
||||
for _, outpoint := range outpoints {
|
||||
if vtxo.Outpoint.Equals(outpoint) {
|
||||
filtered = append(filtered, vtxo)
|
||||
}
|
||||
}
|
||||
}
|
||||
return filtered
|
||||
}
|
||||
|
||||
@@ -78,6 +78,10 @@ type Outpoint struct {
|
||||
VOut uint32
|
||||
}
|
||||
|
||||
func (o Outpoint) Equals(other Outpoint) bool {
|
||||
return o.Txid == other.Txid && o.VOut == other.VOut
|
||||
}
|
||||
|
||||
type Input struct {
|
||||
Outpoint
|
||||
Descriptor string
|
||||
@@ -95,7 +99,7 @@ type Vtxo struct {
|
||||
RoundTxid string
|
||||
ExpiresAt *time.Time
|
||||
RedeemTx string
|
||||
Pending bool
|
||||
IsOOR bool
|
||||
SpentBy string
|
||||
}
|
||||
|
||||
|
||||
@@ -359,7 +359,7 @@ func (c *grpcClient) GetTransactionsStream(
|
||||
Round: &client.RoundTransaction{
|
||||
Txid: tx.Round.Txid,
|
||||
SpentVtxos: outpointsFromProto(tx.Round.SpentVtxos),
|
||||
SpendableVtxos: vtxosFromProto(tx.Round.SpendableVtxos),
|
||||
SpendableVtxos: vtxos(tx.Round.SpendableVtxos).toVtxos(),
|
||||
ClaimedBoardingUtxos: outpointsFromProto(tx.Round.ClaimedBoardingUtxos),
|
||||
},
|
||||
}
|
||||
@@ -368,7 +368,7 @@ func (c *grpcClient) GetTransactionsStream(
|
||||
Redeem: &client.RedeemTransaction{
|
||||
Txid: tx.Redeem.Txid,
|
||||
SpentVtxos: outpointsFromProto(tx.Redeem.SpentVtxos),
|
||||
SpendableVtxos: vtxosFromProto(tx.Redeem.SpendableVtxos),
|
||||
SpendableVtxos: vtxos(tx.Redeem.SpendableVtxos).toVtxos(),
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -394,24 +394,3 @@ func outpointsFromProto(protoOutpoints []*arkv1.Outpoint) []client.Outpoint {
|
||||
}
|
||||
return outpoints
|
||||
}
|
||||
|
||||
func vtxosFromProto(protoVtxos []*arkv1.Vtxo) []client.Vtxo {
|
||||
vtxos := make([]client.Vtxo, len(protoVtxos))
|
||||
for i, v := range protoVtxos {
|
||||
expiresAt := time.Unix(v.ExpireAt, 0)
|
||||
vtxos[i] = client.Vtxo{
|
||||
Outpoint: client.Outpoint{
|
||||
Txid: v.Outpoint.Txid,
|
||||
VOut: v.Outpoint.Vout,
|
||||
},
|
||||
Pubkey: v.Pubkey,
|
||||
Amount: v.Amount,
|
||||
RoundTxid: v.RoundTxid,
|
||||
ExpiresAt: &expiresAt,
|
||||
RedeemTx: v.RedeemTx,
|
||||
Pending: v.Pending,
|
||||
SpentBy: v.SpentBy,
|
||||
}
|
||||
}
|
||||
return vtxos
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ func (v vtxo) toVtxo() client.Vtxo {
|
||||
Amount: v.GetAmount(),
|
||||
RoundTxid: v.GetRoundTxid(),
|
||||
ExpiresAt: expiresAt,
|
||||
Pending: v.GetPending(),
|
||||
IsOOR: v.GetIsOor(),
|
||||
RedeemTx: v.GetRedeemTx(),
|
||||
SpentBy: v.GetSpentBy(),
|
||||
Pubkey: v.GetPubkey(),
|
||||
|
||||
@@ -499,7 +499,7 @@ func (a *restClient) ListVtxos(
|
||||
Amount: uint64(amount),
|
||||
RoundTxid: v.RoundTxid,
|
||||
ExpiresAt: expiresAt,
|
||||
Pending: v.Pending,
|
||||
IsOOR: v.IsOor,
|
||||
RedeemTx: v.RedeemTx,
|
||||
SpentBy: v.SpentBy,
|
||||
Pubkey: v.Pubkey,
|
||||
@@ -701,7 +701,7 @@ func vtxosFromRest(restVtxos []*models.V1Vtxo) []client.Vtxo {
|
||||
RoundTxid: v.RoundTxid,
|
||||
ExpiresAt: expiresAt,
|
||||
RedeemTx: v.RedeemTx,
|
||||
Pending: v.Pending,
|
||||
IsOOR: v.IsOor,
|
||||
SpentBy: v.SpentBy,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,12 +24,12 @@ type V1Vtxo struct {
|
||||
// expire at
|
||||
ExpireAt string `json:"expireAt,omitempty"`
|
||||
|
||||
// is oor
|
||||
IsOor bool `json:"isOor,omitempty"`
|
||||
|
||||
// outpoint
|
||||
Outpoint *V1Outpoint `json:"outpoint,omitempty"`
|
||||
|
||||
// pending
|
||||
Pending bool `json:"pending,omitempty"`
|
||||
|
||||
// pubkey
|
||||
Pubkey string `json:"pubkey,omitempty"`
|
||||
|
||||
|
||||
@@ -33,7 +33,6 @@ func TestVtxosToTxs(t *testing.T) {
|
||||
},
|
||||
Amount: 1000,
|
||||
Type: sdktypes.TxSent,
|
||||
IsPending: false,
|
||||
CreatedAt: time.Unix(1726054898, 0),
|
||||
},
|
||||
},
|
||||
@@ -48,7 +47,6 @@ func TestVtxosToTxs(t *testing.T) {
|
||||
},
|
||||
Amount: 1000,
|
||||
Type: sdktypes.TxReceived,
|
||||
IsPending: true,
|
||||
CreatedAt: time.Unix(1726054898, 0),
|
||||
},
|
||||
{
|
||||
@@ -57,7 +55,6 @@ func TestVtxosToTxs(t *testing.T) {
|
||||
},
|
||||
Amount: 2000,
|
||||
Type: sdktypes.TxReceived,
|
||||
IsPending: true,
|
||||
CreatedAt: time.Unix(1726486359, 0),
|
||||
},
|
||||
},
|
||||
@@ -72,7 +69,6 @@ func TestVtxosToTxs(t *testing.T) {
|
||||
},
|
||||
Amount: 1000,
|
||||
Type: sdktypes.TxReceived,
|
||||
IsPending: false,
|
||||
CreatedAt: time.Unix(1726054898, 0),
|
||||
},
|
||||
{
|
||||
@@ -81,7 +77,6 @@ func TestVtxosToTxs(t *testing.T) {
|
||||
},
|
||||
Amount: 2000,
|
||||
Type: sdktypes.TxReceived,
|
||||
IsPending: false,
|
||||
CreatedAt: time.Unix(1726486359, 0),
|
||||
},
|
||||
},
|
||||
@@ -96,7 +91,6 @@ func TestVtxosToTxs(t *testing.T) {
|
||||
},
|
||||
Amount: 1000,
|
||||
Type: sdktypes.TxReceived,
|
||||
IsPending: false,
|
||||
CreatedAt: time.Unix(1726054898, 0),
|
||||
},
|
||||
{
|
||||
@@ -105,7 +99,6 @@ func TestVtxosToTxs(t *testing.T) {
|
||||
},
|
||||
Amount: 2000,
|
||||
Type: sdktypes.TxReceived,
|
||||
IsPending: false,
|
||||
CreatedAt: time.Unix(1726486359, 0),
|
||||
},
|
||||
{
|
||||
@@ -114,7 +107,6 @@ func TestVtxosToTxs(t *testing.T) {
|
||||
},
|
||||
Amount: 2100,
|
||||
Type: sdktypes.TxSent,
|
||||
IsPending: false,
|
||||
CreatedAt: time.Unix(1726503865, 0),
|
||||
},
|
||||
},
|
||||
@@ -138,7 +130,6 @@ func TestVtxosToTxs(t *testing.T) {
|
||||
require.Equal(t, wantTx.RedeemTxid, gotTx.RedeemTxid)
|
||||
require.Equal(t, int(wantTx.Amount), int(gotTx.Amount))
|
||||
require.Equal(t, wantTx.Type, gotTx.Type)
|
||||
require.Equal(t, wantTx.IsPending, gotTx.IsPending)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -161,16 +152,12 @@ func loadFixtures(jsonStr string) (vtxos, map[string]struct{}, error) {
|
||||
Address string `json:"address"`
|
||||
Amount string `json:"amount"`
|
||||
} `json:"receiver"`
|
||||
Spent bool `json:"spent"`
|
||||
PoolTxid string `json:"poolTxid"`
|
||||
SpentBy string `json:"spentBy"`
|
||||
ExpireAt string `json:"expireAt"`
|
||||
Swept bool `json:"swept"`
|
||||
Pending bool `json:"pending"`
|
||||
PendingData struct {
|
||||
RedeemTx string `json:"redeemTx"`
|
||||
UnconditionalForfeitTxs []string `json:"unconditionalForfeitTxs"`
|
||||
} `json:"pendingData"`
|
||||
Spent bool `json:"spent"`
|
||||
PoolTxid string `json:"poolTxid"`
|
||||
SpentBy string `json:"spentBy"`
|
||||
ExpireAt string `json:"expireAt"`
|
||||
Swept bool `json:"swept"`
|
||||
RedeemTx string `json:"redeemTx"`
|
||||
} `json:"spendableVtxos"`
|
||||
SpentVtxos []struct {
|
||||
Outpoint struct {
|
||||
@@ -181,16 +168,12 @@ func loadFixtures(jsonStr string) (vtxos, map[string]struct{}, error) {
|
||||
Address string `json:"address"`
|
||||
Amount string `json:"amount"`
|
||||
} `json:"receiver"`
|
||||
Spent bool `json:"spent"`
|
||||
PoolTxid string `json:"poolTxid"`
|
||||
SpentBy string `json:"spentBy"`
|
||||
ExpireAt string `json:"expireAt"`
|
||||
Swept bool `json:"swept"`
|
||||
Pending bool `json:"pending"`
|
||||
PendingData struct {
|
||||
RedeemTx string `json:"redeemTx"`
|
||||
UnconditionalForfeitTxs []string `json:"unconditionalForfeitTxs"`
|
||||
} `json:"pendingData"`
|
||||
Spent bool `json:"spent"`
|
||||
PoolTxid string `json:"poolTxid"`
|
||||
SpentBy string `json:"spentBy"`
|
||||
ExpireAt string `json:"expireAt"`
|
||||
Swept bool `json:"swept"`
|
||||
RedeemTx string `json:"redeemTx"`
|
||||
} `json:"spentVtxos"`
|
||||
}
|
||||
|
||||
@@ -216,8 +199,7 @@ func loadFixtures(jsonStr string) (vtxos, map[string]struct{}, error) {
|
||||
Amount: amount,
|
||||
RoundTxid: vtxo.PoolTxid,
|
||||
ExpiresAt: &expireAt,
|
||||
RedeemTx: vtxo.PendingData.RedeemTx,
|
||||
Pending: vtxo.Pending,
|
||||
RedeemTx: vtxo.RedeemTx,
|
||||
SpentBy: vtxo.SpentBy,
|
||||
}
|
||||
}
|
||||
@@ -240,8 +222,7 @@ func loadFixtures(jsonStr string) (vtxos, map[string]struct{}, error) {
|
||||
Amount: amount,
|
||||
RoundTxid: vtxo.PoolTxid,
|
||||
ExpiresAt: &expireAt,
|
||||
RedeemTx: vtxo.PendingData.RedeemTx,
|
||||
Pending: vtxo.Pending,
|
||||
RedeemTx: vtxo.RedeemTx,
|
||||
SpentBy: vtxo.SpentBy,
|
||||
}
|
||||
}
|
||||
@@ -301,9 +282,7 @@ var (
|
||||
"poolTxid": "377fa2fbd27c82bdbc095478384c88b6c75432c0ef464189e49c965194446cdf",
|
||||
"spentBy": "",
|
||||
"expireAt": "1726054928",
|
||||
"swept": false,
|
||||
"pending": false,
|
||||
"pendingData": null
|
||||
"swept": false
|
||||
}
|
||||
],
|
||||
"spentVtxos": []
|
||||
@@ -329,13 +308,7 @@ var (
|
||||
"spentBy": "",
|
||||
"expireAt": "1726054928",
|
||||
"swept": false,
|
||||
"pending": false,
|
||||
"pendingData": {
|
||||
"redeemTx": "cHNidP8BAIkCAAAAAWwxXUjG5tidFA0LmUljX//jwW6xWaS6HKyRCw5StsxpAAAAAAD/////AugDAAAAAAAAIlEgt2eR8LtqTP7yUcQtSydeGrRiHnVmHHnZwYjdC23G7MZwSQAAAAAAACJRIKfUzf/o9h+r0v9y4nmyOt9qO8EkDumQPQZGTbEv8fSFAAAAAAABASsgTgAAAAAAACJRIKfUzf/o9h+r0v9y4nmyOt9qO8EkDumQPQZGTbEv8fSFIgYDp9sz9Cto7FhF+C929Y/jJw1zkRWxq6NURd9kX05mShcYAAAAAFYAAIAAAACAAQAAgAAAAAAAAAAAQRSvBIBey3T0IV353FkuGLMmMJFpqHTrliIsJwJsfJkzq7J0B8bQ0j9842h5lUfOWcbj2TeoFx6OCpgoHIqWIBhHQAFqkBLiRmP3AZ8MS77s1QIWZswMV3L72D9gN0f0MbD6XHkmzZeC1clF3uzxr+13wsF0vcFe29Zl3e2gAhMNGYVCFcFQkpt0waBJVLeLS2A16XpeB4paDyjsltVHv+6azoA6wKRtST8P7teUpSF4DAEbfJj5OIXITx5QGbZns/AtxqGyRSCn2zP0K2jsWEX4L3b1j+MnDXORFbGro1RF32RfTmZKF60grwSAXst09CFd+dxZLhizJjCRaah065YiLCcCbHyZM6uswCEWp9sz9Cto7FhF+C929Y/jJw1zkRWxq6NURd9kX05mShc5AbJ0B8bQ0j9842h5lUfOWcbj2TeoFx6OCpgoHIqWIBhHAAAAAFYAAIAAAACAAQAAgAAAAAAAAAAAARcgUJKbdMGgSVS3i0tgNel6XgeKWg8o7JbVR7/ums6AOsAAAAA=",
|
||||
"unconditionalForfeitTxs": [
|
||||
"cHNidP8BAFICAAAAAWwxXUjG5tidFA0LmUljX//jwW6xWaS6HKyRCw5StsxpAAAAAAD/////AVhNAAAAAAAAFgAUSU38/3Mzx5BdILG4oUO+JoHcoT8AAAAAAAEBKyBOAAAAAAAAIlEgp9TN/+j2H6vS/3LiebI632o7wSQO6ZA9BkZNsS/x9IVBFK8EgF7LdPQhXfncWS4YsyYwkWmodOuWIiwnAmx8mTOrsnQHxtDSP3zjaHmVR85ZxuPZN6gXHo4KmCgcipYgGEdAjH8Mg1Z3GdjGzp78Mg2xq1fop9KDfeji+xoyMgYS7q0Nl0AGOAaNzkDRW4cNcefll5jZC2i3nfygKdXsUsR+LEIVwVCSm3TBoElUt4tLYDXpel4HiloPKOyW1Ue/7prOgDrApG1JPw/u15SlIXgMARt8mPk4hchPHlAZtmez8C3GobJFIKfbM/QraOxYRfgvdvWP4ycNc5EVsaujVEXfZF9OZkoXrSCvBIBey3T0IV353FkuGLMmMJFpqHTrliIsJwJsfJkzq6zAARcgUJKbdMGgSVS3i0tgNel6XgeKWg8o7JbVR7/ums6AOsAAAA=="
|
||||
]
|
||||
}
|
||||
"redeemTx": "cHNidP8BAIkCAAAAAWwxXUjG5tidFA0LmUljX//jwW6xWaS6HKyRCw5StsxpAAAAAAD/////AugDAAAAAAAAIlEgt2eR8LtqTP7yUcQtSydeGrRiHnVmHHnZwYjdC23G7MZwSQAAAAAAACJRIKfUzf/o9h+r0v9y4nmyOt9qO8EkDumQPQZGTbEv8fSFAAAAAAABASsgTgAAAAAAACJRIKfUzf/o9h+r0v9y4nmyOt9qO8EkDumQPQZGTbEv8fSFIgYDp9sz9Cto7FhF+C929Y/jJw1zkRWxq6NURd9kX05mShcYAAAAAFYAAIAAAACAAQAAgAAAAAAAAAAAQRSvBIBey3T0IV353FkuGLMmMJFpqHTrliIsJwJsfJkzq7J0B8bQ0j9842h5lUfOWcbj2TeoFx6OCpgoHIqWIBhHQAFqkBLiRmP3AZ8MS77s1QIWZswMV3L72D9gN0f0MbD6XHkmzZeC1clF3uzxr+13wsF0vcFe29Zl3e2gAhMNGYVCFcFQkpt0waBJVLeLS2A16XpeB4paDyjsltVHv+6azoA6wKRtST8P7teUpSF4DAEbfJj5OIXITx5QGbZns/AtxqGyRSCn2zP0K2jsWEX4L3b1j+MnDXORFbGro1RF32RfTmZKF60grwSAXst09CFd+dxZLhizJjCRaah065YiLCcCbHyZM6uswCEWp9sz9Cto7FhF+C929Y/jJw1zkRWxq6NURd9kX05mShc5AbJ0B8bQ0j9842h5lUfOWcbj2TeoFx6OCpgoHIqWIBhHAAAAAFYAAIAAAACAAQAAgAAAAAAAAAAAARcgUJKbdMGgSVS3i0tgNel6XgeKWg8o7JbVR7/ums6AOsAAAAA="
|
||||
}
|
||||
],
|
||||
"spentVtxos": [
|
||||
@@ -353,8 +326,7 @@ var (
|
||||
"spentBy": "94fa598302f17f00c8881e742ec0ce2f8c8d16f3d54fe6ba0fb7d13a493d84ad",
|
||||
"expireAt": "1726054928",
|
||||
"swept": false,
|
||||
"pending": false,
|
||||
"pendingData": null
|
||||
"redeemTx": ""
|
||||
}
|
||||
]
|
||||
}`
|
||||
@@ -376,13 +348,7 @@ var (
|
||||
"spentBy": "",
|
||||
"expireAt": "1726054928",
|
||||
"swept": false,
|
||||
"pending": true,
|
||||
"pendingData": {
|
||||
"redeemTx": "cHNidP8BAIkCAAAAAWwxXUjG5tidFA0LmUljX//jwW6xWaS6HKyRCw5StsxpAAAAAAD/////AugDAAAAAAAAIlEgt2eR8LtqTP7yUcQtSydeGrRiHnVmHHnZwYjdC23G7MZwSQAAAAAAACJRIKfUzf/o9h+r0v9y4nmyOt9qO8EkDumQPQZGTbEv8fSFAAAAAAABASsgTgAAAAAAACJRIKfUzf/o9h+r0v9y4nmyOt9qO8EkDumQPQZGTbEv8fSFIgYDp9sz9Cto7FhF+C929Y/jJw1zkRWxq6NURd9kX05mShcYAAAAAFYAAIAAAACAAQAAgAAAAAAAAAAAQRSvBIBey3T0IV353FkuGLMmMJFpqHTrliIsJwJsfJkzq7J0B8bQ0j9842h5lUfOWcbj2TeoFx6OCpgoHIqWIBhHQAFqkBLiRmP3AZ8MS77s1QIWZswMV3L72D9gN0f0MbD6XHkmzZeC1clF3uzxr+13wsF0vcFe29Zl3e2gAhMNGYVCFcFQkpt0waBJVLeLS2A16XpeB4paDyjsltVHv+6azoA6wKRtST8P7teUpSF4DAEbfJj5OIXITx5QGbZns/AtxqGyRSCn2zP0K2jsWEX4L3b1j+MnDXORFbGro1RF32RfTmZKF60grwSAXst09CFd+dxZLhizJjCRaah065YiLCcCbHyZM6uswCEWp9sz9Cto7FhF+C929Y/jJw1zkRWxq6NURd9kX05mShc5AbJ0B8bQ0j9842h5lUfOWcbj2TeoFx6OCpgoHIqWIBhHAAAAAFYAAIAAAACAAQAAgAAAAAAAAAAAARcgUJKbdMGgSVS3i0tgNel6XgeKWg8o7JbVR7/ums6AOsAAAAA=",
|
||||
"unconditionalForfeitTxs": [
|
||||
"cHNidP8BAFICAAAAAWwxXUjG5tidFA0LmUljX//jwW6xWaS6HKyRCw5StsxpAAAAAAD/////AVhNAAAAAAAAFgAUSU38/3Mzx5BdILG4oUO+JoHcoT8AAAAAAAEBKyBOAAAAAAAAIlEgp9TN/+j2H6vS/3LiebI632o7wSQO6ZA9BkZNsS/x9IVBFK8EgF7LdPQhXfncWS4YsyYwkWmodOuWIiwnAmx8mTOrsnQHxtDSP3zjaHmVR85ZxuPZN6gXHo4KmCgcipYgGEdAjH8Mg1Z3GdjGzp78Mg2xq1fop9KDfeji+xoyMgYS7q0Nl0AGOAaNzkDRW4cNcefll5jZC2i3nfygKdXsUsR+LEIVwVCSm3TBoElUt4tLYDXpel4HiloPKOyW1Ue/7prOgDrApG1JPw/u15SlIXgMARt8mPk4hchPHlAZtmez8C3GobJFIKfbM/QraOxYRfgvdvWP4ycNc5EVsaujVEXfZF9OZkoXrSCvBIBey3T0IV353FkuGLMmMJFpqHTrliIsJwJsfJkzq6zAARcgUJKbdMGgSVS3i0tgNel6XgeKWg8o7JbVR7/ums6AOsAAAA=="
|
||||
]
|
||||
}
|
||||
"redeemTx": "cHNidP8BAIkCAAAAAWwxXUjG5tidFA0LmUljX//jwW6xWaS6HKyRCw5StsxpAAAAAAD/////AugDAAAAAAAAIlEgt2eR8LtqTP7yUcQtSydeGrRiHnVmHHnZwYjdC23G7MZwSQAAAAAAACJRIKfUzf/o9h+r0v9y4nmyOt9qO8EkDumQPQZGTbEv8fSFAAAAAAABASsgTgAAAAAAACJRIKfUzf/o9h+r0v9y4nmyOt9qO8EkDumQPQZGTbEv8fSFIgYDp9sz9Cto7FhF+C929Y/jJw1zkRWxq6NURd9kX05mShcYAAAAAFYAAIAAAACAAQAAgAAAAAAAAAAAQRSvBIBey3T0IV353FkuGLMmMJFpqHTrliIsJwJsfJkzq7J0B8bQ0j9842h5lUfOWcbj2TeoFx6OCpgoHIqWIBhHQAFqkBLiRmP3AZ8MS77s1QIWZswMV3L72D9gN0f0MbD6XHkmzZeC1clF3uzxr+13wsF0vcFe29Zl3e2gAhMNGYVCFcFQkpt0waBJVLeLS2A16XpeB4paDyjsltVHv+6azoA6wKRtST8P7teUpSF4DAEbfJj5OIXITx5QGbZns/AtxqGyRSCn2zP0K2jsWEX4L3b1j+MnDXORFbGro1RF32RfTmZKF60grwSAXst09CFd+dxZLhizJjCRaah065YiLCcCbHyZM6uswCEWp9sz9Cto7FhF+C929Y/jJw1zkRWxq6NURd9kX05mShc5AbJ0B8bQ0j9842h5lUfOWcbj2TeoFx6OCpgoHIqWIBhHAAAAAFYAAIAAAACAAQAAgAAAAAAAAAAAARcgUJKbdMGgSVS3i0tgNel6XgeKWg8o7JbVR7/ums6AOsAAAAA="
|
||||
},
|
||||
{
|
||||
"outpoint": {
|
||||
@@ -398,13 +364,7 @@ var (
|
||||
"spentBy": "",
|
||||
"expireAt": "1726486389",
|
||||
"swept": false,
|
||||
"pending": true,
|
||||
"pendingData": {
|
||||
"redeemTx": "cHNidP8BAIkCAAAAARH6LJRGP/pFIkD/o5bBp8fXAhjl8yjfN7MhJsxdt5lrAQAAAAD/////AtAHAAAAAAAAIlEguuBh3KQUVZp+NHV2sixQ/mrsngCuLCGXzsgJPC1FzY7ANQ8AAAAAACJRIP7uXXtl4jLUcVVQU+sX7WFXmx2H6iCMzn7gye0v1Y8JAAAAAAABAStYPg8AAAAAACJRIP7uXXtl4jLUcVVQU+sX7WFXmx2H6iCMzn7gye0v1Y8JIgYCHVQFdXiyvwIlLdnji8FvbUgb+ECuTRNAB67owJnjcaMYAAAAAFYAAIAAAACAAQAAgAAAAAAAAAAAQRSc1yjQ/vHRHev23fKGANLvbOhkNYmGtmRWt8fSszlOJUzRFbnfxd1fq9gIEpaI0vrZww8tlZ94iEL75QoaIbVqQJsPdLYf7fAoXO82VoqwYHu1WevE4g6LxUGBPzfd96q5EEZkoW5qqg+v5dWJUEY467Q6qZLFHwziUaB3KEY8yEpCFcBQkpt0waBJVLeLS2A16XpeB4paDyjsltVHv+6azoA6wO5D2Mh3x0XNGxFCS67GNughkENFodpFeVpZjn76chI8RSAdVAV1eLK/AiUt2eOLwW9tSBv4QK5NE0AHrujAmeNxo60gnNco0P7x0R3r9t3yhgDS72zoZDWJhrZkVrfH0rM5TiWswCEWHVQFdXiyvwIlLdnji8FvbUgb+ECuTRNAB67owJnjcaM5AUzRFbnfxd1fq9gIEpaI0vrZww8tlZ94iEL75QoaIbVqAAAAAFYAAIAAAACAAQAAgAAAAAAAAAAAARcgUJKbdMGgSVS3i0tgNel6XgeKWg8o7JbVR7/ums6AOsAAAAA=",
|
||||
"unconditionalForfeitTxs": [
|
||||
"cHNidP8BAFICAAAAARH6LJRGP/pFIkD/o5bBp8fXAhjl8yjfN7MhJsxdt5lrAQAAAAD/////AZA9DwAAAAAAFgAU+9NJhjFhe8jX1hrXh3NvDyHZ1cYAAAAAAAEBK1g+DwAAAAAAIlEg/u5de2XiMtRxVVBT6xftYVebHYfqIIzOfuDJ7S/VjwlBFJzXKND+8dEd6/bd8oYA0u9s6GQ1iYa2ZFa3x9KzOU4lTNEVud/F3V+r2AgSlojS+tnDDy2Vn3iIQvvlChohtWpARJzBjlEkN/kTpyFEtpvP2Ui7ypevuxb9J/NUAwhYf8Pmnnj1l3WuKCSi4Fcp1O+lQjIiZlNpwY6J73q/V8Fe2kIVwFCSm3TBoElUt4tLYDXpel4HiloPKOyW1Ue/7prOgDrA7kPYyHfHRc0bEUJLrsY26CGQQ0Wh2kV5WlmOfvpyEjxFIB1UBXV4sr8CJS3Z44vBb21IG/hArk0TQAeu6MCZ43GjrSCc1yjQ/vHRHev23fKGANLvbOhkNYmGtmRWt8fSszlOJazAARcgUJKbdMGgSVS3i0tgNel6XgeKWg8o7JbVR7/ums6AOsAAAA=="
|
||||
]
|
||||
}
|
||||
"redeemTx": "cHNidP8BAIkCAAAAARH6LJRGP/pFIkD/o5bBp8fXAhjl8yjfN7MhJsxdt5lrAQAAAAD/////AtAHAAAAAAAAIlEguuBh3KQUVZp+NHV2sixQ/mrsngCuLCGXzsgJPC1FzY7ANQ8AAAAAACJRIP7uXXtl4jLUcVVQU+sX7WFXmx2H6iCMzn7gye0v1Y8JAAAAAAABAStYPg8AAAAAACJRIP7uXXtl4jLUcVVQU+sX7WFXmx2H6iCMzn7gye0v1Y8JIgYCHVQFdXiyvwIlLdnji8FvbUgb+ECuTRNAB67owJnjcaMYAAAAAFYAAIAAAACAAQAAgAAAAAAAAAAAQRSc1yjQ/vHRHev23fKGANLvbOhkNYmGtmRWt8fSszlOJUzRFbnfxd1fq9gIEpaI0vrZww8tlZ94iEL75QoaIbVqQJsPdLYf7fAoXO82VoqwYHu1WevE4g6LxUGBPzfd96q5EEZkoW5qqg+v5dWJUEY467Q6qZLFHwziUaB3KEY8yEpCFcBQkpt0waBJVLeLS2A16XpeB4paDyjsltVHv+6azoA6wO5D2Mh3x0XNGxFCS67GNughkENFodpFeVpZjn76chI8RSAdVAV1eLK/AiUt2eOLwW9tSBv4QK5NE0AHrujAmeNxo60gnNco0P7x0R3r9t3yhgDS72zoZDWJhrZkVrfH0rM5TiWswCEWHVQFdXiyvwIlLdnji8FvbUgb+ECuTRNAB67owJnjcaM5AUzRFbnfxd1fq9gIEpaI0vrZww8tlZ94iEL75QoaIbVqAAAAAFYAAIAAAACAAQAAgAAAAAAAAAAAARcgUJKbdMGgSVS3i0tgNel6XgeKWg8o7JbVR7/ums6AOsAAAAA="
|
||||
}
|
||||
],
|
||||
"spentVtxos": []
|
||||
@@ -426,8 +386,7 @@ var (
|
||||
"spentBy": "",
|
||||
"expireAt": "1726503895",
|
||||
"swept": false,
|
||||
"pending": false,
|
||||
"pendingData": null
|
||||
"redeemTx": ""
|
||||
}
|
||||
],
|
||||
"spentVtxos": [
|
||||
@@ -445,13 +404,7 @@ var (
|
||||
"spentBy": "d6684a5b9e6939dccdf07d1f0eaf7fdd7b31de4d123e63e400d23de739800d4e",
|
||||
"expireAt": "1726054928",
|
||||
"swept": false,
|
||||
"pending": true,
|
||||
"pendingData": {
|
||||
"redeemTx": "cHNidP8BAIkCAAAAAWwxXUjG5tidFA0LmUljX//jwW6xWaS6HKyRCw5StsxpAAAAAAD/////AugDAAAAAAAAIlEgt2eR8LtqTP7yUcQtSydeGrRiHnVmHHnZwYjdC23G7MZwSQAAAAAAACJRIKfUzf/o9h+r0v9y4nmyOt9qO8EkDumQPQZGTbEv8fSFAAAAAAABASsgTgAAAAAAACJRIKfUzf/o9h+r0v9y4nmyOt9qO8EkDumQPQZGTbEv8fSFIgYDp9sz9Cto7FhF+C929Y/jJw1zkRWxq6NURd9kX05mShcYAAAAAFYAAIAAAACAAQAAgAAAAAAAAAAAQRSvBIBey3T0IV353FkuGLMmMJFpqHTrliIsJwJsfJkzq7J0B8bQ0j9842h5lUfOWcbj2TeoFx6OCpgoHIqWIBhHQAFqkBLiRmP3AZ8MS77s1QIWZswMV3L72D9gN0f0MbD6XHkmzZeC1clF3uzxr+13wsF0vcFe29Zl3e2gAhMNGYVCFcFQkpt0waBJVLeLS2A16XpeB4paDyjsltVHv+6azoA6wKRtST8P7teUpSF4DAEbfJj5OIXITx5QGbZns/AtxqGyRSCn2zP0K2jsWEX4L3b1j+MnDXORFbGro1RF32RfTmZKF60grwSAXst09CFd+dxZLhizJjCRaah065YiLCcCbHyZM6uswCEWp9sz9Cto7FhF+C929Y/jJw1zkRWxq6NURd9kX05mShc5AbJ0B8bQ0j9842h5lUfOWcbj2TeoFx6OCpgoHIqWIBhHAAAAAFYAAIAAAACAAQAAgAAAAAAAAAAAARcgUJKbdMGgSVS3i0tgNel6XgeKWg8o7JbVR7/ums6AOsAAAAA=",
|
||||
"unconditionalForfeitTxs": [
|
||||
"cHNidP8BAFICAAAAAWwxXUjG5tidFA0LmUljX//jwW6xWaS6HKyRCw5StsxpAAAAAAD/////AVhNAAAAAAAAFgAUSU38/3Mzx5BdILG4oUO+JoHcoT8AAAAAAAEBKyBOAAAAAAAAIlEgp9TN/+j2H6vS/3LiebI632o7wSQO6ZA9BkZNsS/x9IVBFK8EgF7LdPQhXfncWS4YsyYwkWmodOuWIiwnAmx8mTOrsnQHxtDSP3zjaHmVR85ZxuPZN6gXHo4KmCgcipYgGEdAjH8Mg1Z3GdjGzp78Mg2xq1fop9KDfeji+xoyMgYS7q0Nl0AGOAaNzkDRW4cNcefll5jZC2i3nfygKdXsUsR+LEIVwVCSm3TBoElUt4tLYDXpel4HiloPKOyW1Ue/7prOgDrApG1JPw/u15SlIXgMARt8mPk4hchPHlAZtmez8C3GobJFIKfbM/QraOxYRfgvdvWP4ycNc5EVsaujVEXfZF9OZkoXrSCvBIBey3T0IV353FkuGLMmMJFpqHTrliIsJwJsfJkzq6zAARcgUJKbdMGgSVS3i0tgNel6XgeKWg8o7JbVR7/ums6AOsAAAA=="
|
||||
]
|
||||
}
|
||||
"redeemTx": "cHNidP8BAIkCAAAAAWwxXUjG5tidFA0LmUljX//jwW6xWaS6HKyRCw5StsxpAAAAAAD/////AugDAAAAAAAAIlEgt2eR8LtqTP7yUcQtSydeGrRiHnVmHHnZwYjdC23G7MZwSQAAAAAAACJRIKfUzf/o9h+r0v9y4nmyOt9qO8EkDumQPQZGTbEv8fSFAAAAAAABASsgTgAAAAAAACJRIKfUzf/o9h+r0v9y4nmyOt9qO8EkDumQPQZGTbEv8fSFIgYDp9sz9Cto7FhF+C929Y/jJw1zkRWxq6NURd9kX05mShcYAAAAAFYAAIAAAACAAQAAgAAAAAAAAAAAQRSvBIBey3T0IV353FkuGLMmMJFpqHTrliIsJwJsfJkzq7J0B8bQ0j9842h5lUfOWcbj2TeoFx6OCpgoHIqWIBhHQAFqkBLiRmP3AZ8MS77s1QIWZswMV3L72D9gN0f0MbD6XHkmzZeC1clF3uzxr+13wsF0vcFe29Zl3e2gAhMNGYVCFcFQkpt0waBJVLeLS2A16XpeB4paDyjsltVHv+6azoA6wKRtST8P7teUpSF4DAEbfJj5OIXITx5QGbZns/AtxqGyRSCn2zP0K2jsWEX4L3b1j+MnDXORFbGro1RF32RfTmZKF60grwSAXst09CFd+dxZLhizJjCRaah065YiLCcCbHyZM6uswCEWp9sz9Cto7FhF+C929Y/jJw1zkRWxq6NURd9kX05mShc5AbJ0B8bQ0j9842h5lUfOWcbj2TeoFx6OCpgoHIqWIBhHAAAAAFYAAIAAAACAAQAAgAAAAAAAAAAAARcgUJKbdMGgSVS3i0tgNel6XgeKWg8o7JbVR7/ums6AOsAAAAA="
|
||||
},
|
||||
{
|
||||
"outpoint": {
|
||||
@@ -467,13 +420,7 @@ var (
|
||||
"spentBy": "d6684a5b9e6939dccdf07d1f0eaf7fdd7b31de4d123e63e400d23de739800d4e",
|
||||
"expireAt": "1726486389",
|
||||
"swept": false,
|
||||
"pending": true,
|
||||
"pendingData": {
|
||||
"redeemTx": "cHNidP8BAIkCAAAAARH6LJRGP/pFIkD/o5bBp8fXAhjl8yjfN7MhJsxdt5lrAQAAAAD/////AtAHAAAAAAAAIlEguuBh3KQUVZp+NHV2sixQ/mrsngCuLCGXzsgJPC1FzY7ANQ8AAAAAACJRIP7uXXtl4jLUcVVQU+sX7WFXmx2H6iCMzn7gye0v1Y8JAAAAAAABAStYPg8AAAAAACJRIP7uXXtl4jLUcVVQU+sX7WFXmx2H6iCMzn7gye0v1Y8JIgYCHVQFdXiyvwIlLdnji8FvbUgb+ECuTRNAB67owJnjcaMYAAAAAFYAAIAAAACAAQAAgAAAAAAAAAAAQRSc1yjQ/vHRHev23fKGANLvbOhkNYmGtmRWt8fSszlOJUzRFbnfxd1fq9gIEpaI0vrZww8tlZ94iEL75QoaIbVqQJsPdLYf7fAoXO82VoqwYHu1WevE4g6LxUGBPzfd96q5EEZkoW5qqg+v5dWJUEY467Q6qZLFHwziUaB3KEY8yEpCFcBQkpt0waBJVLeLS2A16XpeB4paDyjsltVHv+6azoA6wO5D2Mh3x0XNGxFCS67GNughkENFodpFeVpZjn76chI8RSAdVAV1eLK/AiUt2eOLwW9tSBv4QK5NE0AHrujAmeNxo60gnNco0P7x0R3r9t3yhgDS72zoZDWJhrZkVrfH0rM5TiWswCEWHVQFdXiyvwIlLdnji8FvbUgb+ECuTRNAB67owJnjcaM5AUzRFbnfxd1fq9gIEpaI0vrZww8tlZ94iEL75QoaIbVqAAAAAFYAAIAAAACAAQAAgAAAAAAAAAAAARcgUJKbdMGgSVS3i0tgNel6XgeKWg8o7JbVR7/ums6AOsAAAAA=",
|
||||
"unconditionalForfeitTxs": [
|
||||
"cHNidP8BAFICAAAAARH6LJRGP/pFIkD/o5bBp8fXAhjl8yjfN7MhJsxdt5lrAQAAAAD/////AZA9DwAAAAAAFgAU+9NJhjFhe8jX1hrXh3NvDyHZ1cYAAAAAAAEBK1g+DwAAAAAAIlEg/u5de2XiMtRxVVBT6xftYVebHYfqIIzOfuDJ7S/VjwlBFJzXKND+8dEd6/bd8oYA0u9s6GQ1iYa2ZFa3x9KzOU4lTNEVud/F3V+r2AgSlojS+tnDDy2Vn3iIQvvlChohtWpARJzBjlEkN/kTpyFEtpvP2Ui7ypevuxb9J/NUAwhYf8Pmnnj1l3WuKCSi4Fcp1O+lQjIiZlNpwY6J73q/V8Fe2kIVwFCSm3TBoElUt4tLYDXpel4HiloPKOyW1Ue/7prOgDrA7kPYyHfHRc0bEUJLrsY26CGQQ0Wh2kV5WlmOfvpyEjxFIB1UBXV4sr8CJS3Z44vBb21IG/hArk0TQAeu6MCZ43GjrSCc1yjQ/vHRHev23fKGANLvbOhkNYmGtmRWt8fSszlOJazAARcgUJKbdMGgSVS3i0tgNel6XgeKWg8o7JbVR7/ums6AOsAAAA=="
|
||||
]
|
||||
}
|
||||
"redeemTx": "cHNidP8BAIkCAAAAARH6LJRGP/pFIkD/o5bBp8fXAhjl8yjfN7MhJsxdt5lrAQAAAAD/////AtAHAAAAAAAAIlEguuBh3KQUVZp+NHV2sixQ/mrsngCuLCGXzsgJPC1FzY7ANQ8AAAAAACJRIP7uXXtl4jLUcVVQU+sX7WFXmx2H6iCMzn7gye0v1Y8JAAAAAAABAStYPg8AAAAAACJRIP7uXXtl4jLUcVVQU+sX7WFXmx2H6iCMzn7gye0v1Y8JIgYCHVQFdXiyvwIlLdnji8FvbUgb+ECuTRNAB67owJnjcaMYAAAAAFYAAIAAAACAAQAAgAAAAAAAAAAAQRSc1yjQ/vHRHev23fKGANLvbOhkNYmGtmRWt8fSszlOJUzRFbnfxd1fq9gIEpaI0vrZww8tlZ94iEL75QoaIbVqQJsPdLYf7fAoXO82VoqwYHu1WevE4g6LxUGBPzfd96q5EEZkoW5qqg+v5dWJUEY467Q6qZLFHwziUaB3KEY8yEpCFcBQkpt0waBJVLeLS2A16XpeB4paDyjsltVHv+6azoA6wO5D2Mh3x0XNGxFCS67GNughkENFodpFeVpZjn76chI8RSAdVAV1eLK/AiUt2eOLwW9tSBv4QK5NE0AHrujAmeNxo60gnNco0P7x0R3r9t3yhgDS72zoZDWJhrZkVrfH0rM5TiWswCEWHVQFdXiyvwIlLdnji8FvbUgb+ECuTRNAB67owJnjcaM5AUzRFbnfxd1fq9gIEpaI0vrZww8tlZ94iEL75QoaIbVqAAAAAFYAAIAAAACAAQAAgAAAAAAAAAAAARcgUJKbdMGgSVS3i0tgNel6XgeKWg8o7JbVR7/ums6AOsAAAAA="
|
||||
}
|
||||
]
|
||||
}`
|
||||
@@ -494,13 +441,7 @@ var (
|
||||
"spentBy": "",
|
||||
"expireAt": "1726503895",
|
||||
"swept": false,
|
||||
"pending": false,
|
||||
"pendingData": {
|
||||
"redeemTx": "cHNidP8BAIkCAAAAAdOK9YzYw1ceJznqJxtRXGe0KeHj6CLcLtqLVwcbMCivAAAAAAD/////ArgLAAAAAAAAIlEgC39Vxhw3dIa4heHgFS6X4XwDl1mBggsKLVTBwF1h3qEgegEAAAAAACJRIMkktfIFxFNTtAmy3K0p+7JqVn2kcA0P6y2vJ1QX2zysAAAAAAABASughgEAAAAAACJRIMkktfIFxFNTtAmy3K0p+7JqVn2kcA0P6y2vJ1QX2zysIgYDjGeMfnNwCrU45iB3iRqiFdWTADaiJ968+w3ruFuq1F0YAAAAAFYAAIAAAACAAQAAgAAAAAAAAAAAQRTYEOuHJ0hyLBGzY8nSHpD2F1nby5/XQ5Sh2Je+cQ5Wsx0ZucLmB/LLspxMRN9JcJn3Q2KJRMhhg7415cCg1d0gQNSvgaBk/1WLYqQxCKxCfv8ViVJ7vjBxvNO5tc2FEDy27V9cIrfL1jPJoVrhgPZT0GwY7dkVZS7saIKI03CbipBCFcBQkpt0waBJVLeLS2A16XpeB4paDyjsltVHv+6azoA6wPKiQ0JM6aw2kcUByijEbOydM3gTIVCGN/69q+dmyxcqRSCMZ4x+c3AKtTjmIHeJGqIV1ZMANqIn3rz7Deu4W6rUXa0g2BDrhydIciwRs2PJ0h6Q9hdZ28uf10OUodiXvnEOVrOswCEWjGeMfnNwCrU45iB3iRqiFdWTADaiJ968+w3ruFuq1F05AR0ZucLmB/LLspxMRN9JcJn3Q2KJRMhhg7415cCg1d0gAAAAAFYAAIAAAACAAQAAgAAAAAAAAAAAARcgUJKbdMGgSVS3i0tgNel6XgeKWg8o7JbVR7/ums6AOsAAAAA=",
|
||||
"unconditionalForfeitTxs": [
|
||||
"cHNidP8BAFICAAAAAdOK9YzYw1ceJznqJxtRXGe0KeHj6CLcLtqLVwcbMCivAAAAAAD/////AdiFAQAAAAAAFgAUlsBYsQa9BEiB8ZumuN4J50lbQIoAAAAAAAEBK6CGAQAAAAAAIlEgySS18gXEU1O0CbLcrSn7smpWfaRwDQ/rLa8nVBfbPKxBFNgQ64cnSHIsEbNjydIekPYXWdvLn9dDlKHYl75xDlazHRm5wuYH8suynExE30lwmfdDYolEyGGDvjXlwKDV3SBAZadgbU8gCDvq3XN0EeLIwGKGSAYHZRkGbAnr9ZjCHGKAQlfFNYS0af1Lz4j7Th2osVY8JJv7O736sC5NNQome0IVwFCSm3TBoElUt4tLYDXpel4HiloPKOyW1Ue/7prOgDrA8qJDQkzprDaRxQHKKMRs7J0zeBMhUIY3/r2r52bLFypFIIxnjH5zcAq1OOYgd4kaohXVkwA2oifevPsN67hbqtRdrSDYEOuHJ0hyLBGzY8nSHpD2F1nby5/XQ5Sh2Je+cQ5Ws6zAARcgUJKbdMGgSVS3i0tgNel6XgeKWg8o7JbVR7/ums6AOsAAAA=="
|
||||
]
|
||||
}
|
||||
"redeemTx": "cHNidP8BAIkCAAAAAdOK9YzYw1ceJznqJxtRXGe0KeHj6CLcLtqLVwcbMCivAAAAAAD/////ArgLAAAAAAAAIlEgC39Vxhw3dIa4heHgFS6X4XwDl1mBggsKLVTBwF1h3qEgegEAAAAAACJRIMkktfIFxFNTtAmy3K0p+7JqVn2kcA0P6y2vJ1QX2zysAAAAAAABASughgEAAAAAACJRIMkktfIFxFNTtAmy3K0p+7JqVn2kcA0P6y2vJ1QX2zysIgYDjGeMfnNwCrU45iB3iRqiFdWTADaiJ968+w3ruFuq1F0YAAAAAFYAAIAAAACAAQAAgAAAAAAAAAAAQRTYEOuHJ0hyLBGzY8nSHpD2F1nby5/XQ5Sh2Je+cQ5Wsx0ZucLmB/LLspxMRN9JcJn3Q2KJRMhhg7415cCg1d0gQNSvgaBk/1WLYqQxCKxCfv8ViVJ7vjBxvNO5tc2FEDy27V9cIrfL1jPJoVrhgPZT0GwY7dkVZS7saIKI03CbipBCFcBQkpt0waBJVLeLS2A16XpeB4paDyjsltVHv+6azoA6wPKiQ0JM6aw2kcUByijEbOydM3gTIVCGN/69q+dmyxcqRSCMZ4x+c3AKtTjmIHeJGqIV1ZMANqIn3rz7Deu4W6rUXa0g2BDrhydIciwRs2PJ0h6Q9hdZ28uf10OUodiXvnEOVrOswCEWjGeMfnNwCrU45iB3iRqiFdWTADaiJ968+w3ruFuq1F05AR0ZucLmB/LLspxMRN9JcJn3Q2KJRMhhg7415cCg1d0gAAAAAFYAAIAAAACAAQAAgAAAAAAAAAAAARcgUJKbdMGgSVS3i0tgNel6XgeKWg8o7JbVR7/ums6AOsAAAAA="
|
||||
}
|
||||
],
|
||||
"spentVtxos": [
|
||||
@@ -518,13 +459,7 @@ var (
|
||||
"spentBy": "d6684a5b9e6939dccdf07d1f0eaf7fdd7b31de4d123e63e400d23de739800d4e",
|
||||
"expireAt": "1726054928",
|
||||
"swept": false,
|
||||
"pending": true,
|
||||
"pendingData": {
|
||||
"redeemTx": "cHNidP8BAIkCAAAAAWwxXUjG5tidFA0LmUljX//jwW6xWaS6HKyRCw5StsxpAAAAAAD/////AugDAAAAAAAAIlEgt2eR8LtqTP7yUcQtSydeGrRiHnVmHHnZwYjdC23G7MZwSQAAAAAAACJRIKfUzf/o9h+r0v9y4nmyOt9qO8EkDumQPQZGTbEv8fSFAAAAAAABASsgTgAAAAAAACJRIKfUzf/o9h+r0v9y4nmyOt9qO8EkDumQPQZGTbEv8fSFIgYDp9sz9Cto7FhF+C929Y/jJw1zkRWxq6NURd9kX05mShcYAAAAAFYAAIAAAACAAQAAgAAAAAAAAAAAQRSvBIBey3T0IV353FkuGLMmMJFpqHTrliIsJwJsfJkzq7J0B8bQ0j9842h5lUfOWcbj2TeoFx6OCpgoHIqWIBhHQAFqkBLiRmP3AZ8MS77s1QIWZswMV3L72D9gN0f0MbD6XHkmzZeC1clF3uzxr+13wsF0vcFe29Zl3e2gAhMNGYVCFcFQkpt0waBJVLeLS2A16XpeB4paDyjsltVHv+6azoA6wKRtST8P7teUpSF4DAEbfJj5OIXITx5QGbZns/AtxqGyRSCn2zP0K2jsWEX4L3b1j+MnDXORFbGro1RF32RfTmZKF60grwSAXst09CFd+dxZLhizJjCRaah065YiLCcCbHyZM6uswCEWp9sz9Cto7FhF+C929Y/jJw1zkRWxq6NURd9kX05mShc5AbJ0B8bQ0j9842h5lUfOWcbj2TeoFx6OCpgoHIqWIBhHAAAAAFYAAIAAAACAAQAAgAAAAAAAAAAAARcgUJKbdMGgSVS3i0tgNel6XgeKWg8o7JbVR7/ums6AOsAAAAA=",
|
||||
"unconditionalForfeitTxs": [
|
||||
"cHNidP8BAFICAAAAAWwxXUjG5tidFA0LmUljX//jwW6xWaS6HKyRCw5StsxpAAAAAAD/////AVhNAAAAAAAAFgAUSU38/3Mzx5BdILG4oUO+JoHcoT8AAAAAAAEBKyBOAAAAAAAAIlEgp9TN/+j2H6vS/3LiebI632o7wSQO6ZA9BkZNsS/x9IVBFK8EgF7LdPQhXfncWS4YsyYwkWmodOuWIiwnAmx8mTOrsnQHxtDSP3zjaHmVR85ZxuPZN6gXHo4KmCgcipYgGEdAjH8Mg1Z3GdjGzp78Mg2xq1fop9KDfeji+xoyMgYS7q0Nl0AGOAaNzkDRW4cNcefll5jZC2i3nfygKdXsUsR+LEIVwVCSm3TBoElUt4tLYDXpel4HiloPKOyW1Ue/7prOgDrApG1JPw/u15SlIXgMARt8mPk4hchPHlAZtmez8C3GobJFIKfbM/QraOxYRfgvdvWP4ycNc5EVsaujVEXfZF9OZkoXrSCvBIBey3T0IV353FkuGLMmMJFpqHTrliIsJwJsfJkzq6zAARcgUJKbdMGgSVS3i0tgNel6XgeKWg8o7JbVR7/ums6AOsAAAA=="
|
||||
]
|
||||
}
|
||||
"redeemTx": "cHNidP8BAIkCAAAAAWwxXUjG5tidFA0LmUljX//jwW6xWaS6HKyRCw5StsxpAAAAAAD/////AugDAAAAAAAAIlEgt2eR8LtqTP7yUcQtSydeGrRiHnVmHHnZwYjdC23G7MZwSQAAAAAAACJRIKfUzf/o9h+r0v9y4nmyOt9qO8EkDumQPQZGTbEv8fSFAAAAAAABASsgTgAAAAAAACJRIKfUzf/o9h+r0v9y4nmyOt9qO8EkDumQPQZGTbEv8fSFIgYDp9sz9Cto7FhF+C929Y/jJw1zkRWxq6NURd9kX05mShcYAAAAAFYAAIAAAACAAQAAgAAAAAAAAAAAQRSvBIBey3T0IV353FkuGLMmMJFpqHTrliIsJwJsfJkzq7J0B8bQ0j9842h5lUfOWcbj2TeoFx6OCpgoHIqWIBhHQAFqkBLiRmP3AZ8MS77s1QIWZswMV3L72D9gN0f0MbD6XHkmzZeC1clF3uzxr+13wsF0vcFe29Zl3e2gAhMNGYVCFcFQkpt0waBJVLeLS2A16XpeB4paDyjsltVHv+6azoA6wKRtST8P7teUpSF4DAEbfJj5OIXITx5QGbZns/AtxqGyRSCn2zP0K2jsWEX4L3b1j+MnDXORFbGro1RF32RfTmZKF60grwSAXst09CFd+dxZLhizJjCRaah065YiLCcCbHyZM6uswCEWp9sz9Cto7FhF+C929Y/jJw1zkRWxq6NURd9kX05mShc5AbJ0B8bQ0j9842h5lUfOWcbj2TeoFx6OCpgoHIqWIBhHAAAAAFYAAIAAAACAAQAAgAAAAAAAAAAAARcgUJKbdMGgSVS3i0tgNel6XgeKWg8o7JbVR7/ums6AOsAAAAA="
|
||||
},
|
||||
{
|
||||
"outpoint": {
|
||||
@@ -541,12 +476,7 @@ var (
|
||||
"expireAt": "1726486389",
|
||||
"swept": false,
|
||||
"pending": true,
|
||||
"pendingData": {
|
||||
"redeemTx": "cHNidP8BAIkCAAAAARH6LJRGP/pFIkD/o5bBp8fXAhjl8yjfN7MhJsxdt5lrAQAAAAD/////AtAHAAAAAAAAIlEguuBh3KQUVZp+NHV2sixQ/mrsngCuLCGXzsgJPC1FzY7ANQ8AAAAAACJRIP7uXXtl4jLUcVVQU+sX7WFXmx2H6iCMzn7gye0v1Y8JAAAAAAABAStYPg8AAAAAACJRIP7uXXtl4jLUcVVQU+sX7WFXmx2H6iCMzn7gye0v1Y8JIgYCHVQFdXiyvwIlLdnji8FvbUgb+ECuTRNAB67owJnjcaMYAAAAAFYAAIAAAACAAQAAgAAAAAAAAAAAQRSc1yjQ/vHRHev23fKGANLvbOhkNYmGtmRWt8fSszlOJUzRFbnfxd1fq9gIEpaI0vrZww8tlZ94iEL75QoaIbVqQJsPdLYf7fAoXO82VoqwYHu1WevE4g6LxUGBPzfd96q5EEZkoW5qqg+v5dWJUEY467Q6qZLFHwziUaB3KEY8yEpCFcBQkpt0waBJVLeLS2A16XpeB4paDyjsltVHv+6azoA6wO5D2Mh3x0XNGxFCS67GNughkENFodpFeVpZjn76chI8RSAdVAV1eLK/AiUt2eOLwW9tSBv4QK5NE0AHrujAmeNxo60gnNco0P7x0R3r9t3yhgDS72zoZDWJhrZkVrfH0rM5TiWswCEWHVQFdXiyvwIlLdnji8FvbUgb+ECuTRNAB67owJnjcaM5AUzRFbnfxd1fq9gIEpaI0vrZww8tlZ94iEL75QoaIbVqAAAAAFYAAIAAAACAAQAAgAAAAAAAAAAAARcgUJKbdMGgSVS3i0tgNel6XgeKWg8o7JbVR7/ums6AOsAAAAA=",
|
||||
"unconditionalForfeitTxs": [
|
||||
"cHNidP8BAFICAAAAARH6LJRGP/pFIkD/o5bBp8fXAhjl8yjfN7MhJsxdt5lrAQAAAAD/////AZA9DwAAAAAAFgAU+9NJhjFhe8jX1hrXh3NvDyHZ1cYAAAAAAAEBK1g+DwAAAAAAIlEg/u5de2XiMtRxVVBT6xftYVebHYfqIIzOfuDJ7S/VjwlBFJzXKND+8dEd6/bd8oYA0u9s6GQ1iYa2ZFa3x9KzOU4lTNEVud/F3V+r2AgSlojS+tnDDy2Vn3iIQvvlChohtWpARJzBjlEkN/kTpyFEtpvP2Ui7ypevuxb9J/NUAwhYf8Pmnnj1l3WuKCSi4Fcp1O+lQjIiZlNpwY6J73q/V8Fe2kIVwFCSm3TBoElUt4tLYDXpel4HiloPKOyW1Ue/7prOgDrA7kPYyHfHRc0bEUJLrsY26CGQQ0Wh2kV5WlmOfvpyEjxFIB1UBXV4sr8CJS3Z44vBb21IG/hArk0TQAeu6MCZ43GjrSCc1yjQ/vHRHev23fKGANLvbOhkNYmGtmRWt8fSszlOJazAARcgUJKbdMGgSVS3i0tgNel6XgeKWg8o7JbVR7/ums6AOsAAAA=="
|
||||
]
|
||||
}
|
||||
"redeemTx": "cHNidP8BAIkCAAAAARH6LJRGP/pFIkD/o5bBp8fXAhjl8yjfN7MhJsxdt5lrAQAAAAD/////AtAHAAAAAAAAIlEguuBh3KQUVZp+NHV2sixQ/mrsngCuLCGXzsgJPC1FzY7ANQ8AAAAAACJRIP7uXXtl4jLUcVVQU+sX7WFXmx2H6iCMzn7gye0v1Y8JAAAAAAABAStYPg8AAAAAACJRIP7uXXtl4jLUcVVQU+sX7WFXmx2H6iCMzn7gye0v1Y8JIgYCHVQFdXiyvwIlLdnji8FvbUgb+ECuTRNAB67owJnjcaMYAAAAAFYAAIAAAACAAQAAgAAAAAAAAAAAQRSc1yjQ/vHRHev23fKGANLvbOhkNYmGtmRWt8fSszlOJUzRFbnfxd1fq9gIEpaI0vrZww8tlZ94iEL75QoaIbVqQJsPdLYf7fAoXO82VoqwYHu1WevE4g6LxUGBPzfd96q5EEZkoW5qqg+v5dWJUEY467Q6qZLFHwziUaB3KEY8yEpCFcBQkpt0waBJVLeLS2A16XpeB4paDyjsltVHv+6azoA6wO5D2Mh3x0XNGxFCS67GNughkENFodpFeVpZjn76chI8RSAdVAV1eLK/AiUt2eOLwW9tSBv4QK5NE0AHrujAmeNxo60gnNco0P7x0R3r9t3yhgDS72zoZDWJhrZkVrfH0rM5TiWswCEWHVQFdXiyvwIlLdnji8FvbUgb+ECuTRNAB67owJnjcaM5AUzRFbnfxd1fq9gIEpaI0vrZww8tlZ94iEL75QoaIbVqAAAAAFYAAIAAAACAAQAAgAAAAAAAAAAAARcgUJKbdMGgSVS3i0tgNel6XgeKWg8o7JbVR7/ums6AOsAAAAA="
|
||||
},
|
||||
{
|
||||
"outpoint": {
|
||||
@@ -562,8 +492,7 @@ var (
|
||||
"spentBy": "23c3a885f0ea05f7bdf83f3bf7f8ac9dc3f791ad292f4e63a6f53fa5e4935ab0",
|
||||
"expireAt": "1726503895",
|
||||
"swept": false,
|
||||
"pending": false,
|
||||
"pendingData": null
|
||||
"redeemTx": ""
|
||||
}
|
||||
]
|
||||
}`
|
||||
|
||||
@@ -14,7 +14,6 @@ import (
|
||||
"github.com/ark-network/ark/common"
|
||||
"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"
|
||||
"github.com/ark-network/ark/pkg/client-sdk/internal/utils"
|
||||
"github.com/ark-network/ark/pkg/client-sdk/redemption"
|
||||
"github.com/ark-network/ark/pkg/client-sdk/types"
|
||||
@@ -251,26 +250,6 @@ func (a *covenantArkClient) listenForBoardingUtxos(
|
||||
//are multiple boarding inputs + spent vtxo with change in spendable + received in the same round
|
||||
}
|
||||
|
||||
func (a *covenantArkClient) ListVtxos(
|
||||
ctx context.Context,
|
||||
) (spendableVtxos, spentVtxos []client.Vtxo, err error) {
|
||||
offchainAddrs, _, _, err := a.wallet.GetAddresses(ctx)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for _, addr := range offchainAddrs {
|
||||
spendable, spent, err := a.client.ListVtxos(ctx, addr.Address)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
spendableVtxos = append(spendableVtxos, spendable...)
|
||||
spentVtxos = append(spentVtxos, spent...)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (a *covenantArkClient) Balance(
|
||||
ctx context.Context, computeVtxoExpiration bool,
|
||||
) (*Balance, error) {
|
||||
@@ -285,14 +264,13 @@ func (a *covenantArkClient) Balance(
|
||||
|
||||
chRes := make(chan balanceRes, nbWorkers*len(offchainAddrs))
|
||||
for i := range offchainAddrs {
|
||||
offchainAddr := offchainAddrs[i]
|
||||
boardingAddr := boardingAddrs[i]
|
||||
redeemAddr := redeemAddrs[i]
|
||||
|
||||
go func(addr string) {
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
balance, amountByExpiration, err := a.getOffchainBalance(
|
||||
ctx, addr, computeVtxoExpiration,
|
||||
ctx, computeVtxoExpiration,
|
||||
)
|
||||
if err != nil {
|
||||
chRes <- balanceRes{err: err}
|
||||
@@ -303,7 +281,7 @@ func (a *covenantArkClient) Balance(
|
||||
offchainBalance: balance,
|
||||
offchainBalanceByExpiration: amountByExpiration,
|
||||
}
|
||||
}(offchainAddr.Address)
|
||||
}()
|
||||
|
||||
getDelayedBalance := func(addr string) {
|
||||
defer wg.Done()
|
||||
@@ -448,20 +426,11 @@ func (a *covenantArkClient) UnilateralRedeem(ctx context.Context) error {
|
||||
return fmt.Errorf("wallet is locked")
|
||||
}
|
||||
|
||||
offchainAddrs, _, _, err := a.wallet.GetAddresses(ctx)
|
||||
vtxos, err := a.getVtxos(ctx, false, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
vtxos := make([]client.Vtxo, 0)
|
||||
for _, offchainAddr := range offchainAddrs {
|
||||
fetchedVtxos, _, err := a.client.ListVtxos(ctx, offchainAddr.Address)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
vtxos = append(vtxos, fetchedVtxos...)
|
||||
}
|
||||
|
||||
totalVtxosAmount := uint64(0)
|
||||
for _, vtxo := range vtxos {
|
||||
totalVtxosAmount += vtxo.Amount
|
||||
@@ -519,22 +488,13 @@ func (a *covenantArkClient) CollaborativeRedeem(
|
||||
return "", fmt.Errorf("wallet is locked")
|
||||
}
|
||||
|
||||
// validate liquid address
|
||||
if _, err := address.ToOutputScript(addr); err != nil {
|
||||
return "", fmt.Errorf("invalid onchain address")
|
||||
}
|
||||
|
||||
addrNet, err := address.NetworkForAddress(addr)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("invalid onchain address: unknown network")
|
||||
}
|
||||
net := utils.ToElementsNetwork(a.Network)
|
||||
if net.Name != addrNet.Name {
|
||||
return "", fmt.Errorf("invalid onchain address: must be for %s network", net.Name)
|
||||
}
|
||||
|
||||
if isConf, _ := address.IsConfidential(addr); isConf {
|
||||
info, _ := address.FromConfidential(addr)
|
||||
addr = info.Address
|
||||
if isConf, err := address.IsConfidential(addr); err != nil || isConf {
|
||||
return "", fmt.Errorf("confidential onchain address not supported")
|
||||
}
|
||||
|
||||
offchainAddrs, _, _, err := a.wallet.GetAddresses(ctx)
|
||||
@@ -550,22 +510,34 @@ func (a *covenantArkClient) CollaborativeRedeem(
|
||||
}
|
||||
|
||||
vtxos := make([]client.DescriptorVtxo, 0)
|
||||
for _, offchainAddr := range offchainAddrs {
|
||||
spendableVtxos, err := a.getVtxos(ctx, offchainAddr.Address, withExpiryCoinselect)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
spendableVtxos, err := a.getVtxos(ctx, false, nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
for _, vtxo := range spendableVtxos {
|
||||
vtxos = append(vtxos, client.DescriptorVtxo{
|
||||
Vtxo: vtxo,
|
||||
Descriptor: offchainAddr.Descriptor,
|
||||
})
|
||||
for _, offchainAddr := range offchainAddrs {
|
||||
for _, v := range spendableVtxos {
|
||||
vtxoAddr, err := v.Address(a.AspPubkey, a.Network)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if vtxoAddr == offchainAddr.Address {
|
||||
vtxos = append(vtxos, client.DescriptorVtxo{
|
||||
Vtxo: v,
|
||||
Descriptor: offchainAddr.Descriptor,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
selectedCoins, changeAmount, err := utils.CoinSelect(
|
||||
vtxos, amount, a.Dust, withExpiryCoinselect,
|
||||
boardingUtxos, err := a.getClaimableBoardingUtxos(ctx, nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
selectedBoardingUtxos, selectedCoins, changeAmount, err := utils.CoinSelect(
|
||||
boardingUtxos, vtxos, amount, a.Dust, withExpiryCoinselect,
|
||||
)
|
||||
if err != nil {
|
||||
return "", err
|
||||
@@ -583,7 +555,7 @@ func (a *covenantArkClient) CollaborativeRedeem(
|
||||
})
|
||||
}
|
||||
|
||||
inputs := make([]client.Input, 0, len(selectedCoins))
|
||||
inputs := make([]client.Input, 0, len(selectedCoins)+len(selectedBoardingUtxos))
|
||||
|
||||
for _, coin := range selectedCoins {
|
||||
inputs = append(inputs, client.Input{
|
||||
@@ -594,8 +566,17 @@ func (a *covenantArkClient) CollaborativeRedeem(
|
||||
Descriptor: coin.Descriptor,
|
||||
})
|
||||
}
|
||||
for _, coin := range selectedBoardingUtxos {
|
||||
inputs = append(inputs, client.Input{
|
||||
Outpoint: client.Outpoint{
|
||||
Txid: coin.Txid,
|
||||
VOut: coin.VOut,
|
||||
},
|
||||
Descriptor: coin.Descriptor,
|
||||
})
|
||||
}
|
||||
|
||||
paymentID, err := a.client.RegisterInputsForNextRound(ctx, inputs, "") // ephemeralPublicKey is not required for covenant
|
||||
paymentID, err := a.client.RegisterInputsForNextRound(ctx, inputs, "")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -604,9 +585,7 @@ func (a *covenantArkClient) CollaborativeRedeem(
|
||||
return "", err
|
||||
}
|
||||
|
||||
poolTxID, err := a.handleRoundStream(
|
||||
ctx, paymentID, selectedCoins, nil, "", receivers,
|
||||
)
|
||||
poolTxID, err := a.handleRoundStream(ctx, paymentID, selectedCoins, selectedBoardingUtxos, receivers)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -621,36 +600,10 @@ func (a *covenantArkClient) SendAsync(
|
||||
return "", fmt.Errorf("not implemented")
|
||||
}
|
||||
|
||||
func (a *covenantArkClient) Claim(ctx context.Context) (string, error) {
|
||||
myselfOffchain, boardingAddr, err := a.wallet.NewAddress(ctx, false)
|
||||
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.Address,
|
||||
Amount: pendingBalance,
|
||||
}
|
||||
|
||||
return a.selfTransferAllPendingPayments(
|
||||
ctx,
|
||||
boardingUtxos,
|
||||
receiver,
|
||||
boardingAddr.Descriptor,
|
||||
)
|
||||
func (a *covenantArkClient) Settle(
|
||||
ctx context.Context,
|
||||
) (string, error) {
|
||||
return a.sendOffchain(ctx, false, nil)
|
||||
}
|
||||
|
||||
func (a *covenantArkClient) GetTransactionHistory(
|
||||
@@ -675,13 +628,13 @@ func (a *covenantArkClient) GetTransactionHistory(
|
||||
return vtxosToTxsCovenant(config.RoundLifetime, spendableVtxos, spentVtxos, boardingTxs)
|
||||
}
|
||||
|
||||
func (a *covenantArkClient) getAllBoardingUtxos(ctx context.Context) ([]explorer.Utxo, error) {
|
||||
func (a *covenantArkClient) getAllBoardingUtxos(ctx context.Context) ([]types.Utxo, error) {
|
||||
_, boardingAddrs, _, err := a.wallet.GetAddresses(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
utxos := []explorer.Utxo{}
|
||||
utxos := make([]types.Utxo, 0)
|
||||
for _, addr := range boardingAddrs {
|
||||
txs, err := a.explorer.GetTxs(addr.Address)
|
||||
if err != nil {
|
||||
@@ -694,11 +647,12 @@ func (a *covenantArkClient) getAllBoardingUtxos(ctx context.Context) ([]explorer
|
||||
if tx.Status.Confirmed {
|
||||
createdAt = time.Unix(tx.Status.Blocktime, 0)
|
||||
}
|
||||
utxos = append(utxos, explorer.Utxo{
|
||||
Txid: tx.Txid,
|
||||
Vout: uint32(i),
|
||||
Amount: vout.Amount,
|
||||
CreatedAt: createdAt,
|
||||
utxos = append(utxos, types.Utxo{
|
||||
Txid: tx.Txid,
|
||||
VOut: uint32(i),
|
||||
Amount: vout.Amount,
|
||||
CreatedAt: createdAt,
|
||||
Descriptor: addr.Descriptor,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -708,13 +662,13 @@ func (a *covenantArkClient) getAllBoardingUtxos(ctx context.Context) ([]explorer
|
||||
return utxos, nil
|
||||
}
|
||||
|
||||
func (a *covenantArkClient) getClaimableBoardingUtxos(ctx context.Context) ([]explorer.Utxo, error) {
|
||||
func (a *covenantArkClient) getClaimableBoardingUtxos(ctx context.Context, opts *CoinSelectOptions) ([]types.Utxo, error) {
|
||||
_, boardingAddrs, _, err := a.wallet.GetAddresses(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
claimable := make([]explorer.Utxo, 0)
|
||||
claimable := make([]types.Utxo, 0)
|
||||
|
||||
for _, addr := range boardingAddrs {
|
||||
boardingScript, err := tree.ParseVtxoScript(addr.Descriptor)
|
||||
@@ -738,8 +692,25 @@ func (a *covenantArkClient) getClaimableBoardingUtxos(ctx context.Context) ([]ex
|
||||
now := time.Now()
|
||||
|
||||
for _, utxo := range boardingUtxos {
|
||||
u := utxo.ToUtxo(boardingTimeout)
|
||||
if opts != nil && len(opts.OutpointsFilter) > 0 {
|
||||
utxoOutpoint := client.Outpoint{
|
||||
Txid: utxo.Txid,
|
||||
VOut: utxo.Vout,
|
||||
}
|
||||
found := false
|
||||
for _, outpoint := range opts.OutpointsFilter {
|
||||
if outpoint.Equals(utxoOutpoint) {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
u := utxo.ToUtxo(boardingTimeout, addr.Descriptor)
|
||||
if u.SpendableAt.Before(now) {
|
||||
continue
|
||||
}
|
||||
@@ -906,84 +877,123 @@ func (a *covenantArkClient) sendOnchain(
|
||||
}
|
||||
|
||||
func (a *covenantArkClient) sendOffchain(
|
||||
ctx context.Context, withExpiryCoinselect bool, receivers []Receiver,
|
||||
ctx context.Context,
|
||||
withExpiryCoinselect bool, receivers []Receiver,
|
||||
) (string, error) {
|
||||
if a.wallet.IsLocked() {
|
||||
return "", fmt.Errorf("wallet is locked")
|
||||
}
|
||||
|
||||
expectedAspPubKey := schnorr.SerializePubKey(a.AspPubkey)
|
||||
outputs := make([]client.Output, 0)
|
||||
sumOfReceivers := uint64(0)
|
||||
|
||||
// validate receivers and create outputs
|
||||
for _, receiver := range receivers {
|
||||
rcvAddr, err := common.DecodeAddress(receiver.To())
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("invalid receiver address: %s", err)
|
||||
}
|
||||
|
||||
rcvAspPubKey := schnorr.SerializePubKey(rcvAddr.Asp)
|
||||
|
||||
if !bytes.Equal(expectedAspPubKey, rcvAspPubKey) {
|
||||
return "", fmt.Errorf("invalid receiver address '%s': expected ASP %s, got %s", receiver.To(), hex.EncodeToString(expectedAspPubKey), hex.EncodeToString(rcvAspPubKey))
|
||||
}
|
||||
|
||||
if receiver.Amount() < a.Dust {
|
||||
return "", fmt.Errorf("invalid amount (%d), must be greater than dust %d", receiver.Amount(), a.Dust)
|
||||
}
|
||||
|
||||
outputs = append(outputs, client.Output{
|
||||
Address: receiver.To(),
|
||||
Amount: receiver.Amount(),
|
||||
})
|
||||
sumOfReceivers += receiver.Amount()
|
||||
}
|
||||
|
||||
offchainAddrs, _, _, err := a.wallet.GetAddresses(ctx)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if len(offchainAddrs) <= 0 {
|
||||
return "", fmt.Errorf("no funds detected")
|
||||
}
|
||||
|
||||
expectedAspPubkey := schnorr.SerializePubKey(a.AspPubkey)
|
||||
|
||||
receiversOutput := make([]client.Output, 0)
|
||||
sumOfReceivers := uint64(0)
|
||||
|
||||
for _, receiver := range receivers {
|
||||
rcvAddr, err := common.DecodeAddress(receiver.To())
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("invalid receiver address: %s", err)
|
||||
}
|
||||
|
||||
rcvAspPubkey := schnorr.SerializePubKey(rcvAddr.Asp)
|
||||
|
||||
if !bytes.Equal(rcvAspPubkey, expectedAspPubkey) {
|
||||
return "", fmt.Errorf("invalid receiver address '%s': expected ASP %s, got %s", receiver.To(), hex.EncodeToString(expectedAspPubkey), hex.EncodeToString(rcvAspPubkey))
|
||||
}
|
||||
|
||||
if receiver.Amount() < a.Dust {
|
||||
return "", fmt.Errorf("invalid amount (%d), must be greater than dust %d", receiver.Amount(), a.Dust)
|
||||
}
|
||||
|
||||
receiversOutput = append(receiversOutput, client.Output{
|
||||
Address: receiver.To(),
|
||||
Amount: receiver.Amount(),
|
||||
})
|
||||
sumOfReceivers += receiver.Amount()
|
||||
return "", fmt.Errorf("no offchain addresses found")
|
||||
}
|
||||
|
||||
vtxos := make([]client.DescriptorVtxo, 0)
|
||||
for _, offchainAddr := range offchainAddrs {
|
||||
spendableVtxos, err := a.getVtxos(ctx, offchainAddr.Address, withExpiryCoinselect)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
for _, vtxo := range spendableVtxos {
|
||||
vtxos = append(vtxos, client.DescriptorVtxo{
|
||||
Vtxo: vtxo,
|
||||
Descriptor: offchainAddr.Descriptor,
|
||||
})
|
||||
spendableVtxos, err := a.getVtxos(ctx, withExpiryCoinselect, nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
for _, offchainAddr := range offchainAddrs {
|
||||
for _, v := range spendableVtxos {
|
||||
vtxoAddr, err := v.Address(a.AspPubkey, a.Network)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if vtxoAddr == offchainAddr.Address {
|
||||
vtxos = append(vtxos, client.DescriptorVtxo{
|
||||
Vtxo: v,
|
||||
Descriptor: offchainAddr.Descriptor,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
selectedCoins, changeAmount, err := utils.CoinSelect(
|
||||
vtxos, sumOfReceivers, a.Dust, withExpiryCoinselect,
|
||||
)
|
||||
boardingUtxos, err := a.getClaimableBoardingUtxos(ctx, nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
var selectedBoardingCoins []types.Utxo
|
||||
var selectedCoins []client.DescriptorVtxo
|
||||
var changeAmount uint64
|
||||
|
||||
// if no receivers, self send all selected coins
|
||||
if len(outputs) <= 0 {
|
||||
selectedBoardingCoins = boardingUtxos
|
||||
selectedCoins = vtxos
|
||||
|
||||
amount := uint64(0)
|
||||
for _, utxo := range boardingUtxos {
|
||||
amount += utxo.Amount
|
||||
}
|
||||
for _, utxo := range vtxos {
|
||||
amount += utxo.Amount
|
||||
}
|
||||
|
||||
outputs = append(outputs, client.Output{
|
||||
Address: offchainAddrs[0].Address,
|
||||
Amount: amount,
|
||||
})
|
||||
|
||||
changeAmount = 0
|
||||
} else {
|
||||
selectedBoardingCoins, selectedCoins, changeAmount, err = utils.CoinSelect(
|
||||
boardingUtxos, vtxos, sumOfReceivers, a.Dust, withExpiryCoinselect,
|
||||
)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
if changeAmount > 0 {
|
||||
offchainAddr, _, err := a.wallet.NewAddress(ctx, true)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
changeReceiver := client.Output{
|
||||
outputs = append(outputs, client.Output{
|
||||
Address: offchainAddr.Address,
|
||||
Amount: changeAmount,
|
||||
}
|
||||
receiversOutput = append(receiversOutput, changeReceiver)
|
||||
})
|
||||
}
|
||||
|
||||
inputs := make([]client.Input, 0, len(selectedCoins))
|
||||
inputs := make([]client.Input, 0, len(selectedCoins)+len(selectedBoardingCoins))
|
||||
|
||||
for _, coin := range selectedCoins {
|
||||
inputs = append(inputs, client.Input{
|
||||
Outpoint: client.Outpoint{
|
||||
@@ -993,16 +1003,23 @@ func (a *covenantArkClient) sendOffchain(
|
||||
Descriptor: coin.Descriptor,
|
||||
})
|
||||
}
|
||||
for _, coin := range selectedBoardingCoins {
|
||||
inputs = append(inputs, client.Input{
|
||||
Outpoint: client.Outpoint{
|
||||
Txid: coin.Txid,
|
||||
VOut: coin.VOut,
|
||||
},
|
||||
Descriptor: coin.Descriptor,
|
||||
})
|
||||
}
|
||||
|
||||
paymentID, err := a.client.RegisterInputsForNextRound(
|
||||
ctx, inputs, "", // ephemeralPublicKey is not required for covenant
|
||||
)
|
||||
paymentID, err := a.client.RegisterInputsForNextRound(ctx, inputs, "")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if err := a.client.RegisterOutputsForNextRound(
|
||||
ctx, paymentID, receiversOutput,
|
||||
ctx, paymentID, outputs,
|
||||
); err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -1010,7 +1027,7 @@ func (a *covenantArkClient) sendOffchain(
|
||||
log.Infof("payment registered with id: %s", paymentID)
|
||||
|
||||
poolTxID, err := a.handleRoundStream(
|
||||
ctx, paymentID, selectedCoins, nil, "", receiversOutput,
|
||||
ctx, paymentID, selectedCoins, boardingUtxos, outputs,
|
||||
)
|
||||
if err != nil {
|
||||
return "", err
|
||||
@@ -1023,7 +1040,7 @@ func (a *covenantArkClient) sendOffchain(
|
||||
func (a *covenantArkClient) addInputs(
|
||||
ctx context.Context,
|
||||
updater *psetv2.Updater,
|
||||
utxos []explorer.Utxo,
|
||||
utxos []types.Utxo,
|
||||
) error {
|
||||
// TODO works only with single-key wallet
|
||||
offchain, _, err := a.wallet.NewAddress(ctx, false)
|
||||
@@ -1055,7 +1072,7 @@ func (a *covenantArkClient) addInputs(
|
||||
if err := updater.AddInputs([]psetv2.InputArgs{
|
||||
{
|
||||
Txid: utxo.Txid,
|
||||
TxIndex: utxo.Vout,
|
||||
TxIndex: utxo.VOut,
|
||||
Sequence: sequence,
|
||||
},
|
||||
}); err != nil {
|
||||
@@ -1113,8 +1130,7 @@ func (a *covenantArkClient) handleRoundStream(
|
||||
ctx context.Context,
|
||||
paymentID string,
|
||||
vtxosToSign []client.DescriptorVtxo,
|
||||
boardingUtxos []explorer.Utxo,
|
||||
boardingDescriptor string,
|
||||
boardingUtxos []types.Utxo,
|
||||
receivers []client.Output,
|
||||
) (string, error) {
|
||||
eventsCh, close, err := a.client.GetEventStream(ctx, paymentID)
|
||||
@@ -1151,7 +1167,7 @@ func (a *covenantArkClient) handleRoundStream(
|
||||
log.Info("a round finalization started")
|
||||
|
||||
signedForfeitTxs, signedRoundTx, err := a.handleRoundFinalization(
|
||||
ctx, event.(client.RoundFinalizationEvent), vtxosToSign, boardingUtxos, boardingDescriptor, receivers,
|
||||
ctx, event.(client.RoundFinalizationEvent), vtxosToSign, boardingUtxos, receivers,
|
||||
)
|
||||
if err != nil {
|
||||
return "", err
|
||||
@@ -1178,8 +1194,7 @@ func (a *covenantArkClient) handleRoundFinalization(
|
||||
ctx context.Context,
|
||||
event client.RoundFinalizationEvent,
|
||||
vtxos []client.DescriptorVtxo,
|
||||
boardingUtxos []explorer.Utxo,
|
||||
boardingDescriptor string,
|
||||
boardingUtxos []types.Utxo,
|
||||
receivers []client.Output,
|
||||
) (signedForfeits []string, signedRoundTx string, err error) {
|
||||
if err = a.validateCongestionTree(event, receivers); err != nil {
|
||||
@@ -1193,13 +1208,23 @@ func (a *covenantArkClient) handleRoundFinalization(
|
||||
}
|
||||
}
|
||||
|
||||
if len(boardingUtxos) > 0 {
|
||||
boardingVtxoScript, err := tree.ParseVtxoScript(boardingDescriptor)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
// if no boarding utxos inputs, we don't need to sign the round transaction
|
||||
if len(boardingUtxos) <= 0 {
|
||||
return
|
||||
}
|
||||
|
||||
roundPtx, err := psetv2.NewPsetFromBase64(event.Tx)
|
||||
roundPtx, err := psetv2.NewPsetFromBase64(event.Tx)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
updater, err := psetv2.NewUpdater(roundPtx)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
for _, boardingUtxo := range boardingUtxos {
|
||||
boardingVtxoScript, err := tree.ParseVtxoScript(boardingUtxo.Descriptor)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
@@ -1213,7 +1238,7 @@ func (a *covenantArkClient) handleRoundFinalization(
|
||||
AspPubkey: a.AspPubkey,
|
||||
}
|
||||
default:
|
||||
return nil, "", fmt.Errorf("unsupported boarding descriptor: %s", boardingDescriptor)
|
||||
return nil, "", fmt.Errorf("unsupported boarding descriptor: %s", boardingUtxo.Descriptor)
|
||||
}
|
||||
|
||||
forfeitLeaf, err := forfeitClosure.Leaf()
|
||||
@@ -1241,31 +1266,25 @@ func (a *covenantArkClient) handleRoundFinalization(
|
||||
ControlBlock: *ctrlBlock,
|
||||
}
|
||||
|
||||
updater, err := psetv2.NewUpdater(roundPtx)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
for i, input := range updater.Pset.Inputs {
|
||||
for _, boardingUtxo := range boardingUtxos {
|
||||
if chainhash.Hash(input.PreviousTxid).String() == boardingUtxo.Txid && boardingUtxo.Vout == input.PreviousTxIndex {
|
||||
if err := updater.AddInTapLeafScript(i, tapscript); err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
break
|
||||
if chainhash.Hash(input.PreviousTxid).String() == boardingUtxo.Txid && boardingUtxo.VOut == input.PreviousTxIndex {
|
||||
if err := updater.AddInTapLeafScript(i, tapscript); err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
b64, err := updater.Pset.ToBase64()
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
}
|
||||
|
||||
signedRoundTx, err = a.wallet.SignTransaction(ctx, a.explorer, b64)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
b64, err := updater.Pset.ToBase64()
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
signedRoundTx, err = a.wallet.SignTransaction(ctx, a.explorer, b64)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
return signedForfeits, signedRoundTx, nil
|
||||
@@ -1518,8 +1537,8 @@ func (a *covenantArkClient) createAndSignForfeits(
|
||||
}
|
||||
|
||||
func (a *covenantArkClient) coinSelectOnchain(
|
||||
ctx context.Context, targetAmount uint64, exclude []explorer.Utxo,
|
||||
) ([]explorer.Utxo, uint64, error) {
|
||||
ctx context.Context, targetAmount uint64, exclude []types.Utxo,
|
||||
) ([]types.Utxo, uint64, error) {
|
||||
_, boardingAddrs, redemptionAddrs, err := a.wallet.GetAddresses(ctx)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
@@ -1527,7 +1546,7 @@ func (a *covenantArkClient) coinSelectOnchain(
|
||||
|
||||
now := time.Now()
|
||||
|
||||
fetchedUtxos := make([]explorer.Utxo, 0)
|
||||
fetchedUtxos := make([]types.Utxo, 0)
|
||||
for _, addr := range boardingAddrs {
|
||||
boardingDescriptor := addr.Descriptor
|
||||
|
||||
@@ -1550,14 +1569,14 @@ func (a *covenantArkClient) coinSelectOnchain(
|
||||
}
|
||||
|
||||
for _, utxo := range utxos {
|
||||
u := utxo.ToUtxo(boardingTimeout)
|
||||
u := utxo.ToUtxo(boardingTimeout, addr.Descriptor)
|
||||
if u.SpendableAt.Before(now) {
|
||||
fetchedUtxos = append(fetchedUtxos, u)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
selected := make([]explorer.Utxo, 0)
|
||||
selected := make([]types.Utxo, 0)
|
||||
selectedAmount := uint64(0)
|
||||
for _, utxo := range fetchedUtxos {
|
||||
if selectedAmount >= targetAmount {
|
||||
@@ -1565,7 +1584,7 @@ func (a *covenantArkClient) coinSelectOnchain(
|
||||
}
|
||||
|
||||
for _, excluded := range exclude {
|
||||
if utxo.Txid == excluded.Txid && utxo.Vout == excluded.Vout {
|
||||
if utxo.Txid == excluded.Txid && utxo.VOut == excluded.VOut {
|
||||
continue
|
||||
}
|
||||
}
|
||||
@@ -1578,7 +1597,7 @@ func (a *covenantArkClient) coinSelectOnchain(
|
||||
return selected, selectedAmount - targetAmount, nil
|
||||
}
|
||||
|
||||
fetchedUtxos = make([]explorer.Utxo, 0)
|
||||
fetchedUtxos = make([]types.Utxo, 0)
|
||||
for _, addr := range redemptionAddrs {
|
||||
utxos, err := a.explorer.GetUtxos(addr.Address)
|
||||
if err != nil {
|
||||
@@ -1586,7 +1605,7 @@ func (a *covenantArkClient) coinSelectOnchain(
|
||||
}
|
||||
|
||||
for _, utxo := range utxos {
|
||||
u := utxo.ToUtxo(uint(a.UnilateralExitDelay))
|
||||
u := utxo.ToUtxo(uint(a.UnilateralExitDelay), addr.Descriptor)
|
||||
if u.SpendableAt.Before(now) {
|
||||
fetchedUtxos = append(fetchedUtxos, u)
|
||||
}
|
||||
@@ -1599,7 +1618,7 @@ func (a *covenantArkClient) coinSelectOnchain(
|
||||
}
|
||||
|
||||
for _, excluded := range exclude {
|
||||
if utxo.Txid == excluded.Txid && utxo.Vout == excluded.Vout {
|
||||
if utxo.Txid == excluded.Txid && utxo.VOut == excluded.VOut {
|
||||
continue
|
||||
}
|
||||
}
|
||||
@@ -1648,11 +1667,11 @@ func (a *covenantArkClient) getRedeemBranches(
|
||||
}
|
||||
|
||||
func (a *covenantArkClient) getOffchainBalance(
|
||||
ctx context.Context, addr string, computeVtxoExpiration bool,
|
||||
ctx context.Context, computeVtxoExpiration bool,
|
||||
) (uint64, map[int64]uint64, error) {
|
||||
amountByExpiration := make(map[int64]uint64, 0)
|
||||
|
||||
vtxos, err := a.getVtxos(ctx, addr, computeVtxoExpiration)
|
||||
vtxos, err := a.getVtxos(ctx, computeVtxoExpiration, nil)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
@@ -1675,18 +1694,24 @@ func (a *covenantArkClient) getOffchainBalance(
|
||||
}
|
||||
|
||||
func (a *covenantArkClient) getVtxos(
|
||||
ctx context.Context, addr string, computeVtxoExpiration bool,
|
||||
ctx context.Context,
|
||||
withExpiryCoinselect bool, opts *CoinSelectOptions,
|
||||
) ([]client.Vtxo, error) {
|
||||
vtxos, _, err := a.client.ListVtxos(ctx, addr)
|
||||
spendableVtxos, _, err := a.ListVtxos(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !computeVtxoExpiration {
|
||||
return vtxos, nil
|
||||
if opts != nil && len(opts.OutpointsFilter) > 0 {
|
||||
spendableVtxos = filterByOutpoints(spendableVtxos, opts.OutpointsFilter)
|
||||
}
|
||||
|
||||
redeemBranches, err := a.getRedeemBranches(ctx, vtxos)
|
||||
if opts == nil || !opts.WithExpirySorting {
|
||||
return spendableVtxos, nil
|
||||
}
|
||||
|
||||
// if sorting by expiry is required, we need to get the expiration date of each vtxo
|
||||
redeemBranches, err := a.getRedeemBranches(ctx, spendableVtxos)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1697,75 +1722,24 @@ func (a *covenantArkClient) getVtxos(
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for i, vtxo := range vtxos {
|
||||
for i, vtxo := range spendableVtxos {
|
||||
if vtxo.Txid == vtxoTxid {
|
||||
vtxos[i].ExpiresAt = expiration
|
||||
spendableVtxos[i].ExpiresAt = expiration
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return vtxos, nil
|
||||
}
|
||||
|
||||
func (a *covenantArkClient) selfTransferAllPendingPayments(
|
||||
ctx context.Context, boardingUtxos []explorer.Utxo, myself client.Output, boardingDescriptor string,
|
||||
) (string, error) {
|
||||
inputs := make([]client.Input, 0, len(boardingUtxos))
|
||||
|
||||
for _, utxo := range boardingUtxos {
|
||||
inputs = append(inputs, client.Input{
|
||||
Outpoint: client.Outpoint{
|
||||
Txid: utxo.Txid,
|
||||
VOut: utxo.Vout,
|
||||
},
|
||||
Descriptor: boardingDescriptor,
|
||||
})
|
||||
}
|
||||
|
||||
outputs := []client.Output{myself}
|
||||
|
||||
paymentID, err := a.client.RegisterInputsForNextRound(ctx, inputs, "") // ephemeralPublicKey is not required for covenant
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if err := a.client.RegisterOutputsForNextRound(ctx, paymentID, outputs); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
roundTxid, err := a.handleRoundStream(
|
||||
ctx, paymentID, make([]client.DescriptorVtxo, 0), boardingUtxos, boardingDescriptor, outputs,
|
||||
)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return roundTxid, nil
|
||||
return spendableVtxos, nil
|
||||
}
|
||||
|
||||
func (a *covenantArkClient) getBoardingTxs(ctx context.Context) (transactions []types.Transaction) {
|
||||
utxos, err := a.getClaimableBoardingUtxos(ctx)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
isPending := make(map[string]bool)
|
||||
for _, u := range utxos {
|
||||
isPending[u.Txid] = true
|
||||
}
|
||||
|
||||
allUtxos, err := a.getAllBoardingUtxos(ctx)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, u := range allUtxos {
|
||||
pending := false
|
||||
if isPending[u.Txid] {
|
||||
pending = true
|
||||
}
|
||||
|
||||
transactions = append(transactions, types.Transaction{
|
||||
TransactionKey: types.TransactionKey{
|
||||
BoardingTxid: u.Txid,
|
||||
@@ -1773,7 +1747,6 @@ func (a *covenantArkClient) getBoardingTxs(ctx context.Context) (transactions []
|
||||
Amount: u.Amount,
|
||||
Type: types.TxReceived,
|
||||
CreatedAt: u.CreatedAt,
|
||||
IsPending: pending,
|
||||
})
|
||||
}
|
||||
return
|
||||
@@ -1796,9 +1769,7 @@ func vtxosToTxsCovenant(
|
||||
for _, v := range append(spendable, spent...) {
|
||||
// get vtxo amount
|
||||
amount := int(v.Amount)
|
||||
if !v.Pending {
|
||||
continue
|
||||
}
|
||||
|
||||
// find other spent vtxos that spent this one
|
||||
relatedVtxos := findVtxosBySpentBy(spent, v.Txid)
|
||||
for _, r := range relatedVtxos {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -55,8 +55,8 @@ func main() {
|
||||
onboardAmount := uint64(1_0000_0000) // 1 BTC
|
||||
log.Infof("alice is onboarding with %d sats offchain...", onboardAmount)
|
||||
|
||||
log.Infof("alice claiming onboarding funds...")
|
||||
txid, err := aliceArkClient.Claim(ctx)
|
||||
log.Infof("alice settled the onboard funds...")
|
||||
txid, err := aliceArkClient.Settle(ctx)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -84,13 +84,13 @@ 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)
|
||||
log.Infof("alice is settling the onboard funds...")
|
||||
txid, err := aliceArkClient.Settle(ctx)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
log.Infof("alice claimed onboarding funds in round %s", txid)
|
||||
log.Infof("alice settled the onboard funds in round %s", txid)
|
||||
|
||||
fmt.Println("")
|
||||
log.Info("bob is setting up his ark wallet...")
|
||||
@@ -128,7 +128,7 @@ func main() {
|
||||
fmt.Println("")
|
||||
log.Infof("alice is sending %d sats to bob offchain...", amount)
|
||||
|
||||
if _, err = aliceArkClient.SendAsync(ctx, false, receivers); err != nil {
|
||||
if _, err = aliceArkClient.SendOffChain(ctx, false, receivers); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -158,13 +158,13 @@ func main() {
|
||||
log.Infof("bob offchain balance: %d", bobBalance.OffchainBalance.Total)
|
||||
|
||||
fmt.Println("")
|
||||
log.Info("bob is claiming the incoming payment...")
|
||||
roundTxid, err := bobArkClient.Claim(ctx)
|
||||
log.Info("bob is settling the received funds...")
|
||||
roundTxid, err := bobArkClient.Settle(ctx)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
log.Infof("bob claimed the incoming payment in round %s", roundTxid)
|
||||
log.Infof("bob settled the received funds in round %s", roundTxid)
|
||||
|
||||
time.Sleep(500 * time.Second)
|
||||
}
|
||||
|
||||
@@ -90,19 +90,19 @@
|
||||
}
|
||||
}
|
||||
|
||||
async function claimVtxos() {
|
||||
async function settleVtxos() {
|
||||
const password = document.getElementById("c_password").value;
|
||||
if (!password) {
|
||||
logMessage("Claim error: password is required");
|
||||
logMessage("Settle error: password is required");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await unlock(password);
|
||||
const txID = await claim();
|
||||
logMessage("Claimed money with tx ID: " + txID);
|
||||
const txID = await settle();
|
||||
logMessage("Settled money with tx ID: " + txID);
|
||||
} catch (err) {
|
||||
logMessage("Claim error: " + err.message);
|
||||
logMessage("Settle error: " + err.message);
|
||||
} finally {
|
||||
await lock(password);
|
||||
}
|
||||
@@ -166,7 +166,7 @@
|
||||
<input type="password" id="s_password" placeholder="password">
|
||||
</div>
|
||||
<div>
|
||||
<button onclick="claimVtxos()">Claim</button>
|
||||
<button onclick="settleVtxos()">Settle</button>
|
||||
<input type="password" id="c_password" placeholder="password">
|
||||
</div>
|
||||
<div>
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
|
||||
"github.com/ark-network/ark/common"
|
||||
"github.com/ark-network/ark/pkg/client-sdk/internal/utils"
|
||||
"github.com/ark-network/ark/pkg/client-sdk/types"
|
||||
"github.com/btcsuite/btcd/btcutil/psbt"
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/vulpemventures/go-elements/psetv2"
|
||||
@@ -24,39 +25,6 @@ const (
|
||||
LiquidExplorer = "liquid"
|
||||
)
|
||||
|
||||
type Utxo struct {
|
||||
Txid string
|
||||
Vout uint32
|
||||
Amount uint64
|
||||
Asset string // liquid only
|
||||
Delay uint
|
||||
SpendableAt time.Time
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
||||
func (u *Utxo) Sequence() (uint32, error) {
|
||||
return common.BIP68Sequence(u.Delay)
|
||||
}
|
||||
|
||||
func newUtxo(explorerUtxo ExplorerUtxo, delay uint) Utxo {
|
||||
utxoTime := explorerUtxo.Status.Blocktime
|
||||
createdAt := time.Unix(utxoTime, 0)
|
||||
if utxoTime == 0 {
|
||||
createdAt = time.Time{}
|
||||
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),
|
||||
CreatedAt: createdAt,
|
||||
}
|
||||
}
|
||||
|
||||
type ExplorerTx struct {
|
||||
Txid string `json:"txid"`
|
||||
Vout []struct {
|
||||
@@ -85,8 +53,8 @@ type SpentStatus struct {
|
||||
SpentBy string `json:"txid,omitempty"`
|
||||
}
|
||||
|
||||
func (e ExplorerUtxo) ToUtxo(delay uint) Utxo {
|
||||
return newUtxo(e, delay)
|
||||
func (e ExplorerUtxo) ToUtxo(delay uint, descriptor string) types.Utxo {
|
||||
return newUtxo(e, delay, descriptor)
|
||||
}
|
||||
|
||||
type Explorer interface {
|
||||
@@ -446,3 +414,23 @@ func parseBitcoinTx(txStr string) (string, string, error) {
|
||||
|
||||
return txhex, txid, nil
|
||||
}
|
||||
|
||||
func newUtxo(explorerUtxo ExplorerUtxo, delay uint, descriptor string) types.Utxo {
|
||||
utxoTime := explorerUtxo.Status.Blocktime
|
||||
createdAt := time.Unix(utxoTime, 0)
|
||||
if utxoTime == 0 {
|
||||
createdAt = time.Time{}
|
||||
utxoTime = time.Now().Unix()
|
||||
}
|
||||
|
||||
return types.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),
|
||||
CreatedAt: createdAt,
|
||||
Descriptor: descriptor,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
|
||||
"github.com/ark-network/ark/common"
|
||||
"github.com/ark-network/ark/pkg/client-sdk/client"
|
||||
"github.com/ark-network/ark/pkg/client-sdk/types"
|
||||
"github.com/btcsuite/btcd/btcec/v2"
|
||||
"github.com/btcsuite/btcd/btcutil"
|
||||
"github.com/btcsuite/btcd/chaincfg"
|
||||
@@ -23,10 +24,14 @@ import (
|
||||
)
|
||||
|
||||
func CoinSelect(
|
||||
vtxos []client.DescriptorVtxo, amount, dust uint64, sortByExpirationTime bool,
|
||||
) ([]client.DescriptorVtxo, uint64, error) {
|
||||
selected := make([]client.DescriptorVtxo, 0)
|
||||
notSelected := make([]client.DescriptorVtxo, 0)
|
||||
boardingUtxos []types.Utxo,
|
||||
vtxos []client.DescriptorVtxo,
|
||||
amount,
|
||||
dust uint64,
|
||||
sortByExpirationTime bool,
|
||||
) ([]types.Utxo, []client.DescriptorVtxo, uint64, error) {
|
||||
selected, notSelected := make([]client.DescriptorVtxo, 0), make([]client.DescriptorVtxo, 0)
|
||||
selectedBoarding, notSelectedBoarding := make([]types.Utxo, 0), make([]types.Utxo, 0)
|
||||
selectedAmount := uint64(0)
|
||||
|
||||
if sortByExpirationTime {
|
||||
@@ -38,6 +43,20 @@ func CoinSelect(
|
||||
|
||||
return vtxos[i].ExpiresAt.Before(*vtxos[j].ExpiresAt)
|
||||
})
|
||||
|
||||
sort.SliceStable(boardingUtxos, func(i, j int) bool {
|
||||
return boardingUtxos[i].SpendableAt.Before(boardingUtxos[j].SpendableAt)
|
||||
})
|
||||
}
|
||||
|
||||
for _, boardingUtxo := range boardingUtxos {
|
||||
if selectedAmount >= amount {
|
||||
notSelectedBoarding = append(notSelectedBoarding, boardingUtxo)
|
||||
break
|
||||
}
|
||||
|
||||
selectedBoarding = append(selectedBoarding, boardingUtxo)
|
||||
selectedAmount += boardingUtxo.Amount
|
||||
}
|
||||
|
||||
for _, vtxo := range vtxos {
|
||||
@@ -51,7 +70,7 @@ func CoinSelect(
|
||||
}
|
||||
|
||||
if selectedAmount < amount {
|
||||
return nil, 0, fmt.Errorf("not enough funds to cover amount %d", amount)
|
||||
return nil, nil, 0, fmt.Errorf("not enough funds to cover amount %d", amount)
|
||||
}
|
||||
|
||||
change := selectedAmount - amount
|
||||
@@ -60,10 +79,13 @@ func CoinSelect(
|
||||
if len(notSelected) > 0 {
|
||||
selected = append(selected, notSelected[0])
|
||||
change += notSelected[0].Amount
|
||||
} else if len(notSelectedBoarding) > 0 {
|
||||
selectedBoarding = append(selectedBoarding, notSelectedBoarding[0])
|
||||
change += notSelectedBoarding[0].Amount
|
||||
}
|
||||
}
|
||||
|
||||
return selected, change, nil
|
||||
return selectedBoarding, selected, change, nil
|
||||
}
|
||||
|
||||
func ParseLiquidAddress(addr string) (
|
||||
|
||||
@@ -3,6 +3,7 @@ package arksdk
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/ark-network/ark/pkg/client-sdk/client"
|
||||
grpcclient "github.com/ark-network/ark/pkg/client-sdk/client/grpc"
|
||||
restclient "github.com/ark-network/ark/pkg/client-sdk/client/rest"
|
||||
"github.com/ark-network/ark/pkg/client-sdk/internal/utils"
|
||||
@@ -123,3 +124,10 @@ type balanceRes struct {
|
||||
offchainBalanceByExpiration map[int64]uint64
|
||||
err error
|
||||
}
|
||||
|
||||
type CoinSelectOptions struct {
|
||||
// If true, coin selector will select coins closest to expiry first.
|
||||
WithExpirySorting bool
|
||||
// If specified, coin selector will select only coins in the list.
|
||||
OutpointsFilter []client.Outpoint
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ type Transaction struct {
|
||||
TransactionKey
|
||||
Amount uint64
|
||||
Type TxType
|
||||
IsPending bool
|
||||
Settled bool
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
||||
@@ -103,3 +103,19 @@ type TransactionEvent struct {
|
||||
Tx Transaction
|
||||
Event EventType
|
||||
}
|
||||
|
||||
type Utxo struct {
|
||||
Txid string
|
||||
VOut uint32
|
||||
Amount uint64
|
||||
Asset string // liquid only
|
||||
Delay uint
|
||||
SpendableAt time.Time
|
||||
CreatedAt time.Time
|
||||
Descriptor string
|
||||
Spent bool
|
||||
}
|
||||
|
||||
func (u *Utxo) Sequence() (uint32, error) {
|
||||
return common.BIP68Sequence(u.Delay)
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ func init() {
|
||||
js.Global().Set("sendOnChain", SendOnChainWrapper())
|
||||
js.Global().Set("sendOffChain", SendOffChainWrapper())
|
||||
js.Global().Set("sendAsync", SendAsyncWrapper())
|
||||
js.Global().Set("claim", ClaimWrapper())
|
||||
js.Global().Set("settle", SettleWrapper())
|
||||
js.Global().Set("unilateralRedeem", UnilateralRedeemWrapper())
|
||||
js.Global().Set("collaborativeRedeem", CollaborativeRedeemWrapper())
|
||||
js.Global().Set("getTransactionHistory", GetTransactionHistoryWrapper())
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
"time"
|
||||
|
||||
arksdk "github.com/ark-network/ark/pkg/client-sdk"
|
||||
"github.com/ark-network/ark/pkg/client-sdk/client"
|
||||
"github.com/ark-network/ark/pkg/client-sdk/wallet"
|
||||
singlekeywallet "github.com/ark-network/ark/pkg/client-sdk/wallet/singlekey"
|
||||
)
|
||||
@@ -186,17 +187,17 @@ func SendOnChainWrapper() js.Func {
|
||||
if len(args) != 1 {
|
||||
return nil, errors.New("invalid number of args")
|
||||
}
|
||||
receivers := make([]arksdk.Receiver, args[0].Length())
|
||||
for i := 0; i < args[0].Length(); i++ {
|
||||
receiver := args[0].Index(i)
|
||||
receivers[i] = arksdk.NewBitcoinReceiver(
|
||||
receiver.Get("To").String(), uint64(receiver.Get("Amount").Int()),
|
||||
)
|
||||
|
||||
receivers, err := parseReceivers(args[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
txID, err := arkSdkClient.SendOnChain(
|
||||
context.Background(), receivers,
|
||||
)
|
||||
if receivers == nil || len(receivers) == 0 {
|
||||
return nil, errors.New("no receivers specified")
|
||||
}
|
||||
|
||||
txID, err := arkSdkClient.SendOnChain(context.Background(), receivers)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -209,13 +210,11 @@ func SendOffChainWrapper() js.Func {
|
||||
if len(args) != 2 {
|
||||
return nil, errors.New("invalid number of args")
|
||||
}
|
||||
|
||||
withExpiryCoinselect := args[0].Bool()
|
||||
receivers := make([]arksdk.Receiver, args[1].Length())
|
||||
for i := 0; i < args[1].Length(); i++ {
|
||||
receiver := args[1].Index(i)
|
||||
receivers[i] = arksdk.NewBitcoinReceiver(
|
||||
receiver.Get("To").String(), uint64(receiver.Get("Amount").Int()),
|
||||
)
|
||||
receivers, err := parseReceivers(args[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
txID, err := arkSdkClient.SendOffChain(
|
||||
@@ -233,13 +232,15 @@ func SendAsyncWrapper() js.Func {
|
||||
if len(args) != 2 {
|
||||
return nil, errors.New("invalid number of args")
|
||||
}
|
||||
|
||||
withExpiryCoinselect := args[0].Bool()
|
||||
receivers := make([]arksdk.Receiver, args[1].Length())
|
||||
for i := 0; i < args[1].Length(); i++ {
|
||||
receiver := args[1].Index(i)
|
||||
receivers[i] = arksdk.NewBitcoinReceiver(
|
||||
receiver.Get("To").String(), uint64(receiver.Get("Amount").Int()),
|
||||
)
|
||||
receivers, err := parseReceivers(args[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if receivers == nil || len(receivers) == 0 {
|
||||
return nil, errors.New("no receivers specified")
|
||||
}
|
||||
|
||||
txID, err := arkSdkClient.SendAsync(
|
||||
@@ -252,13 +253,13 @@ func SendAsyncWrapper() js.Func {
|
||||
})
|
||||
}
|
||||
|
||||
func ClaimWrapper() js.Func {
|
||||
func SettleWrapper() js.Func {
|
||||
return JSPromise(func(args []js.Value) (interface{}, error) {
|
||||
if len(args) != 0 {
|
||||
return nil, errors.New("invalid number of args")
|
||||
}
|
||||
|
||||
resp, err := arkSdkClient.Claim(context.Background())
|
||||
resp, err := arkSdkClient.Settle(context.Background())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -306,7 +307,7 @@ func GetTransactionHistoryWrapper() js.Func {
|
||||
"redeemTxid": record.RedeemTxid,
|
||||
"amount": strconv.Itoa(int(record.Amount)),
|
||||
"type": record.Type,
|
||||
"isPending": record.IsPending,
|
||||
"settled": record.Settled,
|
||||
"createdAt": record.CreatedAt.Format(time.RFC3339),
|
||||
})
|
||||
}
|
||||
@@ -433,3 +434,63 @@ func JSPromise(fn promise) js.Func {
|
||||
return promiseConstructor.New(handler)
|
||||
})
|
||||
}
|
||||
|
||||
func parseReceivers(jsReceivers js.Value) ([]arksdk.Receiver, error) {
|
||||
if jsReceivers.IsNull() || jsReceivers.IsUndefined() {
|
||||
return nil, nil // Return nil slice if input is null or undefined
|
||||
}
|
||||
|
||||
if jsReceivers.Type() != js.TypeObject || jsReceivers.Get("length").Type() != js.TypeNumber {
|
||||
return nil, errors.New("invalid receivers argument: expected array")
|
||||
}
|
||||
|
||||
length := jsReceivers.Length()
|
||||
if length == 0 {
|
||||
return []arksdk.Receiver{}, nil // Return empty slice if input array is empty
|
||||
}
|
||||
|
||||
receivers := make([]arksdk.Receiver, length)
|
||||
for i := 0; i < length; i++ {
|
||||
receiver := jsReceivers.Index(i)
|
||||
if receiver.Type() != js.TypeObject {
|
||||
return nil, fmt.Errorf("invalid receiver at index %d: expected object", i)
|
||||
}
|
||||
|
||||
to := receiver.Get("To")
|
||||
amount := receiver.Get("Amount")
|
||||
if to.Type() != js.TypeString || amount.Type() != js.TypeNumber {
|
||||
return nil, fmt.Errorf("invalid receiver at index %d: expected 'To' (string) and 'Amount' (number)", i)
|
||||
}
|
||||
|
||||
receivers[i] = arksdk.NewBitcoinReceiver(to.String(), uint64(amount.Int()))
|
||||
}
|
||||
|
||||
return receivers, nil
|
||||
}
|
||||
|
||||
func parseOutpoints(jsOutpoints js.Value) ([]client.Outpoint, error) {
|
||||
if jsOutpoints.Length() == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
outpoints := make([]client.Outpoint, jsOutpoints.Length())
|
||||
for i := 0; i < jsOutpoints.Length(); i++ {
|
||||
jsOutpoint := jsOutpoints.Index(i)
|
||||
if jsOutpoint.Type() != js.TypeObject {
|
||||
return nil, fmt.Errorf("invalid outpoint at index %d: expected object", i)
|
||||
}
|
||||
|
||||
txid := jsOutpoint.Get("Txid")
|
||||
vout := jsOutpoint.Get("Vout")
|
||||
if txid.Type() != js.TypeString || vout.Type() != js.TypeNumber {
|
||||
return nil, fmt.Errorf("invalid outpoint at index %d: expected 'Txid' (string) and 'Vout' (number)", i)
|
||||
}
|
||||
|
||||
outpoints[i] = client.Outpoint{
|
||||
Txid: txid.String(),
|
||||
VOut: uint32(vout.Int()),
|
||||
}
|
||||
}
|
||||
|
||||
return outpoints, nil
|
||||
}
|
||||
|
||||
@@ -39,5 +39,3 @@ func PrintBuildInfo() {
|
||||
func GetVersion() string {
|
||||
return Version
|
||||
}
|
||||
|
||||
// You can add more build-related functions here as needed
|
||||
|
||||
@@ -21,8 +21,3 @@ func main() {
|
||||
println("ARK SDK WebAssembly module initialized")
|
||||
<-c
|
||||
}
|
||||
|
||||
func init() {
|
||||
// You can add any additional initialization here if needed
|
||||
// This runs before the main function
|
||||
}
|
||||
|
||||
@@ -23,8 +23,8 @@ help:
|
||||
## intergrationtest: runs integration tests
|
||||
integrationtest:
|
||||
@echo "Running integration tests..."
|
||||
@go test -v -count 1 -timeout 400s github.com/ark-network/ark/server/test/e2e/covenant
|
||||
@go test -v -count 1 -timeout 400s github.com/ark-network/ark/server/test/e2e/covenantless
|
||||
@go test -v -count 1 -timeout 500s github.com/ark-network/ark/server/test/e2e/covenant
|
||||
@go test -v -count 1 -timeout 500s github.com/ark-network/ark/server/test/e2e/covenantless
|
||||
|
||||
## lint: lint codebase
|
||||
lint:
|
||||
|
||||
@@ -51,10 +51,7 @@ type covenantlessService struct {
|
||||
currentRoundLock sync.Mutex
|
||||
currentRound *domain.Round
|
||||
treeSigningSessions map[string]*musigSigningSession
|
||||
asyncPaymentsCache map[string]struct { // redeem txid -> receivers
|
||||
receivers []domain.Receiver
|
||||
expireAt int64
|
||||
}
|
||||
asyncPaymentsCache map[string]asyncPaymentData
|
||||
}
|
||||
|
||||
func NewCovenantlessService(
|
||||
@@ -69,11 +66,6 @@ func NewCovenantlessService(
|
||||
return nil, fmt.Errorf("failed to fetch pubkey: %s", err)
|
||||
}
|
||||
|
||||
asyncPaymentsCache := make(map[string]struct {
|
||||
receivers []domain.Receiver
|
||||
expireAt int64
|
||||
})
|
||||
|
||||
svc := &covenantlessService{
|
||||
network: network,
|
||||
pubkey: pubkey,
|
||||
@@ -90,7 +82,7 @@ func NewCovenantlessService(
|
||||
eventsCh: make(chan domain.RoundEvent),
|
||||
transactionEventsCh: make(chan TransactionEvent),
|
||||
currentRoundLock: sync.Mutex{},
|
||||
asyncPaymentsCache: asyncPaymentsCache,
|
||||
asyncPaymentsCache: make(map[string]asyncPaymentData),
|
||||
treeSigningSessions: make(map[string]*musigSigningSession),
|
||||
boardingExitDelay: boardingExitDelay,
|
||||
}
|
||||
@@ -269,19 +261,16 @@ func (s *covenantlessService) CompleteAsyncPayment(
|
||||
|
||||
vtxoPubkey := hex.EncodeToString(schnorr.SerializePubKey(vtxoTapKey))
|
||||
|
||||
// all pending except the last one
|
||||
isPending := outIndex < len(asyncPayData.receivers)-1
|
||||
|
||||
vtxos = append(vtxos, domain.Vtxo{
|
||||
VtxoKey: domain.VtxoKey{
|
||||
Txid: redeemTxid,
|
||||
VOut: uint32(outIndex),
|
||||
},
|
||||
Pubkey: vtxoPubkey,
|
||||
Amount: uint64(out.Value),
|
||||
ExpireAt: asyncPayData.expireAt,
|
||||
RedeemTx: redeemTx,
|
||||
Pending: isPending,
|
||||
Pubkey: vtxoPubkey,
|
||||
Amount: uint64(out.Value),
|
||||
ExpireAt: asyncPayData.expireAt,
|
||||
RoundTxid: asyncPayData.roundTxid,
|
||||
RedeemTx: redeemTx,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -338,6 +327,8 @@ func (s *covenantlessService) CreateAsyncPayment(
|
||||
vtxosInputs := make([]domain.Vtxo, 0, len(inputs))
|
||||
|
||||
expiration := vtxos[0].ExpireAt
|
||||
roundTxid := vtxos[0].RoundTxid
|
||||
|
||||
for _, vtxo := range vtxos {
|
||||
if vtxo.Spent {
|
||||
return "", fmt.Errorf("all vtxos must be unspent")
|
||||
@@ -350,11 +341,9 @@ func (s *covenantlessService) CreateAsyncPayment(
|
||||
if vtxo.Swept {
|
||||
return "", fmt.Errorf("all vtxos must be swept")
|
||||
}
|
||||
if vtxo.Pending {
|
||||
return "", fmt.Errorf("all vtxos must be claimed")
|
||||
}
|
||||
|
||||
if vtxo.ExpireAt < expiration {
|
||||
roundTxid = vtxo.RoundTxid
|
||||
expiration = vtxo.ExpireAt
|
||||
}
|
||||
|
||||
@@ -373,12 +362,10 @@ func (s *covenantlessService) CreateAsyncPayment(
|
||||
return "", fmt.Errorf("failed to parse redeem tx: %s", err)
|
||||
}
|
||||
|
||||
s.asyncPaymentsCache[redeemPtx.UnsignedTx.TxID()] = struct {
|
||||
receivers []domain.Receiver
|
||||
expireAt int64
|
||||
}{
|
||||
s.asyncPaymentsCache[redeemPtx.UnsignedTx.TxID()] = asyncPaymentData{
|
||||
receivers: receivers,
|
||||
expireAt: expiration,
|
||||
roundTxid: roundTxid,
|
||||
}
|
||||
|
||||
return redeemTx, nil
|
||||
@@ -1588,6 +1575,12 @@ func findForfeitTxBitcoin(
|
||||
return "", fmt.Errorf("forfeit tx not found")
|
||||
}
|
||||
|
||||
type asyncPaymentData struct {
|
||||
receivers []domain.Receiver
|
||||
expireAt int64
|
||||
roundTxid string
|
||||
}
|
||||
|
||||
// musigSigningSession holds the state of ephemeral nonces and signatures in order to coordinate the signing of the tree
|
||||
type musigSigningSession struct {
|
||||
lock sync.Mutex
|
||||
|
||||
@@ -166,6 +166,24 @@ func (m *paymentsMap) update(payment domain.Payment) error {
|
||||
return fmt.Errorf("payment %s not found", payment.Id)
|
||||
}
|
||||
|
||||
sumOfInputs := uint64(0)
|
||||
for _, input := range payment.Inputs {
|
||||
sumOfInputs += input.Amount
|
||||
}
|
||||
|
||||
for _, boardingInput := range p.boardingInputs {
|
||||
sumOfInputs += boardingInput.Amount
|
||||
}
|
||||
|
||||
sumOfOutputs := uint64(0)
|
||||
for _, receiver := range payment.Receivers {
|
||||
sumOfOutputs += receiver.Amount
|
||||
}
|
||||
|
||||
if sumOfInputs != sumOfOutputs {
|
||||
return fmt.Errorf("sum of inputs %d does not match sum of outputs %d", sumOfInputs, sumOfOutputs)
|
||||
}
|
||||
|
||||
p.Payment = payment
|
||||
|
||||
return nil
|
||||
|
||||
@@ -123,5 +123,4 @@ type Vtxo struct {
|
||||
Swept bool
|
||||
ExpireAt int64
|
||||
RedeemTx string // empty if in-round vtxo
|
||||
Pending bool
|
||||
}
|
||||
|
||||
@@ -54,7 +54,6 @@ CREATE TABLE IF NOT EXISTS vtxo (
|
||||
expire_at INTEGER NOT NULL,
|
||||
payment_id TEXT,
|
||||
redeem_tx TEXT,
|
||||
pending BOOLEAN NOT NULL,
|
||||
PRIMARY KEY (txid, vout),
|
||||
FOREIGN KEY (payment_id) REFERENCES payment(id)
|
||||
);
|
||||
|
||||
@@ -33,7 +33,6 @@ type PaymentVtxoVw struct {
|
||||
ExpireAt sql.NullInt64
|
||||
PaymentID sql.NullString
|
||||
RedeemTx sql.NullString
|
||||
Pending sql.NullBool
|
||||
}
|
||||
|
||||
type Receiver struct {
|
||||
@@ -100,5 +99,4 @@ type Vtxo struct {
|
||||
ExpireAt int64
|
||||
PaymentID sql.NullString
|
||||
RedeemTx sql.NullString
|
||||
Pending bool
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ func (q *Queries) MarkVtxoAsSwept(ctx context.Context, arg MarkVtxoAsSweptParams
|
||||
}
|
||||
|
||||
const selectNotRedeemedVtxos = `-- name: SelectNotRedeemedVtxos :many
|
||||
SELECT vtxo.txid, vtxo.vout, vtxo.pubkey, vtxo.amount, vtxo.pool_tx, vtxo.spent_by, vtxo.spent, vtxo.redeemed, vtxo.swept, vtxo.expire_at, vtxo.payment_id, vtxo.redeem_tx, vtxo.pending FROM vtxo
|
||||
SELECT vtxo.txid, vtxo.vout, vtxo.pubkey, vtxo.amount, vtxo.pool_tx, vtxo.spent_by, vtxo.spent, vtxo.redeemed, vtxo.swept, vtxo.expire_at, vtxo.payment_id, vtxo.redeem_tx FROM vtxo
|
||||
WHERE redeemed = false
|
||||
`
|
||||
|
||||
@@ -84,7 +84,6 @@ func (q *Queries) SelectNotRedeemedVtxos(ctx context.Context) ([]SelectNotRedeem
|
||||
&i.Vtxo.ExpireAt,
|
||||
&i.Vtxo.PaymentID,
|
||||
&i.Vtxo.RedeemTx,
|
||||
&i.Vtxo.Pending,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -100,7 +99,7 @@ func (q *Queries) SelectNotRedeemedVtxos(ctx context.Context) ([]SelectNotRedeem
|
||||
}
|
||||
|
||||
const selectNotRedeemedVtxosWithPubkey = `-- name: SelectNotRedeemedVtxosWithPubkey :many
|
||||
SELECT vtxo.txid, vtxo.vout, vtxo.pubkey, vtxo.amount, vtxo.pool_tx, vtxo.spent_by, vtxo.spent, vtxo.redeemed, vtxo.swept, vtxo.expire_at, vtxo.payment_id, vtxo.redeem_tx, vtxo.pending FROM vtxo
|
||||
SELECT vtxo.txid, vtxo.vout, vtxo.pubkey, vtxo.amount, vtxo.pool_tx, vtxo.spent_by, vtxo.spent, vtxo.redeemed, vtxo.swept, vtxo.expire_at, vtxo.payment_id, vtxo.redeem_tx FROM vtxo
|
||||
WHERE redeemed = false AND pubkey = ?
|
||||
`
|
||||
|
||||
@@ -130,7 +129,6 @@ func (q *Queries) SelectNotRedeemedVtxosWithPubkey(ctx context.Context, pubkey s
|
||||
&i.Vtxo.ExpireAt,
|
||||
&i.Vtxo.PaymentID,
|
||||
&i.Vtxo.RedeemTx,
|
||||
&i.Vtxo.Pending,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -209,7 +207,7 @@ SELECT round.id, round.starting_timestamp, round.ending_timestamp, round.ended,
|
||||
round_payment_vw.id, round_payment_vw.round_id,
|
||||
round_tx_vw.id, round_tx_vw.tx, round_tx_vw.round_id, round_tx_vw.type, round_tx_vw.position, round_tx_vw.txid, round_tx_vw.tree_level, round_tx_vw.parent_txid, round_tx_vw.is_leaf,
|
||||
payment_receiver_vw.payment_id, payment_receiver_vw.pubkey, payment_receiver_vw.onchain_address, payment_receiver_vw.amount,
|
||||
payment_vtxo_vw.txid, payment_vtxo_vw.vout, payment_vtxo_vw.pubkey, payment_vtxo_vw.amount, payment_vtxo_vw.pool_tx, payment_vtxo_vw.spent_by, payment_vtxo_vw.spent, payment_vtxo_vw.redeemed, payment_vtxo_vw.swept, payment_vtxo_vw.expire_at, payment_vtxo_vw.payment_id, payment_vtxo_vw.redeem_tx, payment_vtxo_vw.pending
|
||||
payment_vtxo_vw.txid, payment_vtxo_vw.vout, payment_vtxo_vw.pubkey, payment_vtxo_vw.amount, payment_vtxo_vw.pool_tx, payment_vtxo_vw.spent_by, payment_vtxo_vw.spent, payment_vtxo_vw.redeemed, payment_vtxo_vw.swept, payment_vtxo_vw.expire_at, payment_vtxo_vw.payment_id, payment_vtxo_vw.redeem_tx
|
||||
FROM round
|
||||
LEFT OUTER JOIN round_payment_vw ON round.id=round_payment_vw.round_id
|
||||
LEFT OUTER JOIN round_tx_vw ON round.id=round_tx_vw.round_id
|
||||
@@ -275,7 +273,6 @@ func (q *Queries) SelectRoundWithRoundId(ctx context.Context, id string) ([]Sele
|
||||
&i.PaymentVtxoVw.ExpireAt,
|
||||
&i.PaymentVtxoVw.PaymentID,
|
||||
&i.PaymentVtxoVw.RedeemTx,
|
||||
&i.PaymentVtxoVw.Pending,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -295,7 +292,7 @@ SELECT round.id, round.starting_timestamp, round.ending_timestamp, round.ended,
|
||||
round_payment_vw.id, round_payment_vw.round_id,
|
||||
round_tx_vw.id, round_tx_vw.tx, round_tx_vw.round_id, round_tx_vw.type, round_tx_vw.position, round_tx_vw.txid, round_tx_vw.tree_level, round_tx_vw.parent_txid, round_tx_vw.is_leaf,
|
||||
payment_receiver_vw.payment_id, payment_receiver_vw.pubkey, payment_receiver_vw.onchain_address, payment_receiver_vw.amount,
|
||||
payment_vtxo_vw.txid, payment_vtxo_vw.vout, payment_vtxo_vw.pubkey, payment_vtxo_vw.amount, payment_vtxo_vw.pool_tx, payment_vtxo_vw.spent_by, payment_vtxo_vw.spent, payment_vtxo_vw.redeemed, payment_vtxo_vw.swept, payment_vtxo_vw.expire_at, payment_vtxo_vw.payment_id, payment_vtxo_vw.redeem_tx, payment_vtxo_vw.pending
|
||||
payment_vtxo_vw.txid, payment_vtxo_vw.vout, payment_vtxo_vw.pubkey, payment_vtxo_vw.amount, payment_vtxo_vw.pool_tx, payment_vtxo_vw.spent_by, payment_vtxo_vw.spent, payment_vtxo_vw.redeemed, payment_vtxo_vw.swept, payment_vtxo_vw.expire_at, payment_vtxo_vw.payment_id, payment_vtxo_vw.redeem_tx
|
||||
FROM round
|
||||
LEFT OUTER JOIN round_payment_vw ON round.id=round_payment_vw.round_id
|
||||
LEFT OUTER JOIN round_tx_vw ON round.id=round_tx_vw.round_id
|
||||
@@ -361,7 +358,6 @@ func (q *Queries) SelectRoundWithRoundTxId(ctx context.Context, txid string) ([]
|
||||
&i.PaymentVtxoVw.ExpireAt,
|
||||
&i.PaymentVtxoVw.PaymentID,
|
||||
&i.PaymentVtxoVw.RedeemTx,
|
||||
&i.PaymentVtxoVw.Pending,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -381,7 +377,7 @@ SELECT round.id, round.starting_timestamp, round.ending_timestamp, round.ended,
|
||||
round_payment_vw.id, round_payment_vw.round_id,
|
||||
round_tx_vw.id, round_tx_vw.tx, round_tx_vw.round_id, round_tx_vw.type, round_tx_vw.position, round_tx_vw.txid, round_tx_vw.tree_level, round_tx_vw.parent_txid, round_tx_vw.is_leaf,
|
||||
payment_receiver_vw.payment_id, payment_receiver_vw.pubkey, payment_receiver_vw.onchain_address, payment_receiver_vw.amount,
|
||||
payment_vtxo_vw.txid, payment_vtxo_vw.vout, payment_vtxo_vw.pubkey, payment_vtxo_vw.amount, payment_vtxo_vw.pool_tx, payment_vtxo_vw.spent_by, payment_vtxo_vw.spent, payment_vtxo_vw.redeemed, payment_vtxo_vw.swept, payment_vtxo_vw.expire_at, payment_vtxo_vw.payment_id, payment_vtxo_vw.redeem_tx, payment_vtxo_vw.pending
|
||||
payment_vtxo_vw.txid, payment_vtxo_vw.vout, payment_vtxo_vw.pubkey, payment_vtxo_vw.amount, payment_vtxo_vw.pool_tx, payment_vtxo_vw.spent_by, payment_vtxo_vw.spent, payment_vtxo_vw.redeemed, payment_vtxo_vw.swept, payment_vtxo_vw.expire_at, payment_vtxo_vw.payment_id, payment_vtxo_vw.redeem_tx
|
||||
FROM round
|
||||
LEFT OUTER JOIN round_payment_vw ON round.id=round_payment_vw.round_id
|
||||
LEFT OUTER JOIN round_tx_vw ON round.id=round_tx_vw.round_id
|
||||
@@ -447,7 +443,6 @@ func (q *Queries) SelectSweepableRounds(ctx context.Context) ([]SelectSweepableR
|
||||
&i.PaymentVtxoVw.ExpireAt,
|
||||
&i.PaymentVtxoVw.PaymentID,
|
||||
&i.PaymentVtxoVw.RedeemTx,
|
||||
&i.PaymentVtxoVw.Pending,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -463,7 +458,7 @@ func (q *Queries) SelectSweepableRounds(ctx context.Context) ([]SelectSweepableR
|
||||
}
|
||||
|
||||
const selectSweepableVtxos = `-- name: SelectSweepableVtxos :many
|
||||
SELECT vtxo.txid, vtxo.vout, vtxo.pubkey, vtxo.amount, vtxo.pool_tx, vtxo.spent_by, vtxo.spent, vtxo.redeemed, vtxo.swept, vtxo.expire_at, vtxo.payment_id, vtxo.redeem_tx, vtxo.pending FROM vtxo
|
||||
SELECT vtxo.txid, vtxo.vout, vtxo.pubkey, vtxo.amount, vtxo.pool_tx, vtxo.spent_by, vtxo.spent, vtxo.redeemed, vtxo.swept, vtxo.expire_at, vtxo.payment_id, vtxo.redeem_tx FROM vtxo
|
||||
WHERE redeemed = false AND swept = false
|
||||
`
|
||||
|
||||
@@ -493,7 +488,6 @@ func (q *Queries) SelectSweepableVtxos(ctx context.Context) ([]SelectSweepableVt
|
||||
&i.Vtxo.ExpireAt,
|
||||
&i.Vtxo.PaymentID,
|
||||
&i.Vtxo.RedeemTx,
|
||||
&i.Vtxo.Pending,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -513,7 +507,7 @@ SELECT round.id, round.starting_timestamp, round.ending_timestamp, round.ended,
|
||||
round_payment_vw.id, round_payment_vw.round_id,
|
||||
round_tx_vw.id, round_tx_vw.tx, round_tx_vw.round_id, round_tx_vw.type, round_tx_vw.position, round_tx_vw.txid, round_tx_vw.tree_level, round_tx_vw.parent_txid, round_tx_vw.is_leaf,
|
||||
payment_receiver_vw.payment_id, payment_receiver_vw.pubkey, payment_receiver_vw.onchain_address, payment_receiver_vw.amount,
|
||||
payment_vtxo_vw.txid, payment_vtxo_vw.vout, payment_vtxo_vw.pubkey, payment_vtxo_vw.amount, payment_vtxo_vw.pool_tx, payment_vtxo_vw.spent_by, payment_vtxo_vw.spent, payment_vtxo_vw.redeemed, payment_vtxo_vw.swept, payment_vtxo_vw.expire_at, payment_vtxo_vw.payment_id, payment_vtxo_vw.redeem_tx, payment_vtxo_vw.pending
|
||||
payment_vtxo_vw.txid, payment_vtxo_vw.vout, payment_vtxo_vw.pubkey, payment_vtxo_vw.amount, payment_vtxo_vw.pool_tx, payment_vtxo_vw.spent_by, payment_vtxo_vw.spent, payment_vtxo_vw.redeemed, payment_vtxo_vw.swept, payment_vtxo_vw.expire_at, payment_vtxo_vw.payment_id, payment_vtxo_vw.redeem_tx
|
||||
FROM round
|
||||
LEFT OUTER JOIN round_payment_vw ON round.id=round_payment_vw.round_id
|
||||
LEFT OUTER JOIN round_tx_vw ON round.id=round_tx_vw.round_id
|
||||
@@ -579,7 +573,6 @@ func (q *Queries) SelectSweptRounds(ctx context.Context) ([]SelectSweptRoundsRow
|
||||
&i.PaymentVtxoVw.ExpireAt,
|
||||
&i.PaymentVtxoVw.PaymentID,
|
||||
&i.PaymentVtxoVw.RedeemTx,
|
||||
&i.PaymentVtxoVw.Pending,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -595,7 +588,7 @@ func (q *Queries) SelectSweptRounds(ctx context.Context) ([]SelectSweptRoundsRow
|
||||
}
|
||||
|
||||
const selectVtxoByOutpoint = `-- name: SelectVtxoByOutpoint :one
|
||||
SELECT vtxo.txid, vtxo.vout, vtxo.pubkey, vtxo.amount, vtxo.pool_tx, vtxo.spent_by, vtxo.spent, vtxo.redeemed, vtxo.swept, vtxo.expire_at, vtxo.payment_id, vtxo.redeem_tx, vtxo.pending FROM vtxo
|
||||
SELECT vtxo.txid, vtxo.vout, vtxo.pubkey, vtxo.amount, vtxo.pool_tx, vtxo.spent_by, vtxo.spent, vtxo.redeemed, vtxo.swept, vtxo.expire_at, vtxo.payment_id, vtxo.redeem_tx FROM vtxo
|
||||
WHERE txid = ? AND vout = ?
|
||||
`
|
||||
|
||||
@@ -624,13 +617,12 @@ func (q *Queries) SelectVtxoByOutpoint(ctx context.Context, arg SelectVtxoByOutp
|
||||
&i.Vtxo.ExpireAt,
|
||||
&i.Vtxo.PaymentID,
|
||||
&i.Vtxo.RedeemTx,
|
||||
&i.Vtxo.Pending,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const selectVtxosByPoolTxid = `-- name: SelectVtxosByPoolTxid :many
|
||||
SELECT vtxo.txid, vtxo.vout, vtxo.pubkey, vtxo.amount, vtxo.pool_tx, vtxo.spent_by, vtxo.spent, vtxo.redeemed, vtxo.swept, vtxo.expire_at, vtxo.payment_id, vtxo.redeem_tx, vtxo.pending FROM vtxo
|
||||
SELECT vtxo.txid, vtxo.vout, vtxo.pubkey, vtxo.amount, vtxo.pool_tx, vtxo.spent_by, vtxo.spent, vtxo.redeemed, vtxo.swept, vtxo.expire_at, vtxo.payment_id, vtxo.redeem_tx FROM vtxo
|
||||
WHERE pool_tx = ?
|
||||
`
|
||||
|
||||
@@ -660,7 +652,6 @@ func (q *Queries) SelectVtxosByPoolTxid(ctx context.Context, poolTx string) ([]S
|
||||
&i.Vtxo.ExpireAt,
|
||||
&i.Vtxo.PaymentID,
|
||||
&i.Vtxo.RedeemTx,
|
||||
&i.Vtxo.Pending,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -847,8 +838,8 @@ func (q *Queries) UpsertTransaction(ctx context.Context, arg UpsertTransactionPa
|
||||
}
|
||||
|
||||
const upsertVtxo = `-- name: UpsertVtxo :exec
|
||||
INSERT INTO vtxo (txid, vout, pubkey, amount, pool_tx, spent_by, spent, redeemed, swept, expire_at, redeem_tx, pending)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT(txid, vout) DO UPDATE SET
|
||||
INSERT INTO vtxo (txid, vout, pubkey, amount, pool_tx, spent_by, spent, redeemed, swept, expire_at, redeem_tx)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT(txid, vout) DO UPDATE SET
|
||||
pubkey = EXCLUDED.pubkey,
|
||||
amount = EXCLUDED.amount,
|
||||
pool_tx = EXCLUDED.pool_tx,
|
||||
@@ -857,8 +848,7 @@ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT(txid, vout) DO UPDATE SE
|
||||
redeemed = EXCLUDED.redeemed,
|
||||
swept = EXCLUDED.swept,
|
||||
expire_at = EXCLUDED.expire_at,
|
||||
redeem_tx = EXCLUDED.redeem_tx,
|
||||
pending = EXCLUDED.pending
|
||||
redeem_tx = EXCLUDED.redeem_tx
|
||||
`
|
||||
|
||||
type UpsertVtxoParams struct {
|
||||
@@ -873,7 +863,6 @@ type UpsertVtxoParams struct {
|
||||
Swept bool
|
||||
ExpireAt int64
|
||||
RedeemTx sql.NullString
|
||||
Pending bool
|
||||
}
|
||||
|
||||
func (q *Queries) UpsertVtxo(ctx context.Context, arg UpsertVtxoParams) error {
|
||||
@@ -889,7 +878,6 @@ func (q *Queries) UpsertVtxo(ctx context.Context, arg UpsertVtxoParams) error {
|
||||
arg.Swept,
|
||||
arg.ExpireAt,
|
||||
arg.RedeemTx,
|
||||
arg.Pending,
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -112,8 +112,8 @@ SELECT id FROM round WHERE starting_timestamp > ? AND starting_timestamp < ?;
|
||||
SELECT id FROM round;
|
||||
|
||||
-- name: UpsertVtxo :exec
|
||||
INSERT INTO vtxo (txid, vout, pubkey, amount, pool_tx, spent_by, spent, redeemed, swept, expire_at, redeem_tx, pending)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT(txid, vout) DO UPDATE SET
|
||||
INSERT INTO vtxo (txid, vout, pubkey, amount, pool_tx, spent_by, spent, redeemed, swept, expire_at, redeem_tx)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT(txid, vout) DO UPDATE SET
|
||||
pubkey = EXCLUDED.pubkey,
|
||||
amount = EXCLUDED.amount,
|
||||
pool_tx = EXCLUDED.pool_tx,
|
||||
@@ -122,8 +122,7 @@ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT(txid, vout) DO UPDATE SE
|
||||
redeemed = EXCLUDED.redeemed,
|
||||
swept = EXCLUDED.swept,
|
||||
expire_at = EXCLUDED.expire_at,
|
||||
redeem_tx = EXCLUDED.redeem_tx,
|
||||
pending = EXCLUDED.pending;
|
||||
redeem_tx = EXCLUDED.redeem_tx;
|
||||
|
||||
-- name: SelectSweepableVtxos :many
|
||||
SELECT sqlc.embed(vtxo) FROM vtxo
|
||||
|
||||
@@ -51,7 +51,6 @@ func (v *vxtoRepository) AddVtxos(ctx context.Context, vtxos []domain.Vtxo) erro
|
||||
Swept: vtxo.Swept,
|
||||
ExpireAt: vtxo.ExpireAt,
|
||||
RedeemTx: sql.NullString{String: vtxo.RedeemTx, Valid: true},
|
||||
Pending: vtxo.Pending,
|
||||
},
|
||||
); err != nil {
|
||||
return err
|
||||
@@ -259,7 +258,6 @@ func rowToVtxo(row queries.Vtxo) domain.Vtxo {
|
||||
Swept: row.Swept,
|
||||
ExpireAt: row.ExpireAt,
|
||||
RedeemTx: row.RedeemTx.String,
|
||||
Pending: row.Pending,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -782,9 +782,9 @@ func (s *service) Status(ctx context.Context) (ports.WalletStatus, error) {
|
||||
|
||||
w := s.wallet.InternalWallet()
|
||||
return status{
|
||||
true,
|
||||
!w.Manager.IsLocked(),
|
||||
w.ChainSynced(),
|
||||
initialized: true,
|
||||
unlocked: !w.Manager.IsLocked(),
|
||||
synced: s.isSynced,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -124,7 +124,7 @@ func (v vtxoList) toProto() []*arkv1.Vtxo {
|
||||
SpentBy: vv.SpentBy,
|
||||
Swept: vv.Swept,
|
||||
RedeemTx: vv.RedeemTx,
|
||||
Pending: vv.Pending,
|
||||
IsOor: len(vv.RedeemTx) > 0,
|
||||
Pubkey: vv.Pubkey,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ func TestSendOffchain(t *testing.T) {
|
||||
|
||||
time.Sleep(5 * time.Second)
|
||||
|
||||
_, err = runArkCommand("claim", "--password", utils.Password)
|
||||
_, err = runArkCommand("settle", "--password", utils.Password)
|
||||
require.NoError(t, err)
|
||||
|
||||
time.Sleep(3 * time.Second)
|
||||
@@ -101,7 +101,7 @@ func TestUnilateralExit(t *testing.T) {
|
||||
|
||||
time.Sleep(5 * time.Second)
|
||||
|
||||
_, err = runArkCommand("claim", "--password", utils.Password)
|
||||
_, err = runArkCommand("settle", "--password", utils.Password)
|
||||
require.NoError(t, err)
|
||||
|
||||
time.Sleep(3 * time.Second)
|
||||
@@ -142,7 +142,7 @@ func TestCollaborativeExit(t *testing.T) {
|
||||
|
||||
time.Sleep(5 * time.Second)
|
||||
|
||||
_, err = runArkCommand("claim", "--password", utils.Password)
|
||||
_, err = runArkCommand("settle", "--password", utils.Password)
|
||||
require.NoError(t, err)
|
||||
|
||||
time.Sleep(3 * time.Second)
|
||||
@@ -164,7 +164,7 @@ func TestReactToSpentVtxosRedemption(t *testing.T) {
|
||||
|
||||
time.Sleep(5 * time.Second)
|
||||
|
||||
_, err = client.Claim(ctx)
|
||||
_, err = client.Settle(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
time.Sleep(3 * time.Second)
|
||||
@@ -216,7 +216,7 @@ func TestSweep(t *testing.T) {
|
||||
|
||||
time.Sleep(5 * time.Second)
|
||||
|
||||
_, err = runArkCommand("claim", "--password", utils.Password)
|
||||
_, err = runArkCommand("settle", "--password", utils.Password)
|
||||
require.NoError(t, err)
|
||||
|
||||
time.Sleep(3 * time.Second)
|
||||
|
||||
@@ -77,7 +77,7 @@ func TestSendOffchain(t *testing.T) {
|
||||
|
||||
time.Sleep(5 * time.Second)
|
||||
|
||||
_, err = runClarkCommand("claim", "--password", utils.Password)
|
||||
_, err = runClarkCommand("settle", "--password", utils.Password)
|
||||
require.NoError(t, err)
|
||||
|
||||
time.Sleep(3 * time.Second)
|
||||
@@ -91,7 +91,7 @@ func TestSendOffchain(t *testing.T) {
|
||||
require.NoError(t, json.Unmarshal([]byte(balanceStr), &balance))
|
||||
require.NotZero(t, balance.Offchain.Total)
|
||||
|
||||
_, err = runClarkCommand("claim", "--password", utils.Password)
|
||||
_, err = runClarkCommand("settle", "--password", utils.Password)
|
||||
require.NoError(t, err)
|
||||
|
||||
balanceStr, err = runClarkCommand("balance")
|
||||
@@ -113,7 +113,7 @@ func TestUnilateralExit(t *testing.T) {
|
||||
|
||||
time.Sleep(5 * time.Second)
|
||||
|
||||
_, err = runClarkCommand("claim", "--password", utils.Password)
|
||||
_, err = runClarkCommand("settle", "--password", utils.Password)
|
||||
require.NoError(t, err)
|
||||
|
||||
time.Sleep(3 * time.Second)
|
||||
@@ -155,11 +155,6 @@ func TestCollaborativeExit(t *testing.T) {
|
||||
|
||||
time.Sleep(5 * time.Second)
|
||||
|
||||
_, err = runClarkCommand("claim", "--password", utils.Password)
|
||||
require.NoError(t, err)
|
||||
|
||||
time.Sleep(3 * time.Second)
|
||||
|
||||
_, err = runClarkCommand("redeem", "--amount", "1000", "--address", redeemAddress, "--password", utils.Password)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
@@ -177,7 +172,7 @@ func TestReactToSpentVtxosRedemption(t *testing.T) {
|
||||
|
||||
time.Sleep(5 * time.Second)
|
||||
|
||||
_, err = client.Claim(ctx)
|
||||
_, err = client.Settle(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = client.SendOffChain(ctx, false, []arksdk.Receiver{arksdk.NewBitcoinReceiver(offchainAddress, 1000)})
|
||||
@@ -217,71 +212,105 @@ func TestReactToSpentVtxosRedemption(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestReactToAsyncSpentVtxosRedemption(t *testing.T) {
|
||||
t.Run("receiver claimed funds", func(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
sdkClient, grpcClient := setupArkSDK(t)
|
||||
defer grpcClient.Close()
|
||||
ctx := context.Background()
|
||||
sdkClient, grpcClient := setupArkSDK(t)
|
||||
defer grpcClient.Close()
|
||||
|
||||
offchainAddress, boardingAddress, err := sdkClient.Receive(ctx)
|
||||
require.NoError(t, err)
|
||||
offchainAddress, boardingAddress, err := sdkClient.Receive(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = utils.RunCommand("nigiri", "faucet", boardingAddress)
|
||||
require.NoError(t, err)
|
||||
_, err = utils.RunCommand("nigiri", "faucet", boardingAddress)
|
||||
require.NoError(t, err)
|
||||
|
||||
time.Sleep(5 * time.Second)
|
||||
time.Sleep(5 * time.Second)
|
||||
|
||||
roundId, err := sdkClient.Claim(ctx)
|
||||
require.NoError(t, err)
|
||||
roundId, err := sdkClient.Settle(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = utils.GenerateBlock()
|
||||
require.NoError(t, err)
|
||||
err = utils.GenerateBlock()
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = sdkClient.SendAsync(ctx, false, []arksdk.Receiver{arksdk.NewBitcoinReceiver(offchainAddress, 1000)})
|
||||
require.NoError(t, err)
|
||||
_, err = sdkClient.SendOffChain(ctx, false, []arksdk.Receiver{arksdk.NewBitcoinReceiver(offchainAddress, 1000)})
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = sdkClient.Claim(ctx)
|
||||
require.NoError(t, err)
|
||||
_, err = sdkClient.Settle(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
time.Sleep(5 * time.Second)
|
||||
time.Sleep(5 * time.Second)
|
||||
|
||||
_, spentVtxos, err := sdkClient.ListVtxos(ctx)
|
||||
require.NoError(t, err)
|
||||
require.NotEmpty(t, spentVtxos)
|
||||
_, spentVtxos, err := sdkClient.ListVtxos(ctx)
|
||||
require.NoError(t, err)
|
||||
require.NotEmpty(t, spentVtxos)
|
||||
|
||||
var vtxo client.Vtxo
|
||||
var vtxo client.Vtxo
|
||||
|
||||
for _, v := range spentVtxos {
|
||||
if v.RoundTxid == roundId {
|
||||
vtxo = v
|
||||
break
|
||||
}
|
||||
for _, v := range spentVtxos {
|
||||
if v.RoundTxid == roundId {
|
||||
vtxo = v
|
||||
break
|
||||
}
|
||||
require.NotEmpty(t, vtxo)
|
||||
}
|
||||
require.NotEmpty(t, vtxo)
|
||||
|
||||
round, err := grpcClient.GetRound(ctx, vtxo.RoundTxid)
|
||||
round, err := grpcClient.GetRound(ctx, vtxo.RoundTxid)
|
||||
require.NoError(t, err)
|
||||
|
||||
expl := explorer.NewExplorer("http://localhost:3000", common.BitcoinRegTest)
|
||||
|
||||
branch, err := redemption.NewCovenantlessRedeemBranch(expl, round.Tree, vtxo)
|
||||
require.NoError(t, err)
|
||||
|
||||
txs, err := branch.RedeemPath()
|
||||
require.NoError(t, err)
|
||||
|
||||
for _, tx := range txs {
|
||||
_, err := expl.Broadcast(tx)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
expl := explorer.NewExplorer("http://localhost:3000", common.BitcoinRegTest)
|
||||
// give time for the ASP to detect and process the fraud
|
||||
time.Sleep(50 * time.Second)
|
||||
|
||||
branch, err := redemption.NewCovenantlessRedeemBranch(expl, round.Tree, vtxo)
|
||||
require.NoError(t, err)
|
||||
balance, err := sdkClient.Balance(ctx, false)
|
||||
require.NoError(t, err)
|
||||
|
||||
txs, err := branch.RedeemPath()
|
||||
require.NoError(t, err)
|
||||
require.Empty(t, balance.OnchainBalance.LockedAmount)
|
||||
}
|
||||
|
||||
for _, tx := range txs {
|
||||
_, err := expl.Broadcast(tx)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
func TestChainAsyncPayments(t *testing.T) {
|
||||
var receive utils.ArkReceive
|
||||
receiveStr, err := runClarkCommand("receive")
|
||||
require.NoError(t, err)
|
||||
|
||||
// give time for the ASP to detect and process the fraud
|
||||
time.Sleep(50 * time.Second)
|
||||
err = json.Unmarshal([]byte(receiveStr), &receive)
|
||||
require.NoError(t, err)
|
||||
|
||||
balance, err := sdkClient.Balance(ctx, false)
|
||||
require.NoError(t, err)
|
||||
_, err = utils.RunCommand("nigiri", "faucet", receive.Boarding)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Empty(t, balance.OnchainBalance.LockedAmount)
|
||||
})
|
||||
time.Sleep(5 * time.Second)
|
||||
|
||||
_, err = runClarkCommand("settle", "--password", utils.Password)
|
||||
require.NoError(t, err)
|
||||
|
||||
time.Sleep(3 * time.Second)
|
||||
|
||||
_, err = runClarkCommand("send", "--amount", "10000", "--to", receive.Offchain, "--password", utils.Password)
|
||||
require.NoError(t, err)
|
||||
|
||||
var balance utils.ArkBalance
|
||||
balanceStr, err := runClarkCommand("balance")
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, json.Unmarshal([]byte(balanceStr), &balance))
|
||||
require.NotZero(t, balance.Offchain.Total)
|
||||
|
||||
_, err = runClarkCommand("send", "--amount", "10000", "--to", receive.Offchain, "--password", utils.Password)
|
||||
require.NoError(t, err)
|
||||
|
||||
balanceStr, err = runClarkCommand("balance")
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, json.Unmarshal([]byte(balanceStr), &balance))
|
||||
require.NotZero(t, balance.Offchain.Total)
|
||||
}
|
||||
|
||||
func TestAliceSeveralPaymentsToBob(t *testing.T) {
|
||||
@@ -300,9 +329,6 @@ func TestAliceSeveralPaymentsToBob(t *testing.T) {
|
||||
|
||||
time.Sleep(5 * time.Second)
|
||||
|
||||
_, err = alice.Claim(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
bobAddress, _, err := bob.Receive(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -315,12 +341,6 @@ func TestAliceSeveralPaymentsToBob(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
require.Len(t, bobVtxos, 1)
|
||||
|
||||
_, err = bob.Claim(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = alice.Claim(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = alice.SendOffChain(ctx, false, []arksdk.Receiver{arksdk.NewBitcoinReceiver(bobAddress, 10000)})
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -339,7 +359,7 @@ func TestAliceSeveralPaymentsToBob(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
require.Len(t, bobVtxos, 3)
|
||||
|
||||
_, err = alice.SendAsync(ctx, false, []arksdk.Receiver{arksdk.NewBitcoinReceiver(bobAddress, 10000)})
|
||||
_, err = alice.SendOffChain(ctx, false, []arksdk.Receiver{arksdk.NewBitcoinReceiver(bobAddress, 10000)})
|
||||
require.NoError(t, err)
|
||||
|
||||
time.Sleep(2 * time.Second)
|
||||
@@ -348,9 +368,6 @@ func TestAliceSeveralPaymentsToBob(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
require.Len(t, bobVtxos, 4)
|
||||
|
||||
_, err = alice.Claim(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
// bobVtxos should be unique
|
||||
uniqueVtxos := make(map[string]struct{})
|
||||
for _, v := range bobVtxos {
|
||||
@@ -358,9 +375,7 @@ func TestAliceSeveralPaymentsToBob(t *testing.T) {
|
||||
}
|
||||
require.Len(t, uniqueVtxos, 4)
|
||||
|
||||
_, err = bob.Claim(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
}
|
||||
|
||||
func TestSweep(t *testing.T) {
|
||||
@@ -376,7 +391,7 @@ func TestSweep(t *testing.T) {
|
||||
|
||||
time.Sleep(5 * time.Second)
|
||||
|
||||
_, err = runClarkCommand("claim", "--password", utils.Password)
|
||||
_, err = runClarkCommand("settle", "--password", utils.Password)
|
||||
require.NoError(t, err)
|
||||
|
||||
time.Sleep(3 * time.Second)
|
||||
|
||||
Reference in New Issue
Block a user