trident_assistant 0.1.3 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/trident_assistant/api/collectible.rb +58 -26
- data/lib/trident_assistant/api/collection.rb +7 -6
- data/lib/trident_assistant/api/mixin_asset.rb +12 -0
- data/lib/trident_assistant/api/order.rb +3 -2
- data/lib/trident_assistant/api.rb +6 -0
- data/lib/trident_assistant/cli/collectible.rb +13 -2
- data/lib/trident_assistant/cli/nfo.rb +32 -26
- data/lib/trident_assistant/client.rb +2 -2
- data/lib/trident_assistant/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 78044f2cab71b01faa20d88f6e46cc1231e6716d6f1a2e1c7f1ab4566c12a8c8
|
4
|
+
data.tar.gz: ffe521c1a183c2924ab38358bebe0e3e657f825b5b6e2be16a5c1962cc0beb8c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6a56b4a274b0e74f19d2dbeb4e04738ccd653dfaa33588482eb62f7a921537ee9dbb24ae36a042d691fb11f2e77c103a078b8002ba3d435362875894ed818d12
|
7
|
+
data.tar.gz: a60869ceb2bceb39c86b4dc57a9ef35fca14da6246472efe8856cf8acbb8af08a9c18a544e83c921c0f27d47608a2dbb4cf34174146521f16c98f8deb7105305
|
@@ -7,10 +7,27 @@ module TridentAssistant
|
|
7
7
|
EXCHANGE_ASSET_ID = "965e5c6e-434c-3fa9-b780-c50f43cd955c"
|
8
8
|
MINIMUM_AMOUNT = 0.000_000_01
|
9
9
|
|
10
|
+
def collectibles(**kwargs)
|
11
|
+
client
|
12
|
+
.get(
|
13
|
+
"api/collectibles",
|
14
|
+
headers: {
|
15
|
+
Authorization: "Bearer #{mixin_bot.access_token("GET", "/me")}"
|
16
|
+
},
|
17
|
+
params: {
|
18
|
+
collection_id: kwargs[:collection_id],
|
19
|
+
type: kwargs[:type],
|
20
|
+
page: kwargs[:page],
|
21
|
+
query: kwargs[:query]
|
22
|
+
}
|
23
|
+
)
|
24
|
+
end
|
25
|
+
|
10
26
|
def deposit(collection, token)
|
11
27
|
token_id = MixinBot::Utils::Nfo.new(collection: collection, token: token).unique_token_id
|
12
|
-
collectible =
|
13
|
-
|
28
|
+
collectible = find_collectible(:unspent, token_id)
|
29
|
+
collectible ||= find_collectible(:signed, token_id)
|
30
|
+
raise ForbiddenError, "Cannot find collectible" if collectible.blank?
|
14
31
|
|
15
32
|
nfo = MixinBot::Utils::Nfo.new(extra: "deposit".unpack1("H*")).encode.hex
|
16
33
|
_transfer_nft(
|
@@ -36,9 +53,9 @@ module TridentAssistant
|
|
36
53
|
|
37
54
|
def airdrop(collection, token, **kwargs)
|
38
55
|
token_id = MixinBot::Utils::Nfo.new(collection: collection, token: token).unique_token_id
|
39
|
-
collectible =
|
40
|
-
collectible ||=
|
41
|
-
raise "Cannot find collectible in wallet" if collectible.blank?
|
56
|
+
collectible = find_collectible(:unspent, token_id)
|
57
|
+
collectible ||= find_collectible(:signed, token_id)
|
58
|
+
raise ForbiddenError, "Cannot find collectible in wallet" if collectible.blank?
|
42
59
|
|
43
60
|
memo =
|
44
61
|
TridentAssistant::Utils::Memo.new(
|
@@ -56,13 +73,13 @@ module TridentAssistant
|
|
56
73
|
)
|
57
74
|
end
|
58
75
|
|
59
|
-
def transfer(collection, token, recipient, **
|
76
|
+
def transfer(collection, token, recipient, **kwargs)
|
60
77
|
token_id = MixinBot::Utils::Nfo.new(collection: collection, token: token).unique_token_id
|
61
|
-
collectible =
|
62
|
-
collectible ||=
|
63
|
-
raise "Cannot find collectible in wallet" if collectible.blank?
|
78
|
+
collectible = find_collectible(:unspent, token_id)
|
79
|
+
collectible ||= find_collectible(:signed, token_id)
|
80
|
+
raise ForbiddenError, "Cannot find collectible in wallet" if collectible.blank?
|
64
81
|
|
65
|
-
memo = "TRANSFER"
|
82
|
+
memo = kwargs[:memo] || "TRANSFER"
|
66
83
|
nfo = MixinBot::Utils::Nfo.new(extra: memo.unpack1("H*")).encode.hex
|
67
84
|
|
68
85
|
_transfer_nft(
|
@@ -75,23 +92,38 @@ module TridentAssistant
|
|
75
92
|
|
76
93
|
private
|
77
94
|
|
95
|
+
def find_collectible(state, token_id)
|
96
|
+
limit = 500
|
97
|
+
offset = ""
|
98
|
+
|
99
|
+
loop do
|
100
|
+
r = mixin_bot.collectibles(state: state, limit: limit, offset: offset)["data"]
|
101
|
+
puts "offset: #{offset}, loaded #{r.size} collectibles"
|
102
|
+
collectible = r.find(&->(c) { c["token_id"] == token_id })
|
103
|
+
break collectible if collectible.present?
|
104
|
+
|
105
|
+
break if r.size < 500
|
106
|
+
|
107
|
+
offset = r.last["updated_at"]
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
78
111
|
def _transfer_nft(collectible, nfo, **kwargs)
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
mixin_bot.send_raw_transaction sign["raw_transaction"]
|
112
|
+
if collectible["state"] == "signed"
|
113
|
+
mixin_bot.send_raw_transaction collectible["signed_tx"]
|
114
|
+
else
|
115
|
+
raw = mixin_bot.build_collectible_transaction(
|
116
|
+
collectible: collectible,
|
117
|
+
receivers: kwargs[:receivers],
|
118
|
+
receivers_threshold: kwargs[:threshold],
|
119
|
+
nfo: nfo
|
120
|
+
)
|
121
|
+
tx = mixin_bot.sign_raw_transaction raw
|
122
|
+
|
123
|
+
request = mixin_bot.create_sign_collectible_request tx
|
124
|
+
sign = mixin_bot.sign_collectible_request request["request_id"], keystore[:pin]
|
125
|
+
mixin_bot.send_raw_transaction sign["raw_transaction"]
|
126
|
+
end
|
95
127
|
end
|
96
128
|
end
|
97
129
|
end
|
@@ -6,18 +6,18 @@ module TridentAssistant
|
|
6
6
|
module Collection
|
7
7
|
def collection(id)
|
8
8
|
client.get(
|
9
|
-
"api/collections/#{id}"
|
10
|
-
headers: {
|
11
|
-
Authorization: "Bearer #{mixin_bot.access_token("GET", "/me")}"
|
12
|
-
}
|
9
|
+
"api/collections/#{id}"
|
13
10
|
)
|
14
11
|
end
|
15
12
|
|
16
|
-
def collections
|
13
|
+
def collections(**kwargs)
|
17
14
|
client.get(
|
18
15
|
"api/collections",
|
19
16
|
headers: {
|
20
17
|
Authorization: "Bearer #{mixin_bot.access_token("GET", "/me")}"
|
18
|
+
},
|
19
|
+
params: {
|
20
|
+
page: kwargs[:page]
|
21
21
|
}
|
22
22
|
)
|
23
23
|
end
|
@@ -52,7 +52,8 @@ module TridentAssistant
|
|
52
52
|
json: {
|
53
53
|
description: kwargs[:description],
|
54
54
|
external_url: kwargs[:external_url],
|
55
|
-
icon_base64: kwargs[:icon_base64]
|
55
|
+
icon_base64: kwargs[:icon_base64],
|
56
|
+
icon_url: kwargs[:icon_url]
|
56
57
|
}.compact
|
57
58
|
)
|
58
59
|
end
|
@@ -19,6 +19,7 @@ module TridentAssistant
|
|
19
19
|
metahash: kwargs[:metahash],
|
20
20
|
state: kwargs[:state],
|
21
21
|
type: kwargs[:type],
|
22
|
+
maker_id: kwargs[:maker_id],
|
22
23
|
page: kwargs[:page]
|
23
24
|
}
|
24
25
|
)
|
@@ -146,8 +147,8 @@ module TridentAssistant
|
|
146
147
|
|
147
148
|
def cancel_order(order_id)
|
148
149
|
info = order order_id
|
149
|
-
raise "Order maker: #{info["maker"]["id"]}" if info.dig("maker", "id") != mixin_bot.client_id
|
150
|
-
raise "Order state: #{info["state"]}" if info["state"] != "open"
|
150
|
+
raise ForbiddenError, "Order maker: #{info["maker"]["id"]}" if info.dig("maker", "id") != mixin_bot.client_id
|
151
|
+
raise ForbiddenError, "Order state: #{info["state"]}" if info["state"] != "open"
|
151
152
|
|
152
153
|
memo = TridentAssistant::Utils::Memo.new(type: "C", order_id: order_id, token_id: info["token_id"])
|
153
154
|
|
@@ -4,11 +4,16 @@ require_relative "./client"
|
|
4
4
|
require_relative "./api/collection"
|
5
5
|
require_relative "./api/collectible"
|
6
6
|
require_relative "./api/metadata"
|
7
|
+
require_relative "./api/mixin_asset"
|
7
8
|
require_relative "./api/order"
|
8
9
|
|
9
10
|
module TridentAssistant
|
10
11
|
# APIs of Trident server
|
11
12
|
class API
|
13
|
+
class UnauthorizedError < TridentAssistant::Error; end
|
14
|
+
class ArgumentError < TridentAssistant::Error; end
|
15
|
+
class ForbiddenError < TridentAssistant::Error; end
|
16
|
+
|
12
17
|
attr_reader :mixin_bot, :client, :keystore
|
13
18
|
|
14
19
|
def initialize(**args)
|
@@ -22,6 +27,7 @@ module TridentAssistant
|
|
22
27
|
include TridentAssistant::API::Collectible
|
23
28
|
include TridentAssistant::API::Collection
|
24
29
|
include TridentAssistant::API::Metadata
|
30
|
+
include TridentAssistant::API::MixinAsset
|
25
31
|
include TridentAssistant::API::Order
|
26
32
|
end
|
27
33
|
end
|
@@ -11,7 +11,7 @@ module TridentAssistant
|
|
11
11
|
desc: "keystore or keystore.json file of Mixin bot"
|
12
12
|
option :keystore, type: :string, aliases: "k", required: true, desc: "keystore or keystore.json file of Mixin bot"
|
13
13
|
def index
|
14
|
-
r = api.mixin_bot.collectibles state: options[:state]
|
14
|
+
r = api.mixin_bot.collectibles state: options[:state], limit: 500
|
15
15
|
|
16
16
|
log r["data"]
|
17
17
|
end
|
@@ -87,7 +87,18 @@ module TridentAssistant
|
|
87
87
|
log UI.fmt("{{v}} airdrop receiver_id: #{receiver_id}")
|
88
88
|
log UI.fmt("{{v}} airdrop start_at: #{start_at}")
|
89
89
|
|
90
|
-
|
90
|
+
attempt = 0
|
91
|
+
r =
|
92
|
+
begin
|
93
|
+
attempt += 1
|
94
|
+
api.airdrop metadata.collection["id"], metadata.token["id"], receiver_id: receiver_id, start_at: start_at
|
95
|
+
rescue Errno::ECONNRESET, OpenSSL::SSL::SSLError, MixinBot::HttpError => e
|
96
|
+
log UI.fmt("{{x}} #{e.inspect}")
|
97
|
+
log UI.fmt("Retrying #{attempt} times...")
|
98
|
+
sleep 0.5
|
99
|
+
retry
|
100
|
+
end
|
101
|
+
|
91
102
|
log r["data"]
|
92
103
|
data["_airdrop"] ||= {}
|
93
104
|
data["_airdrop"]["hash"] = r["data"]["hash"]
|
@@ -26,9 +26,20 @@ module TridentAssistant
|
|
26
26
|
files.each do |file|
|
27
27
|
log "-" * 80
|
28
28
|
log UI.fmt("{{v}} found #{file}")
|
29
|
-
|
30
|
-
|
31
|
-
|
29
|
+
attempt = 0
|
30
|
+
success =
|
31
|
+
begin
|
32
|
+
attempt += 1
|
33
|
+
_mint file
|
34
|
+
rescue Errno::ECONNRESET, OpenSSL::SSL::SSLError, MixinBot::HttpError, TridentAssistant::Client::HttpError,
|
35
|
+
TridentAssistant::Client::RequestError, MixinBot::RequestError => e
|
36
|
+
log UI.fmt("{{x}} #{e.inspect}")
|
37
|
+
log UI.fmt("Retrying #{attempt} times...")
|
38
|
+
sleep 0.5
|
39
|
+
retry
|
40
|
+
end
|
41
|
+
minted.push(file) if success
|
42
|
+
rescue TridentAssistant::Utils::Metadata::InvalidFormatError, JSON::ParserError, RuntimeError => e
|
32
43
|
log UI.fmt("{{x}} #{file} failed: #{e.inspect}")
|
33
44
|
next
|
34
45
|
end
|
@@ -55,8 +66,8 @@ module TridentAssistant
|
|
55
66
|
api.upload_metadata metadata: metadata.json, metahash: metadata.metahash
|
56
67
|
data["_mint"] ||= {}
|
57
68
|
data["_mint"]["metahash"] = metadata.metahash
|
69
|
+
log UI.fmt("{{v}} metadata uploaded: #{options[:endpoint]}/api/collectibles/#{metadata.metahash}")
|
58
70
|
end
|
59
|
-
log UI.fmt("{{v}} metadata uploaded: #{options[:endpoint]}/api/collectibles/#{metadata.metahash}")
|
60
71
|
|
61
72
|
token_id = MixinBot::Utils::Nfo.new(collection: metadata.collection[:id],
|
62
73
|
token: metadata.token[:id]).unique_token_id
|
@@ -76,33 +87,28 @@ module TridentAssistant
|
|
76
87
|
memo = api.mixin_bot.nft_memo metadata.collection[:id], metadata.token[:id].to_i, metadata.metahash
|
77
88
|
|
78
89
|
data["_mint"]["trace_id"] = trace_id
|
79
|
-
|
90
|
+
begin
|
80
91
|
payment =
|
81
|
-
|
82
|
-
api.
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
)
|
93
|
-
rescue MixinBot::InsufficientPoolError, MixinBot::HttpError => e
|
94
|
-
log UI.fmt("{{x}} #{e.inspect}")
|
95
|
-
log "Retrying to pay..."
|
96
|
-
sleep 1
|
97
|
-
nil
|
98
|
-
end
|
99
|
-
|
100
|
-
next if payment.blank? || payment["errors"].present?
|
92
|
+
api.mixin_bot.create_multisig_transaction(
|
93
|
+
api.keystore[:pin],
|
94
|
+
{
|
95
|
+
asset_id: TridentAssistant::Utils::MINT_ASSET_ID,
|
96
|
+
trace_id: trace_id,
|
97
|
+
amount: TridentAssistant::Utils::MINT_AMOUNT,
|
98
|
+
memo: memo,
|
99
|
+
receivers: TridentAssistant::Utils::NFO_MTG[:members],
|
100
|
+
threshold: TridentAssistant::Utils::NFO_MTG[:threshold]
|
101
|
+
}
|
102
|
+
)
|
101
103
|
|
102
104
|
log UI.fmt("{{v}} NFT mint payment paid: #{payment["data"]}")
|
103
105
|
data["_mint"]["token_id"] = token_id
|
104
106
|
log UI.fmt("{{v}} NFT successfully minted")
|
105
|
-
|
107
|
+
rescue MixinBot::InsufficientPoolError, MixinBot::HttpError => e
|
108
|
+
log UI.fmt("{{x}} #{e.inspect}")
|
109
|
+
log "Retrying to pay..."
|
110
|
+
sleep 1
|
111
|
+
retry
|
106
112
|
end
|
107
113
|
|
108
114
|
data.dig("_mint", "token_id").present?
|
@@ -35,7 +35,7 @@ module TridentAssistant
|
|
35
35
|
options[:headers]["Content-Type"] ||= "application/json"
|
36
36
|
|
37
37
|
begin
|
38
|
-
response = HTTP.timeout(connect: 5, write:
|
38
|
+
response = HTTP.timeout(connect: 5, write: 120, read: 60).request(verb, uri, options)
|
39
39
|
rescue HTTP::Error => e
|
40
40
|
raise HttpError, e.message
|
41
41
|
end
|
@@ -45,7 +45,7 @@ module TridentAssistant
|
|
45
45
|
parse_response(response) do |parse_as, result|
|
46
46
|
case parse_as
|
47
47
|
when :json
|
48
|
-
break result if result["message"].blank?
|
48
|
+
break result if result.is_a?(Array) || (result.is_a?(Hash) && result["message"].blank?)
|
49
49
|
|
50
50
|
raise result["message"]
|
51
51
|
else
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: trident_assistant
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- an-lee
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-07-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mixin_bot
|
@@ -47,6 +47,7 @@ files:
|
|
47
47
|
- lib/trident_assistant/api/collectible.rb
|
48
48
|
- lib/trident_assistant/api/collection.rb
|
49
49
|
- lib/trident_assistant/api/metadata.rb
|
50
|
+
- lib/trident_assistant/api/mixin_asset.rb
|
50
51
|
- lib/trident_assistant/api/order.rb
|
51
52
|
- lib/trident_assistant/cli.rb
|
52
53
|
- lib/trident_assistant/cli/base.rb
|