tangany 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.reek.yml +4 -0
- data/.rspec +3 -0
- data/.rubycritic.yml +7 -0
- data/.sasori/Dockerfile +51 -0
- data/.simplecov +13 -0
- data/CHANGELOG.md +5 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/Gemfile +20 -0
- data/Gemfile.lock +210 -0
- data/LICENSE.txt +21 -0
- data/README.md +410 -0
- data/Rakefile +133 -0
- data/bin/console +22 -0
- data/bin/setup +8 -0
- data/bin/test-live +170 -0
- data/lib/config/chains.json +22 -0
- data/lib/tangany/application_contract.rb +19 -0
- data/lib/tangany/collection.rb +13 -0
- data/lib/tangany/config.rb +24 -0
- data/lib/tangany/custody/client.rb +37 -0
- data/lib/tangany/custody/collection.rb +17 -0
- data/lib/tangany/custody/contracts/wallets/create.rb +23 -0
- data/lib/tangany/custody/contracts/wallets/list.rb +37 -0
- data/lib/tangany/custody/contracts/wallets/update.rb +21 -0
- data/lib/tangany/custody/contracts/wallets.rb +3 -0
- data/lib/tangany/custody/contracts.rb +1 -0
- data/lib/tangany/custody/objects/wallet.rb +17 -0
- data/lib/tangany/custody/objects/wallet_recovery.rb +10 -0
- data/lib/tangany/custody/objects/wallet_status.rb +10 -0
- data/lib/tangany/custody/objects.rb +3 -0
- data/lib/tangany/custody/resource.rb +29 -0
- data/lib/tangany/custody/resources/wallet_statuses_resource.rb +9 -0
- data/lib/tangany/custody/resources/wallets_resource.rb +34 -0
- data/lib/tangany/custody/resources.rb +2 -0
- data/lib/tangany/custody.rb +7 -0
- data/lib/tangany/customers/application_contract.rb +6 -0
- data/lib/tangany/customers/client.rb +37 -0
- data/lib/tangany/customers/collection.rb +16 -0
- data/lib/tangany/customers/contracts/customers/create.rb +17 -0
- data/lib/tangany/customers/contracts/customers/create_schemas/contract.rb +21 -0
- data/lib/tangany/customers/contracts/customers/create_schemas/customer.rb +34 -0
- data/lib/tangany/customers/contracts/customers/list.rb +17 -0
- data/lib/tangany/customers/contracts/customers/update.rb +14 -0
- data/lib/tangany/customers/contracts/customers/update_schemas/customer.rb +15 -0
- data/lib/tangany/customers/contracts/customers.rb +3 -0
- data/lib/tangany/customers/contracts/natural_persons/create.rb +23 -0
- data/lib/tangany/customers/contracts/natural_persons/create_schemas/address.rb +23 -0
- data/lib/tangany/customers/contracts/natural_persons/create_schemas/document.rb +25 -0
- data/lib/tangany/customers/contracts/natural_persons/create_schemas/kyc.rb +24 -0
- data/lib/tangany/customers/contracts/natural_persons/create_schemas/natural_person.rb +44 -0
- data/lib/tangany/customers/contracts/natural_persons/create_schemas/pep.rb +22 -0
- data/lib/tangany/customers/contracts/natural_persons/create_schemas/sanctions.rb +22 -0
- data/lib/tangany/customers/contracts/natural_persons/list.rb +17 -0
- data/lib/tangany/customers/contracts/natural_persons/update.rb +14 -0
- data/lib/tangany/customers/contracts/natural_persons/update_schemas/natural_person.rb +15 -0
- data/lib/tangany/customers/contracts/natural_persons.rb +3 -0
- data/lib/tangany/customers/contracts/wallet_links/create.rb +28 -0
- data/lib/tangany/customers/contracts/wallet_links/list.rb +17 -0
- data/lib/tangany/customers/contracts/wallet_links.rb +2 -0
- data/lib/tangany/customers/contracts.rb +3 -0
- data/lib/tangany/customers/objects/address.rb +11 -0
- data/lib/tangany/customers/objects/contract.rb +13 -0
- data/lib/tangany/customers/objects/customer.rb +14 -0
- data/lib/tangany/customers/objects/document.rb +17 -0
- data/lib/tangany/customers/objects/kyc.rb +16 -0
- data/lib/tangany/customers/objects/natural_person.rb +30 -0
- data/lib/tangany/customers/objects/pep.rb +12 -0
- data/lib/tangany/customers/objects/sanctions.rb +12 -0
- data/lib/tangany/customers/objects/wallet_link.rb +14 -0
- data/lib/tangany/customers/objects.rb +5 -0
- data/lib/tangany/customers/resource.rb +11 -0
- data/lib/tangany/customers/resources/customers_resource.rb +27 -0
- data/lib/tangany/customers/resources/natural_persons_resource.rb +26 -0
- data/lib/tangany/customers/resources/wallet_links_resource.rb +37 -0
- data/lib/tangany/customers/resources.rb +3 -0
- data/lib/tangany/customers.rb +8 -0
- data/lib/tangany/error.rb +34 -0
- data/lib/tangany/json_patch.rb +65 -0
- data/lib/tangany/object.rb +43 -0
- data/lib/tangany/operation.rb +10 -0
- data/lib/tangany/resource.rb +80 -0
- data/lib/tangany/types.rb +7 -0
- data/lib/tangany/version.rb +3 -0
- data/lib/tangany.rb +47 -0
- data/sig/tangany.rbs +4 -0
- metadata +217 -0
data/bin/test-live
ADDED
@@ -0,0 +1,170 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
puts "This suite will run tests against the \e[1mlive Tangany's API\e[0m."
|
4
|
+
puts "\e[36mBe sure to set environment variables with \e[1mtesting values\e[0m\e[36m before running this suite.\e[0m"
|
5
|
+
print "Do you want to continue? [y/N] "
|
6
|
+
answer = gets.chomp
|
7
|
+
|
8
|
+
exit 1 unless answer == "y"
|
9
|
+
|
10
|
+
require "bundler/setup"
|
11
|
+
require "byebug"
|
12
|
+
require "factory_bot"
|
13
|
+
|
14
|
+
require "tangany"
|
15
|
+
|
16
|
+
load("Rakefile")
|
17
|
+
Rake::Task["regenerate_fixtures"].invoke
|
18
|
+
|
19
|
+
Tangany.client_id = ENV.fetch("TEST_TANGANY_CLIENT_ID", "test")
|
20
|
+
Tangany.client_secret = ENV.fetch("TEST_TANGANY_CLIENT_SECRET", "test")
|
21
|
+
Tangany.environment = "testnet"
|
22
|
+
Tangany.subscription = ENV.fetch("TEST_TANGANY_SUBSCRIPTION", "test")
|
23
|
+
Tangany.vault_url = ENV.fetch("TEST_TANGANY_VAULT_URL", "test")
|
24
|
+
|
25
|
+
def safe_not_found(&block)
|
26
|
+
yield
|
27
|
+
rescue Tangany::RequestError => e
|
28
|
+
raise e unless e.status_code == 404
|
29
|
+
end
|
30
|
+
|
31
|
+
begin
|
32
|
+
custody_client = Tangany::Custody::Client.new
|
33
|
+
customers_client = Tangany::Customers::Client.new
|
34
|
+
|
35
|
+
puts
|
36
|
+
puts "== Preparing data ".ljust(80, "=")
|
37
|
+
inputs = {
|
38
|
+
customer: {
|
39
|
+
create: JSON.parse(
|
40
|
+
File.read("spec/fixtures/generated/inputs/customers/customers/create/valid_input.json"),
|
41
|
+
symbolize_names: true
|
42
|
+
),
|
43
|
+
update: JSON.parse(
|
44
|
+
File.read("spec/fixtures/generated/inputs/customers/customers/update/valid_input.json"),
|
45
|
+
symbolize_names: true
|
46
|
+
)
|
47
|
+
},
|
48
|
+
natural_person: {
|
49
|
+
create: JSON.parse(
|
50
|
+
File.read("spec/fixtures/generated/inputs/customers/natural_persons/create/valid_input.json"),
|
51
|
+
symbolize_names: true
|
52
|
+
),
|
53
|
+
update: JSON.parse(
|
54
|
+
File.read("spec/fixtures/generated/inputs/customers/natural_persons/update/valid_input.json"),
|
55
|
+
symbolize_names: true
|
56
|
+
)
|
57
|
+
},
|
58
|
+
wallet: {
|
59
|
+
create: JSON.parse(
|
60
|
+
File.read("spec/fixtures/generated/inputs/custody/wallets/create/valid_input.json"),
|
61
|
+
symbolize_names: true
|
62
|
+
)
|
63
|
+
},
|
64
|
+
wallet_link: {
|
65
|
+
create: JSON.parse(
|
66
|
+
File.read("spec/fixtures/generated/inputs/customers/wallet_links/create/valid_input.json"),
|
67
|
+
symbolize_names: true
|
68
|
+
)
|
69
|
+
}
|
70
|
+
}
|
71
|
+
ids = {
|
72
|
+
customer: inputs[:customer][:create][:id],
|
73
|
+
natural_person: inputs[:natural_person][:create][:id],
|
74
|
+
wallet: inputs[:wallet][:create][:wallet],
|
75
|
+
wallet_link: inputs[:wallet_link][:create][:id]
|
76
|
+
}
|
77
|
+
inputs[:customer][:create][:owner][:entityId] = ids[:natural_person]
|
78
|
+
inputs[:customer][:create][:authorized][0][:entityId] = ids[:natural_person]
|
79
|
+
inputs[:customer][:update][:id] = ids[:customer]
|
80
|
+
inputs[:customer][:update][:owner][:entityId] = ids[:natural_person]
|
81
|
+
inputs[:customer][:update][:authorized][0][:entityId] = ids[:natural_person]
|
82
|
+
inputs[:natural_person][:update][:id] = ids[:natural_person]
|
83
|
+
inputs[:wallet_link][:create][:assignment][:customerId] = ids[:customer]
|
84
|
+
inputs[:wallet_link][:create][:assetId] = "ETH"
|
85
|
+
puts " -> \e[36mCustomer: \e[1m#{ids[:customer]}\e[0m"
|
86
|
+
puts " -> \e[36mNatural person: \e[1m#{ids[:natural_person]}\e[0m"
|
87
|
+
puts " -> \e[36mWallet: \e[1m#{ids[:wallet]}\e[0m"
|
88
|
+
puts " -> \e[36mWallet link: \e[1m#{ids[:wallet_link]}\e[0m"
|
89
|
+
puts "== Data prepared ".ljust(80, "=")
|
90
|
+
|
91
|
+
puts
|
92
|
+
puts "== Running tests... ".ljust(80, "=")
|
93
|
+
|
94
|
+
puts " -> Creating natural person..."
|
95
|
+
natural_person = customers_client.natural_persons.create(inputs[:natural_person][:create])
|
96
|
+
raise "Natural person creation failed" unless natural_person.is_a?(Tangany::Customers::NaturalPerson)
|
97
|
+
|
98
|
+
puts " -> Listing natural persons..."
|
99
|
+
natural_persons = customers_client.natural_persons.list
|
100
|
+
raise "Natural person not present in list" unless natural_persons.data.map(&:id).include?(ids[:natural_person])
|
101
|
+
|
102
|
+
puts " -> Retrieving natural person..."
|
103
|
+
natural_person = customers_client.natural_persons.retrieve(ids[:natural_person])
|
104
|
+
raise "Natural person retrieval failed" unless natural_person.is_a?(Tangany::Customers::NaturalPerson)
|
105
|
+
|
106
|
+
puts " -> Updating natural person..."
|
107
|
+
natural_person = customers_client.natural_persons.update(ids[:natural_person], inputs[:natural_person][:update])
|
108
|
+
raise "Natural person update failed" unless natural_person.is_a?(Tangany::Customers::NaturalPerson)
|
109
|
+
|
110
|
+
puts " -> Creating customer..."
|
111
|
+
customer = customers_client.customers.create(inputs[:customer][:create])
|
112
|
+
raise "Customer creation failed" unless customer.is_a?(Tangany::Customers::Customer)
|
113
|
+
|
114
|
+
puts " -> Listing customers..."
|
115
|
+
customers = customers_client.customers.list
|
116
|
+
raise "Customer not present in list" unless customers.data.map(&:id).include?(ids[:customer])
|
117
|
+
|
118
|
+
puts " -> Retrieving customer..."
|
119
|
+
customer = customers_client.customers.retrieve(ids[:customer])
|
120
|
+
raise "Customer retrieval failed" unless customer.is_a?(Tangany::Customers::Customer)
|
121
|
+
|
122
|
+
puts " -> Updating customer..."
|
123
|
+
customer = customers_client.customers.update(ids[:customer], inputs[:customer][:update])
|
124
|
+
raise "Customer update failed" unless customer.is_a?(Tangany::Customers::Customer)
|
125
|
+
|
126
|
+
puts " -> Creating wallet..."
|
127
|
+
wallet = custody_client.wallets.create(inputs[:wallet][:create])
|
128
|
+
raise "Wallet creation failed" unless wallet.is_a?(Tangany::Custody::Wallet)
|
129
|
+
|
130
|
+
puts " -> Creating wallet link with address value..."
|
131
|
+
wallet_link = customers_client.wallet_links.create(inputs[:wallet_link][:create])
|
132
|
+
raise "Wallet link creation failed" unless wallet_link.is_a?(Tangany::Customers::WalletLink)
|
133
|
+
|
134
|
+
puts " -> Creating wallet link with wallet value..."
|
135
|
+
customers_client.wallet_links.delete(ids[:wallet_link])
|
136
|
+
inputs[:wallet_link][:create].delete(:address)
|
137
|
+
inputs[:wallet_link][:create][:wallet] = ids[:wallet]
|
138
|
+
wallet_link = customers_client.wallet_links.create(inputs[:wallet_link][:create])
|
139
|
+
raise "Wallet link creation failed" unless wallet_link.is_a?(Tangany::Customers::WalletLink)
|
140
|
+
|
141
|
+
puts " -> Listing wallet links..."
|
142
|
+
wallet_links = customers_client.wallet_links.list
|
143
|
+
raise "Wallet link not present in list" unless wallet_links.data.map(&:id).include?(ids[:wallet_link])
|
144
|
+
|
145
|
+
puts " -> Retrieving wallet link..."
|
146
|
+
wallet_link = customers_client.wallet_links.retrieve(ids[:wallet_link])
|
147
|
+
raise "Wallet link retrieval failed" unless wallet_link.is_a?(Tangany::Customers::WalletLink)
|
148
|
+
|
149
|
+
puts "== Tests run... ".ljust(80, "=")
|
150
|
+
rescue => e
|
151
|
+
puts e.message
|
152
|
+
exit 1
|
153
|
+
ensure
|
154
|
+
puts
|
155
|
+
puts "== Cleaning up... ".ljust(80, "=")
|
156
|
+
|
157
|
+
puts " -> Deleting wallet link..."
|
158
|
+
safe_not_found { customers_client.wallet_links.delete(ids[:wallet_link]) }
|
159
|
+
|
160
|
+
puts " -> Deleting wallet..."
|
161
|
+
safe_not_found { custody_client.wallets.delete(ids[:wallet]) }
|
162
|
+
|
163
|
+
puts " -> Deleting customer..."
|
164
|
+
safe_not_found { customers_client.customers.delete(ids[:customer]) }
|
165
|
+
|
166
|
+
puts " -> Deleting natural person..."
|
167
|
+
safe_not_found { customers_client.natural_persons.delete(ids[:natural_person]) }
|
168
|
+
|
169
|
+
puts "== Cleaned ".ljust(80, "=")
|
170
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
[
|
2
|
+
{
|
3
|
+
"asset_id": "ETH",
|
4
|
+
"base_path": "eth",
|
5
|
+
"header": {
|
6
|
+
"name": "tangany-ethereum-network",
|
7
|
+
"mainnet": "mainnet",
|
8
|
+
"testnet": "goerli"
|
9
|
+
},
|
10
|
+
"name": "Ethereum"
|
11
|
+
},
|
12
|
+
{
|
13
|
+
"asset_id": "MATIC",
|
14
|
+
"base_path": "eth",
|
15
|
+
"header": {
|
16
|
+
"name": "tangany-ethereum-network",
|
17
|
+
"mainnet": "polygon",
|
18
|
+
"testnet": "https://rpc-mumbai.maticvigil.com"
|
19
|
+
},
|
20
|
+
"name": "Polygon"
|
21
|
+
}
|
22
|
+
]
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require "active_support/core_ext/object/to_param"
|
2
|
+
require "dry-validation"
|
3
|
+
|
4
|
+
module Tangany
|
5
|
+
class ApplicationContract < Dry::Validation::Contract
|
6
|
+
ALLOWED_SORTS = ["asc", "desc"].freeze
|
7
|
+
COUNTRY_CODE_REGEX = %r{[A-Z]{2}}
|
8
|
+
DATE_REGEX = %r{[0-9]{4}-[0-9]{2}-[0-9]{2}}
|
9
|
+
DATETIME_REGEX = %r{[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{3}Z}
|
10
|
+
ETHEREUM_ADDRESS_REGEX = %r{^0x[a-fA-F0-9]{40}$}
|
11
|
+
|
12
|
+
def to_safe_params!(params)
|
13
|
+
response = call(params)
|
14
|
+
raise InputError, response.errors.to_h if response.failure?
|
15
|
+
|
16
|
+
response.to_h
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Tangany
|
2
|
+
class Collection
|
3
|
+
attr_reader :data, :next_page_token, :next_path, :previous_path, :total
|
4
|
+
|
5
|
+
def initialize(data:, total:, next_page_token: nil, next_path: nil, previous_path: nil)
|
6
|
+
@data = data
|
7
|
+
@next_page_token = next_page_token
|
8
|
+
@next_path = next_path
|
9
|
+
@previous_path = previous_path
|
10
|
+
@total = total
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require "json"
|
2
|
+
|
3
|
+
module Tangany
|
4
|
+
class Config
|
5
|
+
attr_accessor :client_id, :client_secret, :environment, :chain, :subscription, :vault_url
|
6
|
+
|
7
|
+
attr_reader :custody_base_url, :customers_base_url, :customers_version, :chains
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@custody_base_url = "https://api.tangany.com/v1"
|
11
|
+
|
12
|
+
@customers_base_url = "https://api.tangany.com/customers"
|
13
|
+
@customers_version = "1"
|
14
|
+
|
15
|
+
@chains = load_chains
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def load_chains
|
21
|
+
JSON.parse(File.read(File.join(__dir__, "../config/chains.json")))
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require "faraday"
|
2
|
+
|
3
|
+
module Tangany
|
4
|
+
module Custody
|
5
|
+
class Client
|
6
|
+
attr_reader :adapter, :client_id, :client_secret, :environment, :subscription, :vault_url
|
7
|
+
|
8
|
+
def initialize(adapter: Faraday.default_adapter, stubs: nil)
|
9
|
+
@adapter = adapter
|
10
|
+
@client_id = Tangany.client_id
|
11
|
+
@client_secret = Tangany.client_secret
|
12
|
+
@environment = Tangany.environment
|
13
|
+
@subscription = Tangany.subscription
|
14
|
+
@vault_url = Tangany.vault_url
|
15
|
+
|
16
|
+
@stubs = stubs
|
17
|
+
end
|
18
|
+
|
19
|
+
def connection
|
20
|
+
@connection ||= Faraday.new do |faraday|
|
21
|
+
faraday.adapter(adapter, @stubs)
|
22
|
+
faraday.request(:json)
|
23
|
+
faraday.response(:json, content_type: /\bjson$/, parser_options: {symbolize_names: true})
|
24
|
+
faraday.url_prefix = Tangany.custody_base_url
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def wallets
|
29
|
+
WalletsResource.new(self)
|
30
|
+
end
|
31
|
+
|
32
|
+
def wallet_statuses(asset_id:)
|
33
|
+
WalletStatusesResource.new(self, asset_id: asset_id)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Tangany
|
2
|
+
module Custody
|
3
|
+
class Collection
|
4
|
+
class << self
|
5
|
+
def from_response(response, type:)
|
6
|
+
body = response.body
|
7
|
+
Tangany::Collection.new(
|
8
|
+
data: body[:list].map { |attributes| type.new(attributes) },
|
9
|
+
total: body.dig(:hits, :total),
|
10
|
+
next_path: body.dig(:links, :next),
|
11
|
+
previous_path: body.dig(:links, :previous)
|
12
|
+
)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Tangany
|
2
|
+
module Custody
|
3
|
+
module Contracts
|
4
|
+
module Wallets
|
5
|
+
class Create < ApplicationContract
|
6
|
+
TagSchema = Dry::Schema.Params do
|
7
|
+
10.times do |i|
|
8
|
+
optional("tag#{i}".to_sym).maybe(:string, max_size?: 256)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
schema do
|
13
|
+
config.validate_keys = true
|
14
|
+
|
15
|
+
optional(:wallet).filled(:string, max_size?: 127, min_size?: 1)
|
16
|
+
optional(:useHsm).filled(:bool)
|
17
|
+
optional(:tags).array(TagSchema)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Tangany
|
2
|
+
module Custody
|
3
|
+
module Contracts
|
4
|
+
module Wallets
|
5
|
+
class List < ApplicationContract
|
6
|
+
ALLOWED_ORDERS = ["created", "security", "updated", "wallet"].freeze
|
7
|
+
|
8
|
+
schema do
|
9
|
+
config.validate_keys = true
|
10
|
+
|
11
|
+
optional(:start).filled(:integer, lt?: 10_000)
|
12
|
+
optional(:limit).filled(:integer, gt?: 0, lteq?: 100)
|
13
|
+
optional(:order).filled(:string, included_in?: ALLOWED_ORDERS)
|
14
|
+
optional(:sort).filled(:string, included_in?: ALLOWED_SORTS)
|
15
|
+
optional(:tags).filled(:array, min_size?: 1)
|
16
|
+
optional(:xtags).filled(:array, min_size?: 1)
|
17
|
+
end
|
18
|
+
|
19
|
+
rule(:sort) do
|
20
|
+
key.failure("should not be specified without `order`") if values[:sort] && values[:order].nil?
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_safe_params!(params)
|
24
|
+
safe_params = super(params)
|
25
|
+
order = safe_params.delete(:order)
|
26
|
+
|
27
|
+
safe_params[:sort] = order + ((safe_params[:sort] == "desc") ? "desc" : "") if order
|
28
|
+
safe_params[:index] = safe_params.delete(:start) if safe_params[:start]
|
29
|
+
safe_params[:tags] = safe_params[:tags].join(",") if safe_params[:tags]
|
30
|
+
safe_params[:xtags] = safe_params[:xtags].join(",") if safe_params[:xtags]
|
31
|
+
safe_params
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Tangany
|
2
|
+
module Custody
|
3
|
+
module Contracts
|
4
|
+
module Wallets
|
5
|
+
class Update < ApplicationContract
|
6
|
+
TagSchema = Dry::Schema.Params do
|
7
|
+
10.times do |i|
|
8
|
+
optional("tag#{i}".to_sym).maybe(:string, max_size?: 256)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
schema do
|
13
|
+
config.validate_keys = true
|
14
|
+
|
15
|
+
optional(:tags).array(TagSchema)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require_relative "contracts/wallets"
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Tangany
|
2
|
+
module Custody
|
3
|
+
class Wallet < Object
|
4
|
+
attribute :wallet, Types::String
|
5
|
+
attribute? :version, Types::String
|
6
|
+
attribute? :created, Types::DateTime
|
7
|
+
attribute? :updated, Types::DateTime
|
8
|
+
attribute? :security, Types::String
|
9
|
+
attribute? :public do
|
10
|
+
attribute :secp256k1, Types::String
|
11
|
+
end
|
12
|
+
attribute? :tags, Types::Array
|
13
|
+
|
14
|
+
to_datetime :created, :updated
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Tangany
|
2
|
+
module Custody
|
3
|
+
class Resource < Tangany::Resource
|
4
|
+
def initialize(client, options = {})
|
5
|
+
@chain = Tangany.chains.find { |chain| chain["asset_id"] == options[:asset_id] } if options[:asset_id]
|
6
|
+
|
7
|
+
super(client)
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def default_headers
|
13
|
+
headers = {
|
14
|
+
"tangany-client-id" => client.client_id,
|
15
|
+
"tangany-client-secret" => client.client_secret,
|
16
|
+
"tangany-subscription" => client.subscription,
|
17
|
+
"tangany-vault-url" => client.vault_url
|
18
|
+
}
|
19
|
+
merge_chain_header(headers) if @chain
|
20
|
+
headers
|
21
|
+
end
|
22
|
+
|
23
|
+
def merge_chain_header(headers)
|
24
|
+
header = @chain["header"]
|
25
|
+
headers.merge(header["name"] => header[Tangany.environment])
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Tangany
|
2
|
+
module Custody
|
3
|
+
class WalletsResource < Resource
|
4
|
+
def create(**params)
|
5
|
+
Wallet.new(post_request("wallets", body: sanitize_params!(params).to_json).body)
|
6
|
+
end
|
7
|
+
|
8
|
+
def delete(wallet_id)
|
9
|
+
WalletRecovery.new(delete_request("wallet/#{wallet_id}").body)
|
10
|
+
end
|
11
|
+
|
12
|
+
def list(**params)
|
13
|
+
Collection.from_response(get_request("wallets", params: sanitize_params!(params)), type: Wallet)
|
14
|
+
end
|
15
|
+
|
16
|
+
def retrieve(wallet_id)
|
17
|
+
Wallet.new(get_request("wallet/#{wallet_id}").body)
|
18
|
+
end
|
19
|
+
|
20
|
+
def update(wallet_id, **params)
|
21
|
+
safe_params = sanitize_params!(params)
|
22
|
+
|
23
|
+
retrieve_response = get_request("wallet/#{wallet_id}")
|
24
|
+
wallet = Wallet.new(retrieve_response.body)
|
25
|
+
|
26
|
+
Wallet.new(patch_request(
|
27
|
+
"wallet/#{wallet_id}",
|
28
|
+
body: build_update_body_json(wallet.to_h, safe_params),
|
29
|
+
headers: {"If-Match" => retrieve_response.headers["If-Match"]}
|
30
|
+
).body)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require "faraday"
|
2
|
+
|
3
|
+
module Tangany
|
4
|
+
module Customers
|
5
|
+
class Client
|
6
|
+
attr_reader :adapter, :subscription
|
7
|
+
|
8
|
+
def initialize(adapter: Faraday.default_adapter, stubs: nil)
|
9
|
+
@adapter = adapter
|
10
|
+
@subscription = Tangany.subscription
|
11
|
+
|
12
|
+
@stubs = stubs
|
13
|
+
end
|
14
|
+
|
15
|
+
def connection
|
16
|
+
@connection ||= Faraday.new do |faraday|
|
17
|
+
faraday.adapter(adapter, @stubs)
|
18
|
+
faraday.request(:json)
|
19
|
+
faraday.response(:json, content_type: /\bjson$/, parser_options: {symbolize_names: true})
|
20
|
+
faraday.url_prefix = Tangany.customers_base_url
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def customers
|
25
|
+
CustomersResource.new(self)
|
26
|
+
end
|
27
|
+
|
28
|
+
def natural_persons
|
29
|
+
NaturalPersonsResource.new(self)
|
30
|
+
end
|
31
|
+
|
32
|
+
def wallet_links
|
33
|
+
WalletLinksResource.new(self)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Tangany
|
2
|
+
module Customers
|
3
|
+
class Collection
|
4
|
+
class << self
|
5
|
+
def from_response(response, type:)
|
6
|
+
body = response.body
|
7
|
+
Tangany::Collection.new(
|
8
|
+
data: body[:items].map { |attributes| type.new(attributes) },
|
9
|
+
total: body.dig(:pageInfo, :totalResults),
|
10
|
+
next_page_token: body[:nextPageToken]
|
11
|
+
)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require_relative "create_schemas/customer"
|
2
|
+
|
3
|
+
module Tangany
|
4
|
+
module Customers
|
5
|
+
module Contracts
|
6
|
+
module Customers
|
7
|
+
class Create < ApplicationContract
|
8
|
+
schema(CreateSchemas::Customer.schema) { config.validate_keys = true }
|
9
|
+
|
10
|
+
rule(:contracts) do
|
11
|
+
key.failure("must contain at least one contract") if value.size == 0
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Tangany
|
2
|
+
module Customers
|
3
|
+
module Contracts
|
4
|
+
module Customers
|
5
|
+
module CreateSchemas
|
6
|
+
module Contract
|
7
|
+
class << self
|
8
|
+
def schema
|
9
|
+
Dry::Schema.Params do
|
10
|
+
required(:type).filled(:string, included_in?: Tangany::Customers::Contract::ALLOWED_TYPES)
|
11
|
+
required(:signedDate).filled(:string, format?: ApplicationContract::DATE_REGEX)
|
12
|
+
optional(:cancelledDate).maybe(:string, format?: ApplicationContract::DATE_REGEX)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require_relative "contract"
|
2
|
+
|
3
|
+
module Tangany
|
4
|
+
module Customers
|
5
|
+
module Contracts
|
6
|
+
module Customers
|
7
|
+
module CreateSchemas
|
8
|
+
module Customer
|
9
|
+
module ClassMethods
|
10
|
+
def schema
|
11
|
+
Dry::Schema.Params do
|
12
|
+
required(:id).filled(:string, max_size?: 40)
|
13
|
+
required(:owner).hash do
|
14
|
+
required(:entityId).filled(:string)
|
15
|
+
end
|
16
|
+
required(:authorized).array(:hash) do
|
17
|
+
required(:entityId).filled(:string)
|
18
|
+
end
|
19
|
+
required(:contracts).array(CreateSchemas::Contract.schema)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
extend ClassMethods
|
25
|
+
|
26
|
+
def self.included(base)
|
27
|
+
base.extend(ClassMethods)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|