diff --git a/paper-api/src/main/java/io/papermc/paper/datacomponent/item/BlocksAttacks.java b/paper-api/src/main/java/io/papermc/paper/datacomponent/item/BlocksAttacks.java
index bf53d0e0b0..d7372673ac 100644
--- a/paper-api/src/main/java/io/papermc/paper/datacomponent/item/BlocksAttacks.java
+++ b/paper-api/src/main/java/io/papermc/paper/datacomponent/item/BlocksAttacks.java
@@ -1,6 +1,8 @@
 package io.papermc.paper.datacomponent.item;
 
 import io.papermc.paper.datacomponent.DataComponentBuilder;
+import io.papermc.paper.datacomponent.item.blocksattacks.DamageReduction;
+import io.papermc.paper.datacomponent.item.blocksattacks.ItemDamageFunction;
 import io.papermc.paper.registry.tag.TagKey;
 import net.kyori.adventure.key.Key;
 import org.bukkit.damage.DamageType;
@@ -8,8 +10,13 @@ import org.jetbrains.annotations.ApiStatus;
 import org.jetbrains.annotations.Contract;
 import org.jspecify.annotations.NullMarked;
 import org.jspecify.annotations.Nullable;
+import java.util.List;
 
-// TODO
+/**
+ * Holds block attacks to the holding player like Shield.
+ *
+ * @see io.papermc.paper.datacomponent.DataComponentTypes#BLOCKS_ATTACKS
+ */
 @NullMarked
 @ApiStatus.Experimental
 @ApiStatus.NonExtendable
@@ -20,19 +27,59 @@ public interface BlocksAttacks {
         return ItemComponentTypesBridge.bridge().blocksAttacks();
     }
 
+    /**
+     * Gets the amount of time (in seconds) that use must be held before successfully blocking attacks.
+     *
+     * @return the delay in seconds
+     */
     float blockDelaySeconds();
 
+    /**
+     * Gets the multiplier applied to the cooldown time for the item when attacked by a disabling attack (the multiplier for {@link Weapon#disableBlockingForSeconds()}).
+     * <br>
+     * If set to 0, this item can never be disabled by attacks.
+     *
+     * @return the multiplier for the cooldown time
+     */
     float disableCooldownScale();
 
-    //List<DamageReduction> damageReductions();
+    /**
+     * Gets a list of {@link DamageReduction} of how much damage should be blocked in a given attack.
+     *
+     * @return a list of damage reductions
+     */
+    List<DamageReduction> damageReductions();
 
-    //ItemDamageFunction itemDamage();
+    /**
+     * Gets how much damage should be applied to the item from a given attack.
+     *
+     * @return the damage function
+     */
+    ItemDamageFunction itemDamage();
 
-    @Nullable TagKey<DamageType> bypassedBy();
+    /**
+     * Gets the DamageType that can bypass the blocking.
+     *
+     * @return a damage type tag key, or null if there is no such tag key
+     */
+    @Nullable
+    TagKey<DamageType> bypassedBy();
 
-    @Nullable Key blockSound();
+    /**
+     * Gets the key sound to play when an attack is successfully blocked.
+     *
+     * @return a key of the sound
+     */
+    @Nullable
+    Key blockSound();
 
-    @Nullable Key disableSound();
+    /**
+     * Gets the key sound to play when the item goes on its disabled cooldown due to an attack.
+     *
+     * @return a key of the sound
+     */
+    @Nullable
+    Key disableSound();
 
     /**
      * Builder for {@link BlocksAttacks}.
@@ -47,14 +94,14 @@ public interface BlocksAttacks {
         @Contract(value = "_ -> this", mutates = "this")
         Builder disableCooldownScale(float scale);
 
-        //@Contract(value = "_ -> this", mutates = "this")
-        //Builder addDamageReduction(DamageReduction reduction);
+        @Contract(value = "_ -> this", mutates = "this")
+        Builder addDamageReduction(DamageReduction reduction);
 
-        //@Contract(value = "_ -> this", mutates = "this")
-        //Builder damageReductions(List<DamageReduction> reductions);
+        @Contract(value = "_ -> this", mutates = "this")
+        Builder damageReductions(List<DamageReduction> reductions);
 
-        //@Contract(value = "_ -> this", mutates = "this")
-        //Builder itemDamage(ItemDamageFunction function);
+        @Contract(value = "_ -> this", mutates = "this")
+        Builder itemDamage(ItemDamageFunction function);
 
         @Contract(value = "_ -> this", mutates = "this")
         Builder bypassedBy(@Nullable TagKey<DamageType> bypassedBy);
diff --git a/paper-api/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/BlocksAttacksBridge.java b/paper-api/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/BlocksAttacksBridge.java
new file mode 100644
index 0000000000..aafc085c91
--- /dev/null
+++ b/paper-api/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/BlocksAttacksBridge.java
@@ -0,0 +1,21 @@
+package io.papermc.paper.datacomponent.item.blocksattacks;
+
+import org.jetbrains.annotations.ApiStatus;
+import org.jspecify.annotations.NullMarked;
+import java.util.Optional;
+import java.util.ServiceLoader;
+
+@NullMarked
+@ApiStatus.Internal
+interface BlocksAttacksBridge {
+
+    Optional<BlocksAttacksBridge> BRIDGE = ServiceLoader.load(BlocksAttacksBridge.class).findFirst();
+
+    static BlocksAttacksBridge bridge() {
+        return BRIDGE.orElseThrow();
+    }
+
+    DamageReduction.Builder blocksAttacksDamageReduction();
+
+    ItemDamageFunction.Builder blocksAttacksItemDamageFunction();
+}
diff --git a/paper-api/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/DamageReduction.java b/paper-api/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/DamageReduction.java
new file mode 100644
index 0000000000..fbf4a03782
--- /dev/null
+++ b/paper-api/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/DamageReduction.java
@@ -0,0 +1,78 @@
+package io.papermc.paper.datacomponent.item.blocksattacks;
+
+import io.papermc.paper.datacomponent.DataComponentBuilder;
+import io.papermc.paper.registry.set.RegistryKeySet;
+import org.bukkit.damage.DamageType;
+import org.checkerframework.checker.index.qual.Positive;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.Contract;
+import org.jspecify.annotations.NullMarked;
+import org.jspecify.annotations.Nullable;
+
+/**
+ * Hold how much damage should be blocked in a given attack.
+ *
+ * @see io.papermc.paper.datacomponent.DataComponentTypes#BLOCKS_ATTACKS
+ * @see io.papermc.paper.datacomponent.item.BlocksAttacks#damageReductions()
+ */
+@NullMarked
+@ApiStatus.Experimental
+@ApiStatus.NonExtendable
+public interface DamageReduction {
+
+    @Contract(value = "-> new", pure = true)
+    static DamageReduction.Builder damageReduction() {
+        return BlocksAttacksBridge.bridge().blocksAttacksDamageReduction();
+    }
+
+    /**
+     * The damage types to block.
+     *
+     * @return the set of damage type
+     */
+    @Nullable
+    RegistryKeySet<DamageType> type();
+
+    /**
+     * Get the maximum angle between the users facing direction and the direction of the incoming attack to be blocked.
+     *
+     * @return the angle
+     */
+    @Positive
+    float horizontalBlockingAngle();
+
+    /**
+     * Get the constant amount of damage to be blocked.
+     *
+     * @return the base
+     */
+    float base();
+
+    /**
+     * Get the fraction of the dealt damage to be blocked.
+     *
+     * @return the factor
+     */
+    float factor();
+
+    /**
+     * Builder for {@link DamageReduction}.
+     */
+    @ApiStatus.Experimental
+    @ApiStatus.NonExtendable
+    interface Builder extends DataComponentBuilder<DamageReduction> {
+
+        @Contract(value = "_ -> this", mutates = "this")
+        DamageReduction.Builder type(RegistryKeySet<DamageType> type);
+
+        @Contract(value = "_ -> this", mutates = "this")
+        DamageReduction.Builder horizontalBlockingAngle(@Positive float horizontalBlockingAngle);
+
+        @Contract(value = "_ -> this", mutates = "this")
+        DamageReduction.Builder base(float base);
+
+        @Contract(value = "_ -> this", mutates = "this")
+        DamageReduction.Builder factor(float factor);
+    }
+
+}
diff --git a/paper-api/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/ItemDamageFunction.java b/paper-api/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/ItemDamageFunction.java
new file mode 100644
index 0000000000..965b12fc66
--- /dev/null
+++ b/paper-api/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/ItemDamageFunction.java
@@ -0,0 +1,71 @@
+package io.papermc.paper.datacomponent.item.blocksattacks;
+
+import io.papermc.paper.datacomponent.DataComponentBuilder;
+import org.checkerframework.checker.index.qual.NonNegative;
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.Contract;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * Hold how much damage should be applied to the item from a given attack.
+ *
+ * @see io.papermc.paper.datacomponent.DataComponentTypes#BLOCKS_ATTACKS
+ * @see io.papermc.paper.datacomponent.item.BlocksAttacks#itemDamage()
+ */
+@NullMarked
+@ApiStatus.Experimental
+@ApiStatus.NonExtendable
+public interface ItemDamageFunction {
+
+    @Contract(value = "-> new", pure = true)
+    static ItemDamageFunction.Builder itemDamageFunction() {
+        return BlocksAttacksBridge.bridge().blocksAttacksItemDamageFunction();
+    }
+
+    /**
+     * Get the minimum amount of damage dealt by the attack before item damage is applied to the item.
+     *
+     * @return the threshold
+     */
+    @NonNegative
+    float threshold();
+
+    /**
+     * Get the constant amount of damage applied to the item, if threshold is passed.
+     *
+     * @return the base
+     */
+    float base();
+
+    /**
+     * Get the fraction of the dealt damage that should be applied to the item, if threshold is passed.
+     *
+     * @return the base
+     */
+    float factor();
+
+    /**
+     * Get the damage to apply for the item.
+     *
+     * @apiNote this doesn't apply enchantments like {@link org.bukkit.enchantments.Enchantment#UNBREAKING}}
+     * @return the damage to apply
+     */
+    int damageToApply(float damage);
+
+    /**
+     * Builder for {@link ItemDamageFunction}.
+     */
+    @ApiStatus.Experimental
+    @ApiStatus.NonExtendable
+    interface Builder extends DataComponentBuilder<ItemDamageFunction> {
+
+        @Contract(value = "_ -> this", mutates = "this")
+        ItemDamageFunction.Builder threshold(@NonNegative final float threshold);
+
+        @Contract(value = "_ -> this", mutates = "this")
+        ItemDamageFunction.Builder base(final float base);
+
+        @Contract(value = "_ -> this", mutates = "this")
+        ItemDamageFunction.Builder factor(final float factor);
+    }
+}
diff --git a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperBlocksAttacks.java b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperBlocksAttacks.java
index 1748518bbc..b4b9df9d85 100644
--- a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperBlocksAttacks.java
+++ b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperBlocksAttacks.java
@@ -2,8 +2,13 @@ package io.papermc.paper.datacomponent.item;
 
 import com.google.common.base.Preconditions;
 import io.papermc.paper.adventure.PaperAdventure;
+import io.papermc.paper.datacomponent.item.blocksattacks.DamageReduction;
+import io.papermc.paper.datacomponent.item.blocksattacks.ItemDamageFunction;
+import io.papermc.paper.datacomponent.item.blocksattacks.PaperDamageReduction;
+import io.papermc.paper.datacomponent.item.blocksattacks.PaperItemDamageFunction;
 import io.papermc.paper.registry.PaperRegistries;
 import io.papermc.paper.registry.tag.TagKey;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Optional;
 import net.kyori.adventure.key.Key;
@@ -30,6 +35,16 @@ public record PaperBlocksAttacks(
         return this.impl.disableCooldownScale();
     }
 
+    @Override
+    public List<DamageReduction> damageReductions() {
+        return this.impl.damageReductions().stream().map(PaperDamageReduction::new).map(paperDamageReduction -> ((DamageReduction) paperDamageReduction)).toList();
+    }
+
+    @Override
+    public ItemDamageFunction itemDamage() {
+        return new PaperItemDamageFunction(this.impl.itemDamage());
+    }
+
     @Override
     public @Nullable TagKey<DamageType> bypassedBy() {
         final Optional<TagKey<DamageType>> tagKey = this.impl.bypassedBy().map(PaperRegistries::fromNms);
@@ -50,8 +65,8 @@ public record PaperBlocksAttacks(
 
         private float blockDelaySeconds;
         private float disableCooldownScale = 1.0F;
-        //private List<DamageReduction> damageReductions = List.of();
-        //private ItemDamageFunction itemDamage = ItemDamageFunction.DEFAULT;
+        private List<DamageReduction> damageReductions = new ArrayList<>();
+        private ItemDamageFunction itemDamage = new PaperItemDamageFunction(net.minecraft.world.item.component.BlocksAttacks.ItemDamageFunction.DEFAULT);
         private @Nullable TagKey<DamageType> bypassedBy;
         private @Nullable Key blockSound;
         private @Nullable Key disableSound;
@@ -70,15 +85,18 @@ public record PaperBlocksAttacks(
             return this;
         }
 
-        //@Override
-        //public Builder addDamageReduction(final DamageReduction reduction) {
-        //    return null;
-        //}
+        @Override
+        public Builder addDamageReduction(final DamageReduction reduction) {
+            Preconditions.checkArgument(reduction.horizontalBlockingAngle() >= 0, "horizontalBlockingAngle must be non-negative, was %s", reduction.horizontalBlockingAngle());
+            this.damageReductions.add(reduction);
+            return this;
+        }
 
-        //@Override
-        //public Builder itemDamage(final ItemDamageFunction function) {
-        //    return null;
-        //}
+        @Override
+        public Builder itemDamage(final ItemDamageFunction function) {
+            this.itemDamage = function;
+            return this;
+        }
 
         @Override
         public Builder bypassedBy(@Nullable final TagKey<DamageType> bypassedBy) {
@@ -98,18 +116,19 @@ public record PaperBlocksAttacks(
             return this;
         }
 
-        //@Override
-        //public Builder damageReductions(final List<DamageReduction> reductions) {
-        //    return null;
-        //}
+        @Override
+        public Builder damageReductions(final List<DamageReduction> reductions) {
+            this.damageReductions = new ArrayList<>(reductions);
+            return this;
+        }
 
         @Override
         public BlocksAttacks build() {
             return new PaperBlocksAttacks(new net.minecraft.world.item.component.BlocksAttacks(
                 this.blockDelaySeconds,
                 this.disableCooldownScale,
-                List.of(), // TODO
-                net.minecraft.world.item.component.BlocksAttacks.ItemDamageFunction.DEFAULT, // TODO
+                this.damageReductions.stream().map(damageReduction -> ((PaperDamageReduction) damageReduction).getHandle()).toList(),
+                ((PaperItemDamageFunction) itemDamage).getHandle(),
                 Optional.ofNullable(this.bypassedBy).map(PaperRegistries::toNms),
                 Optional.ofNullable(this.blockSound).map(PaperAdventure::resolveSound),
                 Optional.ofNullable(this.disableSound).map(PaperAdventure::resolveSound)
diff --git a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/BlocksAttacksBridgeImpl.java b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/BlocksAttacksBridgeImpl.java
new file mode 100644
index 0000000000..865563be36
--- /dev/null
+++ b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/BlocksAttacksBridgeImpl.java
@@ -0,0 +1,19 @@
+package io.papermc.paper.datacomponent.item.blocksattacks;
+
+import org.jetbrains.annotations.ApiStatus;
+import org.jspecify.annotations.NullMarked;
+
+@ApiStatus.Internal
+@NullMarked
+public class BlocksAttacksBridgeImpl implements BlocksAttacksBridge {
+
+    @Override
+    public DamageReduction.Builder blocksAttacksDamageReduction() {
+        return new PaperDamageReduction.BuilderImpl();
+    }
+
+    @Override
+    public ItemDamageFunction.Builder blocksAttacksItemDamageFunction() {
+        return new PaperItemDamageFunction.BuilderImpl();
+    }
+}
diff --git a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/PaperDamageReduction.java b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/PaperDamageReduction.java
new file mode 100644
index 0000000000..7da287938e
--- /dev/null
+++ b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/PaperDamageReduction.java
@@ -0,0 +1,87 @@
+package io.papermc.paper.datacomponent.item.blocksattacks;
+
+import com.google.common.base.Preconditions;
+import io.papermc.paper.registry.RegistryKey;
+import io.papermc.paper.registry.set.PaperRegistrySets;
+import io.papermc.paper.registry.set.RegistryKeySet;
+import net.minecraft.core.HolderSet;
+import net.minecraft.core.registries.Registries;
+import org.bukkit.craftbukkit.util.Handleable;
+import org.bukkit.damage.DamageType;
+import org.checkerframework.checker.index.qual.Positive;
+import org.jetbrains.annotations.Nullable;
+import java.util.Optional;
+
+public record PaperDamageReduction(
+    net.minecraft.world.item.component.BlocksAttacks.DamageReduction impl
+) implements DamageReduction, Handleable<net.minecraft.world.item.component.BlocksAttacks.DamageReduction> {
+
+    @Override
+    public net.minecraft.world.item.component.BlocksAttacks.DamageReduction getHandle() {
+        return this.impl;
+    }
+
+    @Override
+    public @Nullable RegistryKeySet<DamageType> type() {
+        return this.impl.type().map((set) -> PaperRegistrySets.convertToApi(RegistryKey.DAMAGE_TYPE, set)).orElse(null);
+    }
+
+    @Override
+    public @Positive float horizontalBlockingAngle() {
+        return this.impl.horizontalBlockingAngle();
+    }
+
+    @Override
+    public float base() {
+        return this.impl.base();
+    }
+
+    @Override
+    public float factor() {
+        return this.impl.factor();
+    }
+
+    static final class BuilderImpl implements Builder {
+
+        private Optional<HolderSet<net.minecraft.world.damagesource.DamageType>> type = Optional.empty();
+        private float horizontalBlockingAngle = 90f;
+        private float base = 0;
+        private float factor = 0;
+
+        @Override
+        public Builder type(final @Nullable RegistryKeySet<DamageType> type) {
+            this.type = Optional.ofNullable(type)
+                .map((set) -> PaperRegistrySets.convertToNms(Registries.DAMAGE_TYPE, net.minecraft.server.MinecraftServer.getServer().registryAccess().createSerializationContext(net.minecraft.nbt.NbtOps.INSTANCE).lookupProvider, set));
+            return this;
+        }
+
+        @Override
+        public Builder horizontalBlockingAngle(@Positive final float horizontalBlockingAngle) {
+            Preconditions.checkArgument(horizontalBlockingAngle > 0, "horizontalBlockingAngle must be positive and not zero, was %s", horizontalBlockingAngle);
+            this.horizontalBlockingAngle = horizontalBlockingAngle;
+            return this;
+        }
+
+        @Override
+        public Builder base(final float base) {
+            this.base = base;
+            return this;
+        }
+
+        @Override
+        public Builder factor(final float factor) {
+            this.factor = factor;
+            return this;
+        }
+
+        @Override
+        public DamageReduction build() {
+            return new PaperDamageReduction(new net.minecraft.world.item.component.BlocksAttacks.DamageReduction(
+                this.horizontalBlockingAngle,
+                this.type,
+                this.base,
+                this.factor
+            ));
+        }
+    }
+}
diff --git a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/PaperItemDamageFunction.java b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/PaperItemDamageFunction.java
new file mode 100644
index 0000000000..515eec1599
--- /dev/null
+++ b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/PaperItemDamageFunction.java
@@ -0,0 +1,70 @@
+package io.papermc.paper.datacomponent.item.blocksattacks;
+
+import com.google.common.base.Preconditions;
+import org.bukkit.craftbukkit.util.Handleable;
+import org.checkerframework.checker.index.qual.NonNegative;
+
+public record PaperItemDamageFunction(
+    net.minecraft.world.item.component.BlocksAttacks.ItemDamageFunction impl
+) implements ItemDamageFunction, Handleable<net.minecraft.world.item.component.BlocksAttacks.ItemDamageFunction> {
+
+    @Override
+    public net.minecraft.world.item.component.BlocksAttacks.ItemDamageFunction getHandle() {
+        return this.impl;
+    }
+
+    @Override
+    public @NonNegative float threshold() {
+        return this.impl.threshold();
+    }
+
+    @Override
+    public float base() {
+        return this.impl.base();
+    }
+
+    @Override
+    public float factor() {
+        return this.impl.factor();
+    }
+
+    @Override
+    public int damageToApply(final float damage) {
+        return this.impl.apply(damage);
+    }
+
+    static final class BuilderImpl implements Builder {
+
+        private float threshold;
+        private float base;
+        private float factor;
+
+        @Override
+        public Builder threshold(@NonNegative final float threshold) {
+            Preconditions.checkArgument(threshold >= 0, "threshold must be non-negative, was %s", threshold);
+            this.threshold = threshold;
+            return this;
+        }
+
+        @Override
+        public Builder base(final float base) {
+            this.base = base;
+            return this;
+        }
+
+        @Override
+        public Builder factor(final float factor) {
+            this.factor = factor;
+            return this;
+        }
+
+        @Override
+        public ItemDamageFunction build() {
+            return new PaperItemDamageFunction(new net.minecraft.world.item.component.BlocksAttacks.ItemDamageFunction(
+                this.threshold,
+                this.base,
+                this.factor
+            ));
+        }
+    }
+}
diff --git a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/package-info.java b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/package-info.java
new file mode 100644
index 0000000000..d0fca5341f
--- /dev/null
+++ b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/package-info.java
@@ -0,0 +1,7 @@
+/**
+ * Relating to block attacks for components.
+ */
+@NullMarked
+package io.papermc.paper.datacomponent.item.blocksattacks;
+
+import org.jspecify.annotations.NullMarked;
diff --git a/paper-server/src/main/resources/META-INF/services/io.papermc.paper.datacomponent.item.blocksattacks.BlocksAttacksBridge b/paper-server/src/main/resources/META-INF/services/io.papermc.paper.datacomponent.item.blocksattacks.BlocksAttacksBridge
new file mode 100644
index 0000000000..02e0ef0649
--- /dev/null
+++ b/paper-server/src/main/resources/META-INF/services/io.papermc.paper.datacomponent.item.blocksattacks.BlocksAttacksBridge
@@ -0,0 +1 @@
+io.papermc.paper.datacomponent.item.blocksattacks.BlocksAttacksBridgeImpl