⚠️ This demo is a work in progress.
This is a demonstration of a RESTful API that implements a simple custodial wallet service for the Flow blockchain.
- Single admin account (hot wallet)
- Create user accounts (using admin account)
- Send an arbitrary transaction from the admin account
- Send an arbitrary transaction from a user account
- Send fungible token withdrawals from admin account (FLOW, FUSD)
- Detect fungible token deposits to admin account (FLOW, FUSD)
- Send fungible token withdrawals from a user account (FLOW, FUSD)
- Detect fungible token deposits to a user account (FLOW, FUSD)
- View the fungible token balance of the admin account
- View the fungible token balance of a user account
- Set up admin account with non-fungible token collections (
NFT.Collection
) - Send non-fungible token withdrawals from admin account
- Detect non-fungible token deposits to admin account
- Set up a user account with non-fungible token collections (
NFT.Collection
) - Send non-fungible token withdrawals from a user account
- Detect non-fungible token deposits to a user account
- View the non-fungible tokens owned by the admin account
- View the non-fungible tokens owned by a user account
This local development environment uses the Flow Emulator to simulate the real Flow network.
First, install the Flow CLI.
npm install
cp .env.example .env
Use Docker Compose to launch Postgres and the Flow Emulator:
npm run docker-local-network
npm run dev
To deploy this API as a Docker container in your infrastructure, either build from source or use the pre-built image:
docker pull gcr.io/flow-container-registry/flow-wallet-api-demo:latest
The Docker Compose sample configurations in this repository show how to configure this application when running as a Docker container.
This example shows how to connect the Docker container to an instance of the Flow Emulator.
Configuration: docker-compose.emulator.yml
cp .env.emulator.example .env
docker-compose -f docker-compose.emulator.yml up
Once the emulator is running, you will need to deploy the FUSD contract:
npm run dev-deploy-contracts
This example shows how to connect the Docker container to Flow Testnet.
First you'll need a Testnet account. Here's how to make one:
Generate a new key pair with the Flow CLI:
flow keys generate
Go to the Flow Testnet Faucet to create a new account. Use the public key from the previous step.
After your account has been created, save the address and private key in the .env
file:
cp .env.testnet.example .env
# Replace these values with your own!
FLOW_ADDRESS=0xabcdef12345689
FLOW_PRIVATE_KEY=aaaaaa...aaaaaa
Configuration: docker-compose.testnet.yml
docker-compose -f docker-compose.testnet.yml up
GET /v1/accounts
Example
curl --request GET \
--url http://localhost:3000/v1/accounts
[
{
"address": "0xf8d6e0586b0a20c7"
},
{
"address": "0xe467b9dd11fa00df"
}
]
GET /v1/accounts/{address}
Parameters
address
: The address of the account (e.g. "0xf8d6e0586b0a20c7")
Example
curl --request GET \
--url http://localhost:3000/v1/accounts/0xf8d6e0586b0a20c7
{
"address": "0xf8d6e0586b0a20c7"
}
POST /v1/accounts
Example
curl --request POST \
--url http://localhost:3000/v1/accounts
{
"address": "0xe467b9dd11fa00df"
}
⚠️ Not yet implemented
POST /v1/accounts/{address}/transactions
Parameters
address
: The address of the account (e.g. "0xf8d6e0586b0a20c7")
Body (JSON)
code
: The Cadence code to execute in the transaction- The code must always specify exactly one authorizer (i.e.
prepare(auth: AuthAccount)
)
- The code must always specify exactly one authorizer (i.e.
Example
curl --request POST \
--url http://localhost:3000/v1/accounts/0xf8d6e0586b0a20c7/transactions \
--header 'Content-Type: application/json' \
--data '{ "code": "transaction { prepare(auth: AuthAccount) { log(\"Hello, World!\") } }" }'
{
"transactionId": "18647b584a03345f3b2d2c4d9ab2c4179ae1b124a7f62ef9f33910e5ca8b353c",
"error": null,
}
Supported tokens:
FLOW
FUSD
GET /v1/accounts/{address}/fungible-tokens
Parameters
address
: The address of the account (e.g. "0xf8d6e0586b0a20c7")
Example
curl --request GET \
--url http://localhost:3000/v1/accounts/0xf8d6e0586b0a20c7/fungible-tokens
[
{
"name": "flow"
},
{
"name": "fusd"
}
]
GET /v1/accounts/{address}/fungible-tokens/{tokenName}
Parameters
address
: The address of the account (e.g. "0xf8d6e0586b0a20c7")tokenName
: The name of the fungible token (e.g. "flow")
Example
curl --request GET \
--url http://localhost:3000/v1/accounts/0xf8d6e0586b0a20c7/fungible-tokens/flow
{
"name": "flow",
"balance": "42.0"
}
⚠️ Not yet implemented
GET /v1/accounts/{address}/fungible-tokens/{tokenName}/withdrawals
Parameters
address
: The address of the account (e.g. "0xf8d6e0586b0a20c7")tokenName
: The name of the fungible token (e.g. "flow")
⚠️ Not yet implemented
GET /v1/accounts/{address}/fungible-tokens/{tokenName}/withdrawals/{transactionId}
Parameters
address
: The address of the account (e.g. "0xf8d6e0586b0a20c7")tokenName
: The name of the fungible token (e.g. "flow")transactionId
: The Flow transaction ID for the withdrawal
POST /v1/accounts/{address}/fungible-tokens/{tokenName}/withdrawals
Parameters
address
: The address of the account (e.g. "0xf8d6e0586b0a20c7")tokenName
: The name of the fungible token (e.g. "flow")
Body (JSON)
amount
: The number of tokens to transfer (e.g. "123.456")- Must be a fixed-point number with a maximum of 8 decimal places
recipient
: The Flow address of the recipient (e.g. "0xf8d6e0586b0a20c7")
Example
curl --request POST \
--url http://localhost:3000/v1/accounts/0xf8d6e0586b0a20c7/fungible-tokens/fusd/withdrawls \
--header 'Content-Type: application/json' \
--data '{ "recipient": "0xe467b9dd11fa00df", "amount": "123.456" }'
{
"transactionId": "18647b584a03345f3b2d2c4d9ab2c4179ae1b124a7f62ef9f33910e5ca8b353c",
"recipient": "0xe467b9dd11fa00df",
"amount": "123.456"
}
⚠️ Not yet implemented
⚠️ Not yet implemented
GET /v1/accounts/{address}/non-fungible-tokens
Parameters
address
: The address of the account (e.g. "0xf8d6e0586b0a20c7")
Example
curl --request GET \
--url http://localhost:3000/v1/accounts/0xf8d6e0586b0a20c7/non-fungible-tokens
⚠️ Not yet implemented
GET /v1/accounts/{address}/non-fungible-tokens/{tokenName}
Parameters
address
: The address of the account (e.g. "0xf8d6e0586b0a20c7")tokenName
: The name of the non-fungible token (e.g. "nba-top-shot-moment")
⚠️ Not yet implemented
GET /v1/accounts/{address}/non-fungible-tokens/{tokenName}/withdrawals
Parameters
address
: The address of the account (e.g. "0xf8d6e0586b0a20c7")tokenName
: The name of the non-fungible token (e.g. "nba-top-shot-moment")
⚠️ Not yet implemented
GET /v1/accounts/{address}/non-fungible-tokens/{tokenName}/withdrawals/{transactionId}
Parameters
address
: The address of the account (e.g. "0xf8d6e0586b0a20c7")tokenName
: The name of the non-fungible token (e.g. "nba-top-shot-moment")transactionId
: The Flow transaction ID for the withdrawal
⚠️ Not yet implemented
POST /v1/accounts/{address}/non-fungible-tokens/{tokenName}/withdrawals
Parameters
address
: The address of the account (e.g. "0xf8d6e0586b0a20c7")tokenName
: The name of the non-fungible token (e.g. "nba-top-shot-moment")
Body (JSON)
recipient
: The Flow address of the recipient (e.g. "0xf8d6e0586b0a20c7")