omgnetwork / ewallet Goto Github PK
View Code? Open in Web Editor NEWeWallet Backend for the OmiseGO SDKs.
Home Page: https://omisego.network/
License: Apache License 2.0
eWallet Backend for the OmiseGO SDKs.
Home Page: https://omisego.network/
License: Apache License 2.0
Issue:
After running mix seed --sample in the ewallet Docker container (docker exec -it omisego_ewallet_1 mix seed --sample) and trying to follow the instructions to login as [email protected], the login is denied and the following text is output by the ewallet Docker container:
ewallet_1 | 17:38:27.435 request_id=2kmqfgt2as9jim219g0002n1 [info] GET /admin
ewallet_1 | 17:38:27.514 request_id=2kmqfgt2as9jim219g0002n1 [info] Sent 200 in 78ms
ewallet_1 | 17:38:40.124 request_id=2kmqfhkmpvce4nsp2o0002q1 [info] POST /admin/api/login
ewallet_1 | 17:38:40.237 request_id=2kmqfhkmpvce4nsp2o0002q1 [info] Sent 500 in 113ms
ewallet_1 | 17:38:40.239 [error] #PID<0.1125.0> running UrlDispatcher.Plug terminated
ewallet_1 | Server: localhost:4000 (http)
ewallet_1 | Request: POST /admin/api/login
ewallet_1 | ** (exit) an exception was raised:
ewallet_1 | ** (FunctionClauseError) no function clause matching in Base.url_decode64/2
ewallet_1 | (elixir) lib/base.ex:482: Base.url_decode64(nil, [padding: false])
ewallet_1 | (salty) lib/salty/utils.ex:18: Salty.Utils.decode_key/2
ewallet_1 | (salty) lib/salty/secret_box.ex:53: Salty.SecretBox.decrypt/1
ewallet_1 | (cloak) lib/cloak.ex:170: anonymous fn/3 in Cloak.decrypt/1
ewallet_1 | (elixir) lib/enum.ex:1899: Enum."-reduce/3-lists^foldl/2-0-"/3
ewallet_1 | (cloak) lib/cloak.ex:164: Cloak.decrypt/1
ewallet_1 | (cloak) lib/cloak/types/encrypted_map_field.ex:26: Cloak.EncryptedMapField.load/1
ewallet_1 | (ecto) lib/ecto/type.ex:647: Ecto.Type.process_loaders/3
Compose File:
version: '2.1'
services:
ewallet:
image: omisego/ewallet:latest
depends_on:
db:
condition: service_healthy
environment:
- DATABASE_URL=postgresql://postgres:password@db:5432/ewallet
- LOCAL_LEDGER_DATABASE_URL=postgresql://postgres:password@db:5432/local_ledger
ports:
- 4000:4000
db:
image: postgres
restart: always
environment:
POSTGRES_PASSWORD: password
ports:
- 5432:5432
volumes:
- ./postgres-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 30s
timeout: 30s
retries: 3
Commands:
$ docker-compose up
$ docker exec omisego_ewallet_1 mix do local.rebar --force, local.hex --force, ecto.create, ecto.migrate
$ docker exec -it omisego_ewallet_1 mix seed --sample
When using the ruby-sdk
I noticed that the transactions endpoints don't return the amount that was processed for a given transaction. I believe these endpoints are using this serializer (I have limited elixir exposure so don't trust me 😬) https://github.com/omisego/ewallet/blob/develop/apps/ewallet_api/lib/ewallet_api/v1/serializers/json/transaction_serializer.ex
local rails app using omisego
gem connecting to the eWallet API (omise private test env)
When calling OmiseGO::Transaction#all_for_user
I expect amount
to be serialized and returned in the response.
amount
is not serialized
Things like:
Currently 3 instances of ewallet
is using approximately 60 connections (20 each for each instance, 10 for ewallet, 10 for ledger):
postgres=> select datname, COUNT(datname) from pg_stat_activity GROUP BY datname;
datname | count
-----------------+-------
staging_ewallet | 30
staging_ledger | 30
(4 rows)
This might cause problems with some setups, such as Google Cloud SQL which has very low limit by default to prevent OOM.
Creating minted tokens response returns that the request is bad. I have tried in swagger, admin panel and go. Even though I am using the default parameters it results in the following response:
{
"version": "1",
"success": false,
"data": {
"object": "error",
"messages": null,
"description": "Invalid parameter provided",
"code": "client:invalid_parameter"
}
}
I am on commit 169bf5c.
Parameters:
{
"symbol": "BTC",
"name": "Bitcoin",
"description": "desc",
"subunit_to_unit": 100
}
In order to proceed with blockchain integration, we need to finally add this feature we've been pushing to "later". With this, we'll have a log of all actions that happened in the system and we will be able to find out who did what and when.
1) test /transactions.all returns all the transactions (EWalletAPI.V1.TransactionControllerTest)
test/ewallet_api/v1/controllers/transaction_controller_test.exs:42
Assertion with == failed
code: assert Enum.map(response["data"]["data"], fn t -> t["id"] end) == [meta.transfer_1().id(), meta.transfer_2().id(), meta.transfer_3().id(), meta.transfer_4().id(), meta.transfer_5().id(), meta.transfer_6().id(), meta.transfer_7().id(), meta.transfer_8().id()]
left: ["a6c65166-7694-476e-b031-5879f97ce60e",
"3b38eb21-d483-4f58-ba67-68e8e2f04ad1",
"2b23faf0-c724-4ded-9764-438fba02eb69",
"2f2816d2-e60f-4a57-a8be-85e8bbf7e90c",
"c18165f0-18e7-405c-b825-99a2497c0774",
"b83cc2e9-8285-4970-a4dd-f52c2e96fca9",
"5ab273af-861e-4b26-8f36-8d4fbb27c210",
"6129e74e-86cc-4fb2-ae9b-d94b350b7000"]
right: ["2b23faf0-c724-4ded-9764-438fba02eb69",
"2f2816d2-e60f-4a57-a8be-85e8bbf7e90c",
"c18165f0-18e7-405c-b825-99a2497c0774",
"b83cc2e9-8285-4970-a4dd-f52c2e96fca9",
"5ab273af-861e-4b26-8f36-8d4fbb27c210",
"6129e74e-86cc-4fb2-ae9b-d94b350b7000",
"a6c65166-7694-476e-b031-5879f97ce60e",
"3b38eb21-d483-4f58-ba67-68e8e2f04ad1"]
stacktrace:
test/ewallet_api/v1/controllers/transaction_controller_test.exs:48: (test)
Jenkins, CI
Run the test few times.
Not randomly failing
Randomly failing
Exchange pairs can be synced when creating/updating. This is currently missing from the exchange pair form.
mix seed
shouldn't error if the BASE_URL
wasn't set.
$ uname -a
Linux srv1 4.4.86+ #1 SMP Thu Dec 7 20:11:11 PST 2017 x86_64 GNU/Linux
Leave out BASE_URL
when running mix seed
Seed works with URL fallback to example.com
or something.
Without BASE_URL
:
$ env |grep ^BASE_URL
$ mix seed
** (ArgumentError) argument error
apps/ewallet/priv/repo/report_minimum.exs:5: (file)
(elixir) lib/code.ex:334: Code.load_file/2
With BASE_URL
:
$ env BASE_URL=http://www.example.com/ mix seed
...snip...
Database seeding completed. Enjoy!
This issue is a simple task to get started with the eWallet SDK. It's available for anyone from the community to work on - don't be shy!
Currently, the API docs are available in Swagger format and in YAML. We'd like them to be available in JSON as well under /api/docs.json
for client to potentially generate SDK code dynamically.
$ bin/ewallet export filename.json
$ bin/ewallet import filename.json
For easier backups, etc.
There seems to be a typo on Dockerhub which causes a syntax error.
docker exec <container-id> mix ecto.create, ecto.migrate
should be docker exec <container-id> mix do ecto.create, ecto.migrate
.
Also the current latest image doesn't seem to properly install mix local.hex
and mix local.rebar
. Since I get the following error:
docker exec d5967cfb5a10 mix do ecto.create, ecto.migrate
Could not find Hex, which is needed to build dependency :credo
Shall I install Hex? (if running non-interactively, use "mix local.hex --force") [Yn] ** (Mix) Could not find an SCM for dependency :credo from EWallet.Umbrella.Mixfile
I used the following docker-compose.yml with docker-compose up
and after that ran docker exec <container-id> mix do ecto.create, ecto.migrate
in a seperate window.
version: '3.1'
services:
db:
image: postgres
omisego:
image: omisego/ewallet:latest
ports:
- 4000:4000
environment:
DATABASE_URL: "postgresql://postgres@db:5432/ewallet"
LOCAL_LEDGER_DATABASE_URL: "postgresql://postgres@db:5432/local_ledger"
links:
- db
I expected the Dockerfile in omisego/ewallet:latest to properly install local.hex and local.rebar.
$ docker exec d5967cfb5a10 mix do ecto.create, ecto.migrate
Could not find Hex, which is needed to build dependency :credo
Shall I install Hex? (if running non-interactively, use "mix local.hex --force") [Yn] ** (Mix) Could not find an SCM for dependency :credo from EWallet.Umbrella.Mixfile
To simplify setup.
We should support GraphicsMagick in addition to ImageMagick. GraphicsMagick has a much lighter footprint, uses less resource, and likely cover all features we want (resizing images). It also has mostly compatible API with ImageMagick. We should only need to prefix existing ImageMagick invocation with gm
.
Currently we're using libsodium for metadata encryption in the eWallet DB and Local Ledger DB. Unfortunately, as libsodium (via enacl) is a NIF and I couldn't find a way to bundle libsodium along with release, this makes distributing eWallet binaries for supported platforms a bit harder than I'd hope (e.g. no cross compilation, for one thing).
As libsodium is only used for metadata encryption via Cloak (hopefully not very important) it might more more feasible to switch to AES256-GCM instead. I'd love to hear what you think @thibault @unnawut. Also looping in @fred.
Currently, cached balances are either calculated from scratch (strategy since_beginning
) or from the last caching point (strategy since_last_cached
).
The since_last_cached
strategy should feature an additional option (reset_frequency
) to allow a provider to specify a once in a while reset of the cache. Basically, every X times (as specified in reset_frequency
, the since_last_cached
strategy will switch to a since_beginning
strategy.
This feature prevents an invalid cached balance from running rampant forever, since it will be reset and re-calculated from scratch. Note that incorrect balances should not happen, but this measure will ensure that if it does happen once, the problem will solve itself and give us time to figure out the problem without breaking the whole system.
/account.get_wallets
with owned
= false.For example, missing DATABASE_URL
shouldn't cause a raise, but the app should fail with message among the line of DATABASE_URL is not set, please set it to: ...
Cannot get ewallet to setup correctly on Ubuntu using Docker or git clone.
Describe your issue here.
git clone https://github.com/omisego/ewallet && cd ./ewallet
$ mix deps.get
The above instructions are not working. I get an error stating * (Mix) The task "archive.check" could not be found.
Also when using the docker image, i keep getting the below error:
23:32:07.935 [error] Postgrex.Protocol (#PID<0.778.0>) failed to connect: ** (DBConnection.ConnectionError) tcp connect (127.0.0.1:5432): connection refused - :econnrefused
I CAN connect to that port on my local so i don't know why i'm getting the issue.
Ubuntu 17
Hello! I want to contribute on your project with making logo design. What do you think about it?
Currently Pagination is only possible via per_page
/ page
. In order to support faster pagination and allow infinite scrolling pagination, we need to support pagination via ID.
page_record_id
: defines after which record the wanted set of records starts.per_page
: defines how many records are wanted.The attribute names are up for discussions.
query =
from(
k in Key,
where: k.access_key == ^access,
join: a in assoc(k, :account),
preload: [account: a]
)
Running non-Init process as PID 1 is a Bad Idea ™.
Docker image generated from Dockerfile
docker build
)Lightweight init being ran as PID 1, such as Tini, or S6.
Erlang VM is running as PID 1.
The current README for the project is a little big overwhelming to get started. I believe the user will benefit greatly if we simplify the README to just topic user will first look for, and link to a more advanced topics in the docs/ directory.
Here's some example of a project I stumbled upon that has a great README or something we could take hint from:
Feel free to add more examples.
Currently, the eWallet cannot be used as a stand-alone with only mobile applications using it (currently, it is needed for a provider to create an application to store users, etc.)
This feature is needed for the sample Coffee shop application we're going to be working on.
It involves:
/signup
is currently missing. The user can then see his balances or generate his identity QR code.Tasks:
provider_user_id
/user.signup
endpoint in client API, which will only proceed a request if ALLOW_USER_REGISTRATION
is set to true
(defaults to false
)/user.login
endpoint in client API (which follows the same rules as above, depending on ALLOW_USER_REGISTRATION
And fix all the reports (hint: a lot)
Running mix seed caused an Argument error.
I installed all dependencies with brew and followed all the steps in Setting up. After pressing Enter to start seeding the following error is shown:
** (ArgumentError) argument error
:erlang.bit_size(%EWalletDB.AuthToken{__meta__: #Ecto.Schema.Metadata<:loaded, "auth_token">, account: #Ecto.Association.NotLoaded<association :account is not loaded>, account_uuid: "d5b1eb7e-1397-4e8e-8531-0b6dfe166438", expired: nil, id: "atk_01cczydqdxtpawt0jxax5k8m5c", inserted_at: ~N[2018-05-08 13:18:04.733672], owner_app: "admin_api", token: "_PXmVfh6jZjZM57bvZ_O339He1VWP-D9r4cgJjrKpPE", updated_at: ~N[2018-05-08 13:18:04.733683], user: #Ecto.Association.NotLoaded<association :user is not loaded>, user_uuid: "35ef600a-8ea2-41ad-a793-e59a5d20afcc", uuid: "e09068c2-444c-4483-8889-51c4930a0103"})
apps/ewallet/priv/repo/report_minimum.exs:86: (file)
(elixir) lib/code.ex:629: Code.load_file/2
apps/ewallet/priv/repo/seeder.exs:160: EWallet.Seeder.call/1
(elixir) lib/code.ex:677: Code.require_file/2
(mix) lib/mix/tasks/run.ex:136: Mix.Tasks.Run.run/5
(mix) lib/mix/tasks/run.ex:76: Mix.Tasks.Run.run/1
(mix) lib/mix/task.ex:314: Mix.Task.run_task/3
(mix) lib/mix/task.ex:348: Mix.Task.run_alias/3
(mix) lib/mix/task.ex:277: Mix.Task.run/2
(mix) lib/mix/cli.ex:80: Mix.CLI.run_task/2
The list of API error codes is on Google Drive and seems to be access-protected.
Access the "eWallet Error Codes" link from this page (in incognito mode for instance)
https://ewallet.demo.omisego.io/api/swagger#/
See the doc
Authorization prompt from Google Drive
Currently, it isn't possible to do proper advanced filtering using search_term
and search_terms
. An advanced filtering system needs to be implemented (potentially using a new field, filters
?) that would contain a list of AND
/OR
predicates.
The filtering system should allow association filtering up to one level (e.g. from /wallet.all
, I should be able to specify account.name = something
. Different comparison mechanism should be supported: greater
, equal
, etc.).
Open to suggestions for Elixir libraries that could handle this.
Enables an eWallet server to perform exchanges and transfers from/to different minted tokens within its own eWallet environment.
This RFC describes the standard endpoints, flows, request/response formats, error codes needed to allow an eWallet server to perform cross-token exchanges within its own eWallet environment.
It is expected that there will be following RFCs for exchanges across eWallet environments and across the OMG network.
Prior to this RFC, the eWallet server is able to transfer values between accounts and/or users, if and only if the from
and to
are of the same minted token.
One of the main purposes of the eWallet is to enable exchanges of different minted tokens. Since, different mechanisms could be used and potentially impact future integrations with centralized & decentralized exchanges, it is important for this mechanism to be put up as an RFC and discussed before implementing.
Internal exchange: An exchange transaction that happens within the same eWallet environment.
External exchange: An exchange transaction that involves a third-party, e.g. exchanging with a centralized or decentralized exchange services. The external exchange is out of scope of this RFC.
Exchange pair: A pair of minted tokens that are allowed to be exchanged.
Same-token transfer: A transaction whose its from_address
and to_address
are different, but from_token_uuid
and to_token_uuid
are the same.
Exchange transaction: A transaction whose its from_address
and to_address
are the same, but the from_token_uuid
and to_token_uuid
are different.
Exchange transfer: A transaction whose its from_address
and to_address
are different, and the from_token_uuid
and to_token_uuid
are also different.
EWalletDB.ExchangePair: Contains the data about a pair of minted tokens that are allowed to be exchanged.
from_minted_token
(string)to_minted_token
(string)rate
(float)reversible
(boolean)effective_at
(datetime) - so the exchange rate can be set in advanceEWalletDB.Transfer: Contains the data about each transaction that happened.
from_amount
(integer)from_token_uuid
(uuid)to_amount
(integer)to_token_uuid
(uuid)metadata.exchange_rate
(float, containing the exchange rate used for the transfer)from_amount
<- amount
from_token_uuid
<- token_uuid
to_amount
<- amount
to_token_uuid
<- token_uuid
amount
(use from_amount
and to_amount
instead)token_uuid
(use from_token_uuid
and to_token_uuid
instead)LocalLedgerDB.Transaction: A logical group of ledger entries that represents a single business event (e.g. a same-token transfer, an exchange transaction, an exchange transfer).
Each EWalletDB.Transfer
item is one LocalLedgerDB.Transaction
. One LocalLedgerDB.Transaction
for an exchange has at least 4 LocalLedgerDB.Entry
. For example:
For internal exchanges, the operation happens at the DB's transaction level so it should be seamlessly handled within the eWallet server as long as the exchange operations are wrapped inside a single DB transaction.
At the API level, this can be represented as a typical /transfer
endpoint, where the only difference is that for exchanges, the from_token_id
and to_token_id
have different values.
(Assuming subunit_to_unit = 1 for simplicity)
# EWalletDB.Transfer
{
"id": "tfr_1234567890",
"type": "internal",
"from": "bal_alice_1111",
"from_amount": 10,
"from_token_id": "tok_AAA_1234",
"to": "bal_bob_2222",
"to_amount": 10,
"to_token_id": "tok_AAA_1234"
}
# LocalLedgerDB.Transaction
{
"uuid": "44d7fc38-b250-4456-a4e8-0d23dc52f310",
}
# LocalLedgerDB.Entry
[
{
"transaction_uuid": "44d7fc38-b250-4456-a4e8-0d23dc52f310",
"type": "debit",
"amount": 10,
"wallet_address": "bal_alice_1111",
"token_id": "tok_AAA_1234"
},
{
"transaction_uuid": "44d7fc38-b250-4456-a4e8-0d23dc52f310",
"type": "credit",
"amount": 10,
"wallet_address": "bal_bob_2222",
"token_id": "tok_AAA_1234"
}
]
This is when a user wants to exchange a token for another, where the sender and the receiver is the same address.
(Assuming subunit_to_unit = 1 for simplicity)
# EWalletDB.Transfer
{
"id": "tfr_1234567890",
"type": "exchange",
"from": "bal_alice_1111",
"from_amount": 10,
"from_token_id": "tok_AAA_1234",
"to": "bal_alice_1111",
"to_amount": 1,
"to_token_id": "tok_BBB_1234"
}
# LocalLedgerDB.Transaction
{
"uuid": "44d7fc38-b250-4456-a4e8-0d23dc52f310",
}
# LocalLedgerDB.Entry
[
{
"transaction_uuid": "44d7fc38-b250-4456-a4e8-0d23dc52f310",
"type": "debit",
"amount": 10,
"wallet_address": "bal_alice_1111",
"token_id": "tok_AAA_1234"
},
{
"transaction_uuid": "44d7fc38-b250-4456-a4e8-0d23dc52f310",
"type": "credit",
"amount": 10,
"wallet_address": "bal_exchange_2222",
"token_id": "tok_AAA_1234"
},
{
"transaction_uuid": "44d7fc38-b250-4456-a4e8-0d23dc52f310",
"type": "debit",
"amount": 1,
"wallet_address": "bal_exchange_2222",
"token_id": "tok_BBB_1234"
},
{
"transaction_uuid": "44d7fc38-b250-4456-a4e8-0d23dc52f310",
"type": "credit",
"amount": 1,
"wallet_address": "bal_alice_1111",
"token_id": "tok_BBB_1234"
}
]
This is when a sender wants to transfer a token and expects the receiver at a different address to receive a different token.
(Assuming subunit_to_unit = 1 for simplicity)
# EWalletDB.Transfer
{
"id": "tfr_1234567890",
"type": "exchange_transfer",
"from": "bal_alice_1111",
"from_amount": 10,
"from_token_id": "tok_AAA_1234",
"to": "bal_bob_2222",
"to_amount": 1,
"to_token_id": "tok_BBB_1234"
}
# LocalLedgerDB.Transaction
{
"uuid": "44d7fc38-b250-4456-a4e8-0d23dc52f310",
}
# LocalLedgerDB.Entry
[
{
"transaction_uuid": "44d7fc38-b250-4456-a4e8-0d23dc52f310",
"type": "debit",
"amount": 10,
"wallet_address": "bal_alice_1111",
"token_id": "tok_AAA_1234"
},
{
"transaction_uuid": "44d7fc38-b250-4456-a4e8-0d23dc52f310",
"type": "credit",
"amount": 10,
"wallet_address": "bal_exchange_3333",
"token_id": "tok_AAA_1234"
},
{
"transaction_uuid": "44d7fc38-b250-4456-a4e8-0d23dc52f310",
"type": "debit",
"amount": 1,
"wallet_address": "bal_exchange_3333",
"token_id": "tok_BBB_1234"
},
{
"transaction_uuid": "44d7fc38-b250-4456-a4e8-0d23dc52f310",
"type": "credit",
"amount": 1,
"wallet_address": "bal_bob_2222",
"token_id": "tok_BBB_1234"
}
]
The rounding method to use is "Round half to even", or the banker's rounding.
Transactions are always made with the exchange amounts, not the rate. Although an exchange transaction is based on the exchange rate, the parties agree on the exchanging amounts, not the rate. This is important because the division remainders and the rounding will almost always cause the exchanging parties to get more or less tokens depending on the rounding method used.
Consequently, the UI must display the exchanging amounts and asks user to confirm the amount, not the rate. The rate can be displayed as a complimenting information.
/exchange.calculate
endpointCalculate the amount of minted tokens to be exchanged, used for confirming the exact amount with the user before executing the actual exchange.
from_amount
(integer, optional)from_token_id
(string, required)to_amount
(integer, optional)to_token_id
(string, required)from_amount
is provided, to_amount
will be calculated based on the exchange rate and rounding method.to_amount
is provided, from_amount
will be calculated based on the exchange rate and rounding method.from_amount
and to_amount
are provided, and the amounts are the same as the server's calculation, a successful response is returned.from_amount
and to_amount
are provided, but the amounts are different from the server's calculation, an exchange:invalid_rate
response is returned.{
"from_amount": 100,
"from_token_id": "tok_AAA_1234",
"to_amount": 100,
"to_token_id": "tok_BBB_1234"
}
{
"version": "1",
"success": true,
"data": {
"object": "exchange_calculation",
"from_amount": 100,
"from_token_id": "tok_AAA_1234",
"to_amount": 100,
"to_token_id": "tok_BBB_1234",
"exchange_pair": "exg_AAA_BBB_123456",
"exchange_rate": "1.00",
"exchange_reversed": false
}
}
/transfer
endpointExchange a certain amount of minted tokens between two addresses.
from_amount
(integer, optional)from_token_id
(string, required)from_address
(string, required)to_amount
(integer, optional)to_token_id
(string, required)to_address
(string, required)exchange_account_id
(string, optional)The request may be sent without from_amount
or to_amount
and subjects to the same conditions as /exchange.calculate
.
If the exchange_account_id
is not provided, the exchange will be performed with the master account.
{
"from_token_id": "tok_AAA_1234",
"from_address": "81e75f46-ee14-4e4c-a1e5-cddcb26dce9c",
"to_amount": 100,
"to_token_id": "tok_BBB_1234",
"to_address": "4aa07691-2f99-4cb1-b36c-50763e2d2ba8",
"exchange_account_id": "acc_01ca2p8jqans5aty5gj5etmjcf",
"metadata": {},
"encrypted_metadata": {}
}
Use the current response format (returns a list of affected wallets).
transaction:insufficient_funds
- when requestor does not have enough funds to exchange.exchange:insufficient_funds
- when the counterparty does not have enough funds to exchange back. It is important to distinguish between the user and the counterparty so that user-friendly error message can be displayed, and the user knows if its the counterparty's funds or theirs that is insufficient.exchange:pair_not_found
- when request requires an exchange pair that does not exist.exchange:pair_not_reversible
- when request requires an exchange pair that exists, but the pair does not allow to be exchanged in the opposite direction.exchange:invalid_rate
- when the provided exchange amounts or the exchange rate is invalid.Round-half-to-even or banker's rounding is used as it is commonly used in financial systems. It is also the default rounding mode for IEEE 754 (IEEE Standard for Floating-Point Arithmetic).
The exchange account defaults to the master account (the top-level account) for ease of use. However, for larger use cases, it's expected that an exchange_account_id
is provided as it's probably not ideal for all exchange transactions to go through the master account (for separation of concerns and accountability). This exchange_account_id
would also allow for more use cases, e.g. dedicate an account as the exchange account and put funds in there. It is then possible to limit the amount of tokens that can be exchanged by limiting the funds that the account has.
This RFC chose to reuse the /transfer
endpoint because of its similarities to an exchange transaction and exchange transfer. An exchange transaction is basically a transfer of different tokens to the same address, while an exchange transfer can be represented by a transfer that has different from/to tokens.
There could be a discrepancy between the time /exchange.calculate
is made and when /transfer
happens. Given that this is an internal exchange and exchange rates are fixed, unchanged for most of the time. The discrepancy will be very rare to occur.
Mostly from internal discussions. Any suggestions for the references (either for or against this RFC) is appreciated.
Use deferred_config for compatibility with Distillery where config.exs will be evaluated at build time.
Currently, the ErrorHandler
can return an internal_server_error
for errors that are not handled properly.
Since this behavior is abnormal, it should be reported to Sentry.
Can't retrieve the full list of tokens.
I am on a fresh Vagrant install, prepared using the goban
repo.
mix seed --sample
) and launch the server/minted-token.create
/minted_token.get
on that token ID -> the token data is displayed/minted-token.all
-> no dataThis is the full JSON response I get from .all
endpoint :
{
"version": "1",
"success": true,
"data": {
"pagination": {
"per_page": 10,
"is_last_page": true,
"is_first_page": true,
"current_page": 1
},
"object": "list",
"data": []
}
}
And this is the response I got from .get
endpoint :
{
"version": "1",
"success": true,
"data": {
"updated_at": "2018-02-28T23:10:13.527129Z",
"symbol": "SIMSIM",
"subunit_to_unit": 100,
"object": "minted_token",
"name": "Simcoinzzz",
"id": "SIMSIM:330acf3a-f46a-4dd8-b642-4c246d02da26",
"created_at": "2018-02-28T23:10:13.527117Z"
}
}
All tests have been done through Swagger only.
The token list should not be empty.
No token is available in that list.
See also discussion in #188 (comment)
Randomly Failing to retrieve a transfer after insert in:
def insert(attrs) do
changeset = changeset(%Transfer{}, attrs)
opts = [on_conflict: :nothing, conflict_target: :idempotency_token]
case Repo.insert(changeset, opts) do
{:ok, transfer} ->
{:ok, get_by_idempotency_token(transfer.idempotency_token)}
changeset ->
changeset
end
end
Staging environment, using Ruby SDK or iOS SDK.
env.rb
with real values~/src/ruby-sdk on T305-renaming! ⌚ 16:05:55
$ rspec ./spec/omisego/wallet_spec.rb ‹ruby-2.3.3›
OmiseGO::Wallet
.all
retrieves the list of wallets
.credit
with valid params
credits the user's wallet
with params account_id and account_address
credits the user's wallet (FAILED - 1)
.debit
with valid params
debits the user's wallet (FAILED - 2)
with params account_id and account_address
debit/s the user's wallet
Failures:
1) OmiseGO::Wallet.credit with params account_id and account_address credits the user's wallet
Failure/Error: expect(wallets).to be_kind_of OmiseGO::List
expected #<OmiseGO::Error:70175132363600 code: server:internal_server_error, description: Something went wrong on the server, messages: > to be a kind of OmiseGO::List
# ./spec/omisego/wallet_spec.rb:67:in `block (5 levels) in <module:OmiseGO>'
# /Users/thibault/.rvm/gems/ruby-2.3.3/gems/vcr-3.0.3/lib/vcr/util/variable_args_block_caller.rb:9:in `call_block'
# /Users/thibault/.rvm/gems/ruby-2.3.3/gems/vcr-3.0.3/lib/vcr.rb:189:in `use_cassette'
# ./spec/omisego/wallet_spec.rb:55:in `block (4 levels) in <module:OmiseGO>'
2) OmiseGO::Wallet.debit with valid params debits the user's wallet
Failure/Error: expect(wallets).to be_kind_of OmiseGO::List
expected #<OmiseGO::Error:70175123941460 code: server:internal_server_error, description: Something went wrong on the server, messages: > to be a kind of OmiseGO::List
# ./spec/omisego/wallet_spec.rb:87:in `block (5 levels) in <module:OmiseGO>'
# /Users/thibault/.rvm/gems/ruby-2.3.3/gems/vcr-3.0.3/lib/vcr/util/variable_args_block_caller.rb:9:in `call_block'
# /Users/thibault/.rvm/gems/ruby-2.3.3/gems/vcr-3.0.3/lib/vcr.rb:189:in `use_cassette'
# ./spec/omisego/wallet_spec.rb:76:in `block (4 levels) in <module:OmiseGO>'
Finished in 3.04 seconds (files took 0.46432 seconds to load)
5 examples, 2 failures
Failed examples:
rspec ./spec/omisego/wallet_spec.rb:54 # OmiseGO::Wallet.credit with params account_id and account_address credits the user's wallet
rspec ./spec/omisego/wallet_spec.rb:75 # OmiseGO::Wallet.debit with valid params debits the user's wallet
The response should be successful instead of 500
.
The server returns 500
.
The server crashes because nil
is passed as the first argument in those functions:
defp process_with_transfer(%Transfer{status: "pending"} = transfer, wallets, token) do
transfer
|> TransferGate.process()
|> process_with_transfer(wallets, token)
end
defp process_with_transfer(%Transfer{status: "confirmed"} = transfer, wallets, token) do
{:ok, transfer, wallets, token}
end
defp process_with_transfer(%Transfer{status: "failed"} = transfer, _wallets, _token) do
resp = transfer.ledger_response
{:error, transfer, resp["code"], resp["description"]}
end
Which happens because of get_by_idempotency_token
is returning nil
in the following code, which is not supposed to happen becasue either a record has just been inserted or has been inserted in another process.
def insert(attrs) do
changeset = changeset(%Transfer{}, attrs)
opts = [on_conflict: :nothing, conflict_target: :idempotency_token]
case Repo.insert(changeset, opts) do
{:ok, transfer} ->
{:ok, get_by_idempotency_token(transfer.idempotency_token)}
changeset ->
changeset
end
end
Thoughts? I ran out of ideas except for the retries with delay to solve the fact that the DB state does not seem up to date.
In Swagger the example response for a successful login in the AdminAPI has the following AuthenticationTokenSchema:
object string
authentication_token string
user_id string
user UserSchema
account_id string
account AccountSchema
But when I do an actual login it also returns the key master_admin bool
. Is there a reason for this or is it missing from the example?
Commit 169bf5c
Hey everybody,
This isn't really an issue but I don't know where to share this. I just published a Go SDK for the eWallet and Admin API: https://github.com/Alainy/OmiseGo-Go-SDK
It isn't a finished package yet but I hope it can be of use for someone. Also feedback is welcome!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.