Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
root = true

[*]
charset = utf-8
insert_final_newline = true
trim_trailing_whitespace = true

[*.{cs,csx}]
indent_style = space
indent_size = 4

[*.{json,yml,yaml,md}]
indent_size = 2
2 changes: 2 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Default owners for the whole repository.
* @coinbase/core-dotnet-write @coinbase/core-dotnet-admin
20 changes: 20 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
## Description

<!-- Describe the change and why it's being made. Include any relevant context, motivation, or background. -->

## Type of Change

<!-- Check all that apply. -->

- [ ] Bug fix
- [ ] New feature
- [ ] Breaking change
- [ ] Dependency update
- [ ] Refactor / cleanup
- [ ] Other (describe below)

## Checklist

- [ ] Tests included / updated
- [ ] Changelog updated
- [ ] Version bump if needed
26 changes: 26 additions & 0 deletions .github/workflows/format.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: format
on: [pull_request]

permissions:
contents: read

jobs:
format:
runs-on: ubuntu-latest

steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@002fdce3c6a235733a90a27c80493a3241e56863 # v2.12.1
with:
egress-policy: audit

- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

- name: Setup .NET
uses: actions/setup-dotnet@67a3573c9a986a3f9c594539f4ab511d57bb3ce9 # v4.3.1
with:
dotnet-version: "10.0.x"

- name: Verify formatting
run: dotnet format core-dotnet.sln --verify-no-changes
26 changes: 26 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: lint
on: [pull_request]

permissions:
contents: read

jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@002fdce3c6a235733a90a27c80493a3241e56863 # v2.12.1
with:
egress-policy: audit

- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

- name: Setup .NET
uses: actions/setup-dotnet@67a3573c9a986a3f9c594539f4ab511d57bb3ce9 # v4.3.1
with:
dotnet-version: "10.0.x"

- name: Build
run: dotnet build core-dotnet.sln -c Release
21 changes: 21 additions & 0 deletions .github/workflows/salus-scan.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Salus Security Scan
on: [pull_request, push]

permissions:
contents: read

jobs:
scan:
runs-on: ubuntu-latest
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@002fdce3c6a235733a90a27c80493a3241e56863 # v2.12.1
with:
egress-policy: audit

- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Salus Scan
id: salus_scan
uses: federacy/scan-action@4303a88eba7fe183a9a2d9ca9a13af11203cb835 # 0.1.5
with:
active_scanners: "\n - PatternSearch\n - Semgrep\n - Trufflehog"
29 changes: 29 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: test
on: [pull_request]

permissions:
contents: read

jobs:
test:
runs-on: ubuntu-latest

steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@002fdce3c6a235733a90a27c80493a3241e56863 # v2.12.1
with:
egress-policy: audit

- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

- name: Setup .NET
uses: actions/setup-dotnet@67a3573c9a986a3f9c594539f4ab511d57bb3ce9 # v4.3.1
with:
dotnet-version: "10.0.x"

- name: Build
run: dotnet build core-dotnet.sln -c Release

- name: Test
run: dotnet test core-dotnet.sln -c Release --no-build
25 changes: 25 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,31 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.2.0] - 2026-06-01

### Changed

- Moved the canonical repository to [coinbase/core-dotnet](https://github.com/coinbase/core-dotnet).
- Added GitHub Actions for format, build (lint), and tests.
- CI uses the .NET 10 SDK; the package continues to target `net8.0`.
- Added SECURITY.md, CONTRIBUTING.md, and pull request template aligned with other Coinbase SDKs.

### Notes

- No intentional API breaking changes; minor bump signals repository migration.
- Equivalent to 0.1.1 on coinbase-samples aside from repository and tooling.

## [0.1.1] - 2026-06-01

### Changed

- Marked coinbase-samples/core-dotnet as deprecated in the README.
- Documented migration to coinbase/core-dotnet and CoinbaseSdk.Core 0.2.0+.

### Notes

- No intentional API changes.

## [0.1.0] - 2025-11-24

### Added
Expand Down
5 changes: 5 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Contributing to core-dotnet

At this time we are not accepting Pull Requests. Therefore, if you have an idea for a new feature or have found a non-security bug, please open an issue. We will examine the issue and determine if it is a good fit for the project and if it is, we will provide the change internally and release it to the public.

If you have found a security bug, please refer to the [security policy](SECURITY.md) for how to report it.
72 changes: 72 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
.PHONY: help check-dotnet lint format format-fix build test ci tools setup

SLN := core-dotnet.sln
CONFIG ?= Release

# Prefer the Microsoft dotnet host on macOS when it includes the net8.0 runtime.
DOTNET_DIR := $(firstword $(wildcard /usr/local/share/dotnet) $(HOME)/.dotnet)
ifneq ($(DOTNET_DIR),)
export PATH := $(DOTNET_DIR):$(PATH)
endif
DOTNET ?= dotnet

# Match .github/workflows/*.yml (SDK 10 builds net8.0; tests need the net8.0 runtime).
DOTNET_SDK_CHANNEL ?= 10.0
DOTNET_RUNTIME_CHANNEL ?= 8.0
DOTNET_INSTALL_DIR ?= $(HOME)/.dotnet

.DEFAULT_GOAL := help

help:
@echo "Usage: make <target>"
@echo ""
@echo "Targets:"
@echo " lint Build with StyleCop (same as CI lint job)"
@echo " format Verify formatting (dotnet format --verify-no-changes)"
@echo " format-fix Apply formatting fixes locally"
@echo " build dotnet build ($(CONFIG))"
@echo " test Build and run tests"
@echo " ci format, lint, and test"
@echo " tools Install .NET SDK $(DOTNET_SDK_CHANNEL) and runtime $(DOTNET_RUNTIME_CHANNEL)"
@echo " setup Alias for tools"
@echo ""
@echo "First-time setup: make tools"
@echo "Then add to your shell: export PATH=\"$(DOTNET_INSTALL_DIR):\$$PATH\""

check-dotnet:
@command -v $(DOTNET) >/dev/null 2>&1 || { \
echo "$(DOTNET) not found; install with: make tools"; \
exit 1; \
}
@$(DOTNET) --list-runtimes 2>/dev/null | grep -q 'Microsoft.NETCore.App 8\.' || { \
echo "Microsoft.NETCore.App 8.x runtime not found (required for net8.0 tests)."; \
echo "Install with: make tools"; \
echo "On macOS with Homebrew dotnet 10 only, use: export PATH=\"/usr/local/share/dotnet:\$$PATH\""; \
exit 1; \
}

lint: build

format: check-dotnet
$(DOTNET) format $(SLN) --verify-no-changes

format-fix: check-dotnet
$(DOTNET) format $(SLN)

build: check-dotnet
$(DOTNET) build $(SLN) -c $(CONFIG)

test: build
$(DOTNET) test $(SLN) -c $(CONFIG) --no-build

ci: format lint test

tools setup:
@echo "Installing .NET SDK $(DOTNET_SDK_CHANNEL) and runtime $(DOTNET_RUNTIME_CHANNEL) to $(DOTNET_INSTALL_DIR)..."
@curl -sSL https://dot.net/v1/dotnet-install.sh -o /tmp/dotnet-install.sh
@chmod +x /tmp/dotnet-install.sh
@/tmp/dotnet-install.sh --channel $(DOTNET_SDK_CHANNEL) --install-dir $(DOTNET_INSTALL_DIR)
@/tmp/dotnet-install.sh --runtime dotnet --channel $(DOTNET_RUNTIME_CHANNEL) --install-dir $(DOTNET_INSTALL_DIR)
@echo ""
@echo "Done. Add to ~/.zshrc or ~/.bashrc:"
@echo " export PATH=\"$(DOTNET_INSTALL_DIR):\$$PATH\""
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Coinbase .NET Core Library

The canonical source repository is **[coinbase/core-dotnet](https://github.com/coinbase/core-dotnet)**. The former [coinbase-samples/core-dotnet](https://github.com/coinbase-samples/core-dotnet) repository is deprecated.

## Overview

The **Coinbase .NET Core Library** (`CoinbaseSdk.Core`) is the foundational building block for Coinbase .NET SDKs. It provides a standardized, robust, and thread-safe infrastructure for building API clients, handling authentication, HTTP communication, and serialization.
Expand Down Expand Up @@ -74,6 +76,17 @@ var client = new MyCoinbaseClient(credentials, httpClient: httpClient);
dotnet add package CoinbaseSdk.Core
```

## Development

```bash
git clone https://github.com/coinbase/core-dotnet.git
cd core-dotnet
make tools # first time: install .NET SDK 10 and net8.0 runtime
make ci # format, lint (build), and test
```

Individual targets: `make format`, `make lint`, `make build`, `make test`. Use `make format-fix` to apply formatting locally.

## License

This project is licensed under the [Apache License, Version 2.0](LICENSE).
9 changes: 9 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Security Policy for core-dotnet

## Reporting a Security Bug

If you think you have discovered a security issue within any part of this codebase, please let us know by providing a description of the flaw and any related information (e.g. steps to reproduce, version, etc.). There are two ways to report a security bug:

- The first way is to submit a report to [HackerOne](https://hackerone.com/coinbase). This way of submitting a report will make you eligible for a bounty but will require you to follow a certain process, including possible limitations on when the results can be publicly disclosed.

- If you do not wish to submit via HackerOne, then you can send us a direct email at sa@coinbase.com. This way of submitting a report will not make you eligible for a bounty but will allow you to responsibly disclose on your terms.
4 changes: 2 additions & 2 deletions src/CoinbaseSdk/Core/CoinbaseSdk.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

<PropertyGroup>
<Description>CoinbaseSdk.Core is the core library for .NET Coinbase SDKs.</Description>
<Version>0.1.0</Version>
<Version>0.2.0</Version>
<LangVersion>12</LangVersion>
<Authors>Coinbase</Authors>
<TargetFrameworks>net8.0</TargetFrameworks>
<PackageTags>coinbase</PackageTags>
<PackageProjectUrl>https://github.com/coinbase-samples/core-dotnet</PackageProjectUrl>
<PackageProjectUrl>https://github.com/coinbase/core-dotnet</PackageProjectUrl>
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<SignAssembly>True</SignAssembly>
Expand Down
2 changes: 1 addition & 1 deletion src/CoinbaseSdk/Core/http/CallOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,4 @@ internal bool HasRetryConfiguration()
return this.MaxRetries > 0;
}
}
}
}
2 changes: 1 addition & 1 deletion src/CoinbaseSdk/Core/serialization/IJsonUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ public interface IJsonUtility

T Deserialize<T>(string json);
}
}
}
4 changes: 2 additions & 2 deletions src/CoinbaseSdk/Core/serialization/JsonUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ namespace CoinbaseSdk.Core.Serialization

public class JsonUtility : IJsonUtility
{
private static readonly object DefaultOptionsLock = new ();
private static readonly object DefaultOptionsLock = new object();
private static JsonSerializerOptions? defaultOptions;

private readonly JsonSerializerOptions options;
Expand Down Expand Up @@ -91,7 +91,7 @@ private static JsonSerializerOptions EnsureDefaultOptions()

private static JsonSerializerOptions BuildDefaultOptions()
{
JsonSerializerOptions baseOptions = new (JsonSerializerDefaults.Web)
JsonSerializerOptions baseOptions = new JsonSerializerOptions(JsonSerializerDefaults.Web)
{
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
PropertyNameCaseInsensitive = true,
Expand Down
6 changes: 3 additions & 3 deletions tests/CoinbaseSdk.Core.Tests/Client/CoinbaseClientTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ public class TestCoinbaseClient : CoinbaseClient
public TestCoinbaseClient(
CoinbaseCredentials credentials,
string apiBasePath,
IJsonUtility jsonUtility = null,
IHttpClient httpClient = null)
IJsonUtility? jsonUtility = null,
IHttpClient? httpClient = null)
: base(credentials, apiBasePath, jsonUtility, httpClient)
{
}
Expand All @@ -58,7 +58,7 @@ public CoinbaseClientTests()
[Fact]
public void Constructor_NullCredentials_ThrowsArgumentException()
{
Assert.Throws<ArgumentException>(() => new TestCoinbaseClient(null, _apiBasePath));
Assert.Throws<ArgumentException>(() => new TestCoinbaseClient(null!, _apiBasePath));
}

[Fact]
Expand Down
Loading