-
Notifications
You must be signed in to change notification settings - Fork 1
Add coin ticker available check #403
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3619,6 +3619,54 @@ paths: | |
'500': | ||
description: Server error | ||
content: {} | ||
/coins/ticker/{ticker}/available: | ||
get: | ||
tags: | ||
- coins | ||
operationId: Check Coin Ticker Availability | ||
description: 'Checks if a coin ticker is available for use' | ||
parameters: | ||
- name: ticker | ||
in: path | ||
description: The ticker to check for availability | ||
required: true | ||
schema: | ||
type: string | ||
example: $NEWCOIN | ||
responses: | ||
'200': | ||
description: Ticker is taken (not available) | ||
content: | ||
application/json: | ||
schema: | ||
type: object | ||
properties: | ||
available: | ||
type: boolean | ||
example: false | ||
'404': | ||
description: Ticker is available | ||
content: | ||
application/json: | ||
schema: | ||
type: object | ||
properties: | ||
available: | ||
type: boolean | ||
example: true | ||
'400': | ||
description: Bad request - ticker parameter is required | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: true now but maybe too specific generally for a 400, which I usually treat as "something was invalid about your request; more details in the response message" |
||
content: | ||
application/json: | ||
schema: | ||
type: object | ||
properties: | ||
error: | ||
type: string | ||
example: "ticker parameter is required" | ||
'500': | ||
description: Server error | ||
content: {} | ||
/coins/{mint}/insights: | ||
get: | ||
tags: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -188,3 +188,44 @@ func (app *ApiServer) v1CoinByTicker(c *fiber.Ctx) error { | |
"data": coinRow, | ||
}) | ||
} | ||
|
||
func (app *ApiServer) v1CoinTickerAvailable(c *fiber.Ctx) error { | ||
ticker := c.Params("ticker") | ||
if ticker == "" { | ||
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ | ||
"error": "ticker parameter is required", | ||
}) | ||
} | ||
|
||
// Check if ticker exists in the database | ||
sql := ` | ||
SELECT COUNT(*) | ||
FROM artist_coins | ||
WHERE ticker = @ticker | ||
` | ||
|
||
rows, err := app.pool.Query(c.Context(), sql, pgx.NamedArgs{ | ||
"ticker": ticker, | ||
}) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
var count int | ||
err = rows.Scan(&count) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// If count is 0, ticker is available (return 404 like handle validation) | ||
if count == 0 { | ||
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{ | ||
"available": true, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The pattern of this endpoint feels a little wonky (maybe from trying to match the handle check behavior?) I would suggest either:
Second concern: Curious if client handles this correctly because SDK definitely has special logic for requests that return >= 400 status codes. |
||
}) | ||
} | ||
|
||
// If count > 0, ticker is taken (return 200 with available: false) | ||
return c.JSON(fiber.Map{ | ||
"available": false, | ||
}) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -69,3 +69,52 @@ func TestV1Coin(t *testing.T) { | |
assert.Contains(t, string(body), "no rows") | ||
} | ||
} | ||
|
||
func TestV1CoinTickerAvailable(t *testing.T) { | ||
app := emptyTestApp(t) | ||
|
||
fixtures := database.FixtureMap{ | ||
"artist_coins": { | ||
{ | ||
"ticker": "$AUDIO", | ||
"decimals": 8, | ||
"user_id": 1, | ||
"mint": "9LzCMqDgTKYz9Drzqnpgee3SGa89up3a247ypMj2xrqM", | ||
"name": "Audius", | ||
"created_at": time.Now().Add(-time.Second), | ||
}, | ||
}, | ||
} | ||
|
||
database.Seed(app.pool.Replicas[0], fixtures) | ||
|
||
// Test ticker that exists (should return 200 with available: false) | ||
{ | ||
status, body := testGet(t, app, "/v1/coins/ticker/$AUDIO/available") | ||
assert.Equal(t, 200, status) | ||
|
||
jsonAssert(t, body, map[string]any{ | ||
"available": false, | ||
}) | ||
} | ||
|
||
// Test ticker that doesn't exist (should return 404 with available: true) | ||
{ | ||
status, body := testGet(t, app, "/v1/coins/ticker/$NONEXISTENT/available") | ||
assert.Equal(t, 404, status) | ||
|
||
jsonAssert(t, body, map[string]any{ | ||
"available": true, | ||
}) | ||
} | ||
|
||
// Test with empty ticker parameter (should return 400) | ||
{ | ||
status, body := testGet(t, app, "/v1/coins/ticker//available") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am not certain route matching works like this? Worth double checking that it actually calls the handler for the new endpoint if it can't match a route parameter for the ticker id |
||
assert.Equal(t, 400, status) | ||
|
||
jsonAssert(t, body, map[string]any{ | ||
"error": "ticker parameter is required", | ||
}) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add some min/max length props to this?