tangany 0.0.1

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.
Files changed (87) hide show
  1. checksums.yaml +7 -0
  2. data/.reek.yml +4 -0
  3. data/.rspec +3 -0
  4. data/.rubycritic.yml +7 -0
  5. data/.sasori/Dockerfile +51 -0
  6. data/.simplecov +13 -0
  7. data/CHANGELOG.md +5 -0
  8. data/CODE_OF_CONDUCT.md +84 -0
  9. data/Gemfile +20 -0
  10. data/Gemfile.lock +210 -0
  11. data/LICENSE.txt +21 -0
  12. data/README.md +410 -0
  13. data/Rakefile +133 -0
  14. data/bin/console +22 -0
  15. data/bin/setup +8 -0
  16. data/bin/test-live +170 -0
  17. data/lib/config/chains.json +22 -0
  18. data/lib/tangany/application_contract.rb +19 -0
  19. data/lib/tangany/collection.rb +13 -0
  20. data/lib/tangany/config.rb +24 -0
  21. data/lib/tangany/custody/client.rb +37 -0
  22. data/lib/tangany/custody/collection.rb +17 -0
  23. data/lib/tangany/custody/contracts/wallets/create.rb +23 -0
  24. data/lib/tangany/custody/contracts/wallets/list.rb +37 -0
  25. data/lib/tangany/custody/contracts/wallets/update.rb +21 -0
  26. data/lib/tangany/custody/contracts/wallets.rb +3 -0
  27. data/lib/tangany/custody/contracts.rb +1 -0
  28. data/lib/tangany/custody/objects/wallet.rb +17 -0
  29. data/lib/tangany/custody/objects/wallet_recovery.rb +10 -0
  30. data/lib/tangany/custody/objects/wallet_status.rb +10 -0
  31. data/lib/tangany/custody/objects.rb +3 -0
  32. data/lib/tangany/custody/resource.rb +29 -0
  33. data/lib/tangany/custody/resources/wallet_statuses_resource.rb +9 -0
  34. data/lib/tangany/custody/resources/wallets_resource.rb +34 -0
  35. data/lib/tangany/custody/resources.rb +2 -0
  36. data/lib/tangany/custody.rb +7 -0
  37. data/lib/tangany/customers/application_contract.rb +6 -0
  38. data/lib/tangany/customers/client.rb +37 -0
  39. data/lib/tangany/customers/collection.rb +16 -0
  40. data/lib/tangany/customers/contracts/customers/create.rb +17 -0
  41. data/lib/tangany/customers/contracts/customers/create_schemas/contract.rb +21 -0
  42. data/lib/tangany/customers/contracts/customers/create_schemas/customer.rb +34 -0
  43. data/lib/tangany/customers/contracts/customers/list.rb +17 -0
  44. data/lib/tangany/customers/contracts/customers/update.rb +14 -0
  45. data/lib/tangany/customers/contracts/customers/update_schemas/customer.rb +15 -0
  46. data/lib/tangany/customers/contracts/customers.rb +3 -0
  47. data/lib/tangany/customers/contracts/natural_persons/create.rb +23 -0
  48. data/lib/tangany/customers/contracts/natural_persons/create_schemas/address.rb +23 -0
  49. data/lib/tangany/customers/contracts/natural_persons/create_schemas/document.rb +25 -0
  50. data/lib/tangany/customers/contracts/natural_persons/create_schemas/kyc.rb +24 -0
  51. data/lib/tangany/customers/contracts/natural_persons/create_schemas/natural_person.rb +44 -0
  52. data/lib/tangany/customers/contracts/natural_persons/create_schemas/pep.rb +22 -0
  53. data/lib/tangany/customers/contracts/natural_persons/create_schemas/sanctions.rb +22 -0
  54. data/lib/tangany/customers/contracts/natural_persons/list.rb +17 -0
  55. data/lib/tangany/customers/contracts/natural_persons/update.rb +14 -0
  56. data/lib/tangany/customers/contracts/natural_persons/update_schemas/natural_person.rb +15 -0
  57. data/lib/tangany/customers/contracts/natural_persons.rb +3 -0
  58. data/lib/tangany/customers/contracts/wallet_links/create.rb +28 -0
  59. data/lib/tangany/customers/contracts/wallet_links/list.rb +17 -0
  60. data/lib/tangany/customers/contracts/wallet_links.rb +2 -0
  61. data/lib/tangany/customers/contracts.rb +3 -0
  62. data/lib/tangany/customers/objects/address.rb +11 -0
  63. data/lib/tangany/customers/objects/contract.rb +13 -0
  64. data/lib/tangany/customers/objects/customer.rb +14 -0
  65. data/lib/tangany/customers/objects/document.rb +17 -0
  66. data/lib/tangany/customers/objects/kyc.rb +16 -0
  67. data/lib/tangany/customers/objects/natural_person.rb +30 -0
  68. data/lib/tangany/customers/objects/pep.rb +12 -0
  69. data/lib/tangany/customers/objects/sanctions.rb +12 -0
  70. data/lib/tangany/customers/objects/wallet_link.rb +14 -0
  71. data/lib/tangany/customers/objects.rb +5 -0
  72. data/lib/tangany/customers/resource.rb +11 -0
  73. data/lib/tangany/customers/resources/customers_resource.rb +27 -0
  74. data/lib/tangany/customers/resources/natural_persons_resource.rb +26 -0
  75. data/lib/tangany/customers/resources/wallet_links_resource.rb +37 -0
  76. data/lib/tangany/customers/resources.rb +3 -0
  77. data/lib/tangany/customers.rb +8 -0
  78. data/lib/tangany/error.rb +34 -0
  79. data/lib/tangany/json_patch.rb +65 -0
  80. data/lib/tangany/object.rb +43 -0
  81. data/lib/tangany/operation.rb +10 -0
  82. data/lib/tangany/resource.rb +80 -0
  83. data/lib/tangany/types.rb +7 -0
  84. data/lib/tangany/version.rb +3 -0
  85. data/lib/tangany.rb +47 -0
  86. data/sig/tangany.rbs +4 -0
  87. 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,3 @@
1
+ require_relative "wallets/create"
2
+ require_relative "wallets/list"
3
+ require_relative "wallets/update"
@@ -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,10 @@
1
+ module Tangany
2
+ module Custody
3
+ class WalletRecovery < Object
4
+ attribute :recoveryId, Types::String
5
+ attribute :scheduledPurgeDate, Types::DateTime
6
+
7
+ to_datetime :scheduledPurgeDate
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ module Tangany
2
+ module Custody
3
+ class WalletStatus < Object
4
+ attribute :address, Types::String
5
+ attribute :balance, Types::String
6
+ attribute :currency, Types::String
7
+ attribute :nonce, Types::Integer
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,3 @@
1
+ require_relative "objects/wallet"
2
+ require_relative "objects/wallet_status"
3
+ require_relative "objects/wallet_recovery"
@@ -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,9 @@
1
+ module Tangany
2
+ module Custody
3
+ class WalletStatusesResource < Resource
4
+ def retrieve(wallet_id)
5
+ WalletStatus.new(get_request("#{@chain["base_path"]}/wallet/#{wallet_id}").body)
6
+ end
7
+ end
8
+ end
9
+ 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,2 @@
1
+ require_relative "resources/wallet_statuses_resource"
2
+ require_relative "resources/wallets_resource"
@@ -0,0 +1,7 @@
1
+ require_relative "custody/client"
2
+ require_relative "custody/collection"
3
+ require_relative "custody/resource"
4
+
5
+ require_relative "custody/contracts"
6
+ require_relative "custody/objects"
7
+ require_relative "custody/resources"
@@ -0,0 +1,6 @@
1
+ module Tangany
2
+ module Customers
3
+ class ApplicationContract < Tangany::ApplicationContract
4
+ end
5
+ end
6
+ 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