Skip to content

Commit 00df1f1

Browse files
feat: implement wallet deletion functionality (#89)
1 parent b514f07 commit 00df1f1

5 files changed

Lines changed: 125 additions & 1 deletion

File tree

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ require (
1111
github.com/hashicorp/vault/api v1.20.0
1212
github.com/oapi-codegen/runtime v1.1.2
1313
github.com/smartcontractkit/chain-selectors v1.0.82
14-
github.com/smartcontractkit/crec-api-go v0.3.8-0.20260113233243-298d281b2ab6
14+
github.com/smartcontractkit/crec-api-go v0.3.8-0.20260115174532-3d075a87c5fb
1515
github.com/stretchr/testify v1.10.0
1616
github.com/testcontainers/testcontainers-go v0.38.0
1717
github.com/testcontainers/testcontainers-go/modules/vault v0.38.0

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,8 @@ github.com/smartcontractkit/crec-api-go v0.3.8-0.20260113152121-3ff31eb7e4ce h1:
453453
github.com/smartcontractkit/crec-api-go v0.3.8-0.20260113152121-3ff31eb7e4ce/go.mod h1:TuDZiMoStNQBv3HYA5pqpwPyecbMh8p5momO4b1A9Eg=
454454
github.com/smartcontractkit/crec-api-go v0.3.8-0.20260113233243-298d281b2ab6 h1:GjHgFIYaeuifJJpchd+ytTCYnKIeQseubxn/BZ5sLmo=
455455
github.com/smartcontractkit/crec-api-go v0.3.8-0.20260113233243-298d281b2ab6/go.mod h1:TuDZiMoStNQBv3HYA5pqpwPyecbMh8p5momO4b1A9Eg=
456+
github.com/smartcontractkit/crec-api-go v0.3.8-0.20260115174532-3d075a87c5fb h1:jqwuLPkCM26GsXrh6pV/pZYUvVEg45xFQ/+L4gWw0mQ=
457+
github.com/smartcontractkit/crec-api-go v0.3.8-0.20260115174532-3d075a87c5fb/go.mod h1:TuDZiMoStNQBv3HYA5pqpwPyecbMh8p5momO4b1A9Eg=
456458
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
457459
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
458460
github.com/spf13/afero v1.12.0 h1:UcOPyRBYczmFn6yvphxkn9ZEOY65cpwGKb5mL36mrqs=

mocks/server/server.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,21 @@ func (s *MockServer) PatchWalletsWalletId(w http.ResponseWriter, r *http.Request
621621
http.Error(w, "wallet not found", http.StatusNotFound)
622622
}
623623

624+
func (s *MockServer) DeleteWalletsWalletId(w http.ResponseWriter, r *http.Request, walletId openapiTypes.UUID) {
625+
s.mu.Lock()
626+
defer s.mu.Unlock()
627+
628+
// Find and remove the wallet
629+
for i, wallet := range s.wallets {
630+
if wallet.WalletId == walletId {
631+
s.wallets = append(s.wallets[:i], s.wallets[i+1:]...)
632+
w.WriteHeader(http.StatusOK)
633+
return
634+
}
635+
}
636+
http.Error(w, "wallet not found", http.StatusNotFound)
637+
}
638+
624639
// ============================================================================
625640
// HELPER METHODS (INTERNAL)
626641
// ============================================================================

wallets/wallets.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ var (
4747
ErrGetWallet = errors.New("failed to get wallet")
4848
ErrListWallets = errors.New("failed to list wallets")
4949
ErrUpdateWallet = errors.New("failed to update wallet")
50+
ErrDeleteWallet = errors.New("failed to delete wallet")
5051

5152
// Response errors
5253
ErrUnexpectedStatusCode = errors.New("unexpected status code")
@@ -390,3 +391,40 @@ func (c *Client) Update(ctx context.Context, walletID uuid.UUID, input UpdateInp
390391

391392
return nil
392393
}
394+
395+
// Delete deletes a wallet.
396+
//
397+
// Parameters:
398+
// - ctx: The context for the request.
399+
// - walletID: The UUID of the wallet to delete.
400+
//
401+
// Returns an error if the operation fails or the wallet is not found.
402+
func (c *Client) Delete(ctx context.Context, walletID uuid.UUID) error {
403+
c.logger.Debug("Deleting wallet", "wallet_id", walletID.String())
404+
405+
if walletID == uuid.Nil {
406+
return ErrWalletIDRequired
407+
}
408+
409+
resp, err := c.apiClient.DeleteWalletsWalletIdWithResponse(ctx, walletID)
410+
if err != nil {
411+
c.logger.Error("Failed to delete wallet", "error", err)
412+
return fmt.Errorf("%w: %w", ErrDeleteWallet, err)
413+
}
414+
415+
if resp.StatusCode() == 404 {
416+
c.logger.Warn("Wallet not found", "wallet_id", walletID.String())
417+
return fmt.Errorf("%w: wallet ID %s", ErrWalletNotFound, walletID.String())
418+
}
419+
420+
if resp.StatusCode() != 200 {
421+
c.logger.Error("Unexpected status code when deleting wallet",
422+
"status_code", resp.StatusCode(),
423+
"body", string(resp.Body))
424+
return fmt.Errorf("%w: %w (status code %d)", ErrDeleteWallet, ErrUnexpectedStatusCode, resp.StatusCode())
425+
}
426+
427+
c.logger.Info("Wallet deleted successfully", "wallet_id", walletID.String())
428+
429+
return nil
430+
}

wallets/wallets_test.go

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -871,3 +871,72 @@ func TestClient_Update(t *testing.T) {
871871
assert.True(t, errors.Is(err, ErrUpdateWallet))
872872
})
873873
}
874+
875+
func TestClient_Delete(t *testing.T) {
876+
t.Run("Success", func(t *testing.T) {
877+
walletID := uuid.New()
878+
879+
handler := func(w http.ResponseWriter, r *http.Request) {
880+
assert.Equal(t, "/wallets/"+walletID.String(), r.URL.Path)
881+
assert.Equal(t, "DELETE", r.Method)
882+
assert.Equal(t, "test-api-key", r.Header.Get("Api-Key"))
883+
884+
w.WriteHeader(http.StatusOK)
885+
}
886+
887+
client, server := setupTestClient(t, handler)
888+
defer server.Close()
889+
890+
err := client.Delete(context.Background(), walletID)
891+
892+
require.NoError(t, err)
893+
})
894+
895+
t.Run("NilWalletID", func(t *testing.T) {
896+
client, server := setupTestClient(t, nil)
897+
defer server.Close()
898+
899+
err := client.Delete(context.Background(), uuid.Nil)
900+
901+
require.Error(t, err)
902+
assert.True(t, errors.Is(err, ErrWalletIDRequired))
903+
})
904+
905+
t.Run("NotFound", func(t *testing.T) {
906+
walletID := uuid.New()
907+
908+
handler := func(w http.ResponseWriter, r *http.Request) {
909+
w.Header().Set("Content-Type", "application/json")
910+
w.WriteHeader(http.StatusNotFound)
911+
json.NewEncoder(w).Encode(map[string]string{
912+
"message": "Wallet not found",
913+
"type": "Not found",
914+
})
915+
}
916+
917+
client, server := setupTestClient(t, handler)
918+
defer server.Close()
919+
920+
err := client.Delete(context.Background(), walletID)
921+
922+
require.Error(t, err)
923+
assert.True(t, errors.Is(err, ErrWalletNotFound))
924+
})
925+
926+
t.Run("UnexpectedStatusCode", func(t *testing.T) {
927+
walletID := uuid.New()
928+
929+
handler := func(w http.ResponseWriter, r *http.Request) {
930+
w.WriteHeader(http.StatusInternalServerError)
931+
}
932+
933+
client, server := setupTestClient(t, handler)
934+
defer server.Close()
935+
936+
err := client.Delete(context.Background(), walletID)
937+
938+
require.Error(t, err)
939+
assert.True(t, errors.Is(err, ErrDeleteWallet))
940+
assert.True(t, errors.Is(err, ErrUnexpectedStatusCode))
941+
})
942+
}

0 commit comments

Comments
 (0)