diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index aea426f7..83af545d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,9 +1,16 @@ +# https://github.com/docker/build-push-action/blob/master/docs/advanced/tags-labels.md + name: ci on: push: branches: - - main + - 'main' + tags: + - 'v*.*.*' + pull_request: + branches: + - 'main' jobs: docker: @@ -12,6 +19,21 @@ jobs: - name: Checkout uses: actions/checkout@v2 + - + name: Docker meta + id: meta + uses: docker/metadata-action@v3 + with: + # list of Docker images to use as base name for tags + images: | + ghcr.io/eqlabs/flow-wallet-service + # generate Docker tags based on the following events/attributes + tags: | + type=ref,event=branch + type=ref,event=pr + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=semver,pattern={{major}} - name: Set up QEMU uses: docker/setup-qemu-action@v1 @@ -40,8 +62,9 @@ jobs: with: context: . file: ./docker/wallet/Dockerfile - push: true - tags: ghcr.io/eqlabs/flow-wallet-service:latest + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} cache-from: type=local,src=/tmp/.buildx-cache cache-to: type=local,dest=/tmp/.buildx-cache-new - diff --git a/README.md b/README.md index 45bc55d2..b5f8a825 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Flow Wallet Service v0.0.1 +# Flow Wallet Service v0.0.2 A custodial wallet service for tokens on the Flow blockchain. @@ -18,9 +18,11 @@ A custodial wallet service for tokens on the Flow blockchain. DEFAULT_KEY_TYPE=local # Will store keys in your database, use "google_kms" if you have that setup ENCRYPTION_KEY=passphrasewhichneedstobe32bytes! # replace this with something that is 32 bytes + ENABLED_TOKENS=FlowToken:0x7e60df042a9c0868 + Running: - docker run -d --name flow-wallet-service --env-file .env ghcr.io/eqlabs/flow-wallet-service:0.0.1 + docker run -d --name flow-wallet-service --env-file .env ghcr.io/eqlabs/flow-wallet-service:0.0.2 ## Developing @@ -56,11 +58,22 @@ Run: # edit .env.test # feel free to use the private key in the example file as it is only for testing # admin address is always the same with flow emulator - docker-compose up -d + make build-cli + make up + make deploy go test -v ./... ## Configuration +### Enabled tokens + +A comma separated list of fungible tokens and their corresponding addresses enabled for this instance. Make sure to name each token exactly as it is in the corresponding cadence code (FlowToken, FUSD etc.). Include at least FlowToken as functionality without it is undetermined. + +Examples: + + ENABLED_TOKENS=FlowToken:0x0ae53cb6e3f42a79 + ENABLED_TOKENS=FlowToken:0x0ae53cb6e3f42a79,FUSD:0xf8d6e0586b0a20c7 + ### Database | Config variable | Environment variable | Description | Default | Examples | @@ -122,6 +135,8 @@ Configure Google KMS as the key storage for `flow-wallet-service` and set the ne PORT=3000 ACCESS_API_HOST=localhost:3569 + ENABLED_TOKENS=FlowToken:0x0ae53cb6e3f42a79 + DATABASE_DSN=wallet.db DATABASE_TYPE=sqlite diff --git a/accounts/accounts.go b/accounts/accounts.go index 0e7e605e..ed0e011a 100644 --- a/accounts/accounts.go +++ b/accounts/accounts.go @@ -31,8 +31,8 @@ type Account struct { type AccountToken struct { ID int `json:"-" gorm:"primaryKey"` AccountAddress string `json:"-" gorm:"uniqueIndex:addressname;index;not null"` - TokenAddress string `json:"-" gorm:"uniqueIndex:addressname;index;not null"` TokenName string `json:"name" gorm:"uniqueIndex:addressname;index;not null"` + TokenAddress string `json:"address" gorm:"uniqueIndex:addressname;index;not null"` CreatedAt time.Time `json:"-"` UpdatedAt time.Time `json:"-"` DeletedAt gorm.DeletedAt `json:"-" gorm:"index"` diff --git a/accounts/service.go b/accounts/service.go index 258ad40b..eceb68b4 100644 --- a/accounts/service.go +++ b/accounts/service.go @@ -183,10 +183,5 @@ func (s *Service) AccountFungibleTokens(address string) ([]AccountToken, error) address = flow_helpers.HexString(address) - tt, err := s.db.AccountTokens(address) - if err != nil { - return []AccountToken{}, err - } - - return tt, nil + return s.db.AccountTokens(address) } diff --git a/api/debug.http b/api/debug.http new file mode 100644 index 00000000..e3b09d86 --- /dev/null +++ b/api/debug.http @@ -0,0 +1,3 @@ +### Get debug +GET http://localhost:3000/v1/debug HTTP/1.1 +content-type: application/json diff --git a/api/openapi.yaml b/api/openapi.yaml index 6c61e361..6c061c67 100644 --- a/api/openapi.yaml +++ b/api/openapi.yaml @@ -2,13 +2,26 @@ openapi: 3.0.3 info: title: Flow Wallet Service API - version: 0.0.1 + version: 0.0.2 servers: - url: http://localhost:3000/v1 components: schemas: + debugInfo: + type: string + example: | + url: GET /v1/debug + Headers: + User-Agent: vscode-restclient + Content-Type: application/json + Connection: close + + ver: https://github.com/eqlabs/flow-wallet-service/commit/ + built on: + api version called: v1 + account: type: object properties: @@ -78,6 +91,49 @@ components: plainValue: type: string + token: + type: object + properties: + name: + type: string + example: "FlowToken" + address: + type: string + example: "0xf8d6e0586b0a20c7" + + tokenDetails: + type: object + properties: + name: + type: string + example: "FlowToken" + balance: + type: string + example: "9999999999.99700000" + + tokenWithdrawal: + type: object + properties: + transactionId: + type: string + example: "f1e272ee125b370e5129215179705791220764bf71da2aa938c94181b2c06685" + amount: + type: string + example: "1.0" + token: + type: string + example: "FlowToken" + recipient: + type: string + example: "0x01cf0e2f2f715450" + createdAt: + type: string + example: "2021-06-167T12:05:24.613704+03:00" + updatedAt: + type: string + example: "2021-06-16T12:05:24.617898+03:00" + + parameters: limit: name: limit @@ -121,8 +177,8 @@ components: required: true schema: type: string - enum: [FLOW, FUSD] - example: FLOW + enum: [flow-token, FUSD] + example: flow-token transactionId: name: transactionId @@ -133,6 +189,48 @@ components: example: "9613c9689a50a5ed9198dc43839cd90ef39203dfdd7ab54f0fc5ca12f256eef0" paths: + /debug: + get: + summary: Get debug information about the running instance. + responses: + "200": + description: OK + content: + text/plain: + schema: + $ref: "#/components/schemas/debugInfo" + + /fungible-tokens: + get: + summary: Get all fungible tokens + description: Get all fungible tokens that are enabled in this instance. + responses: + "200": + description: OK + content: + application/json: + schema: + type: array + items: + $ref: "#/components/schemas/token" + /scripts: + post: + summary: Execute a script on chain + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/script" + responses: + "200": + description: Ok + content: + application/json: + schema: + oneOf: + - $ref: "#/components/schemas/cadenceValue" + - $ref: "#/components/schemas/plainValue" + /jobs: get: summary: List all jobs @@ -253,20 +351,88 @@ paths: schema: $ref: "#/components/schemas/transaction" - /scripts: + /accounts/{address}/fungible-tokens: + parameters: + - $ref: "#/components/parameters/address" + get: + summary: Get account fungible tokens + description: Get all fungible tokens that are enabled for an account. + responses: + "200": + description: OK + content: + application/json: + schema: + type: array + items: + $ref: "#/components/schemas/token" + + /accounts/{address}/fungible-tokens/{tokenName}: + parameters: + - $ref: "#/components/parameters/address" + - $ref: "#/components/parameters/tokenName" + get: + summary: Get fungible tokens details for an account + description: Get details (balance) regarding a fungible token for an account. + responses: + "200": + description: OK + content: + application/json: + schema: + type: array + items: + $ref: "#/components/schemas/tokenDetails" post: - summary: Execute a script on chain - requestBody: - content: - application/json: - schema: - $ref: "#/components/schemas/script" + summary: Enable a fungible token for an account + responses: + "201": + description: OK + content: + application/json: + schema: + type: array + items: + $ref: "#/components/schemas/job" + + /accounts/{address}/fungible-tokens/{tokenName}/withdrawals: + parameters: + - $ref: "#/components/parameters/address" + - $ref: "#/components/parameters/tokenName" + get: + summary: List all withdrawals of a fungible token responses: "200": - description: Ok + description: OK content: application/json: schema: - oneOf: - - $ref: "#/components/schemas/cadenceValue" - - $ref: "#/components/schemas/plainValue" + type: array + items: + $ref: "#/components/schemas/tokenWithdrawal" + post: + summary: Create a fungible token withdrawal + responses: + "201": + description: OK + content: + application/json: + schema: + type: array + items: + $ref: "#/components/schemas/job" + + /accounts/{address}/fungible-tokens/{tokenName}/withdrawals/{transactionId}: + parameters: + - $ref: "#/components/parameters/address" + - $ref: "#/components/parameters/tokenName" + - $ref: "#/components/parameters/transactionId" + get: + summary: Get details of a fungible token withdrawal + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: "#/components/schemas/tokenWithdrawal" diff --git a/api/tokens.http b/api/tokens.http index d7bd4c32..a4b6512d 100644 --- a/api/tokens.http +++ b/api/tokens.http @@ -34,11 +34,11 @@ content-type: application/json "amount":"1.0" } -### Get FlowToken withdrawals for admin account +### List FlowToken withdrawals for admin account GET http://localhost:3000/v1/accounts/{{$dotenv ADMIN_ADDRESS}}/fungible-tokens/flow-token/withdrawals HTTP/1.1 content-type: application/json -### Get FUSD withdrawals for admin account +### List FUSD withdrawals for admin account GET http://localhost:3000/v1/accounts/{{$dotenv ADMIN_ADDRESS}}/fungible-tokens/fusd/withdrawals HTTP/1.1 content-type: application/json @@ -82,11 +82,11 @@ content-type: application/json "amount":"1.0" } -### Get FlowToken withdrawals for custody account +### List FlowToken withdrawals for custody account GET http://localhost:3000/v1/accounts/{{emulatorCustodyAccount}}/fungible-tokens/flow-token/withdrawals HTTP/1.1 content-type: application/json -### Get FUSD withdrawals for custody account +### List FUSD withdrawals for custody account GET http://localhost:3000/v1/accounts/{{emulatorCustodyAccount}}/fungible-tokens/fusd/withdrawals HTTP/1.1 content-type: application/json diff --git a/main_test.go b/main_test.go index 8691bff6..4864e6f8 100644 --- a/main_test.go +++ b/main_test.go @@ -999,7 +999,7 @@ func TestTokenHandlers(t *testing.T) { method: http.MethodGet, contentType: "application/json", url: fmt.Sprintf("/%s/fungible-tokens", aa[1].Address), - expected: `\[.*{"name":"FUSD"}.*{"name":"FlowToken"}.*\]`, + expected: `\[.*"name":"FUSD".*"name":"FlowToken".*\]`, status: http.StatusOK, }, }